From 34155f91197a12655146074ceec8b35e31c69c4b Mon Sep 17 00:00:00 2001
From: Yasmeen Abuerrub <yabuerrub@hotmail.com>
Date: Mon, 7 Aug 2017 18:58:53 +0300
Subject: [PATCH] Issue #2900313 by yasmeensalah, Mohammed J. Razem: Add
 ability to embed tweets and other rich content in WYSIWYG with Varbase Editor
 [Rich editor] Text format

---
 composer.json                                 |   7 +-
 css/admin-toolbar-tools.css                   |   4 +
 drupal-org.make                               |   7 +-
 images/embed.png                              | Bin 0 -> 3073 bytes
 .../ckeditor/plugins/autoembed/lang/az.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/ca.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/cs.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/de-ch.js  |   8 +
 .../ckeditor/plugins/autoembed/lang/de.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/en.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/eo.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/es-mx.js  |   8 +
 .../ckeditor/plugins/autoembed/lang/es.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/eu.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/fr.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/gl.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/hr.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/hu.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/it.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/ja.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/km.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/ko.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/ku.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/mk.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/nb.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/nl.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/oc.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/pl.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/pt-br.js  |   8 +
 .../ckeditor/plugins/autoembed/lang/pt.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/ru.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/sk.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/sv.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/tr.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/ug.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/uk.js     |   8 +
 .../ckeditor/plugins/autoembed/lang/zh-cn.js  |   8 +
 .../ckeditor/plugins/autoembed/lang/zh.js     |   8 +
 .../ckeditor/plugins/autoembed/plugin.js      | 214 ++++
 libraries/ckeditor/plugins/autolink/plugin.js |  42 +
 .../ckeditor/plugins/embed/icons/embed.png    | Bin 0 -> 389 bytes
 .../plugins/embed/icons/hidpi/embed.png       | Bin 0 -> 728 bytes
 libraries/ckeditor/plugins/embed/plugin.js    | 105 ++
 .../plugins/embedbase/dialogs/embedbase.js    |  99 ++
 .../ckeditor/plugins/embedbase/lang/az.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/ca.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/cs.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/da.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/de-ch.js  |  15 +
 .../ckeditor/plugins/embedbase/lang/de.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/en.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/eo.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/es-mx.js  |  15 +
 .../ckeditor/plugins/embedbase/lang/es.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/eu.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/fr.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/gl.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/hr.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/hu.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/id.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/it.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/ja.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/ko.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/ku.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/nb.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/nl.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/oc.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/pl.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/pt-br.js  |  15 +
 .../ckeditor/plugins/embedbase/lang/pt.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/ru.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/sk.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/sv.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/tr.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/ug.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/uk.js     |  15 +
 .../ckeditor/plugins/embedbase/lang/zh-cn.js  |  15 +
 .../ckeditor/plugins/embedbase/lang/zh.js     |  15 +
 .../ckeditor/plugins/embedbase/plugin.js      | 652 +++++++++++++
 .../embedsemantic/icons/embedsemantic.png     | Bin 0 -> 389 bytes
 .../icons/hidpi/embedsemantic.png             | Bin 0 -> 728 bytes
 .../ckeditor/plugins/embedsemantic/plugin.js  | 114 +++
 .../ckeditor/plugins/notification/lang/az.js  |   7 +
 .../ckeditor/plugins/notification/lang/ca.js  |   7 +
 .../ckeditor/plugins/notification/lang/cs.js  |   7 +
 .../ckeditor/plugins/notification/lang/da.js  |   7 +
 .../plugins/notification/lang/de-ch.js        |   7 +
 .../ckeditor/plugins/notification/lang/de.js  |   7 +
 .../ckeditor/plugins/notification/lang/en.js  |   7 +
 .../ckeditor/plugins/notification/lang/eo.js  |   7 +
 .../plugins/notification/lang/es-mx.js        |   7 +
 .../ckeditor/plugins/notification/lang/es.js  |   7 +
 .../ckeditor/plugins/notification/lang/eu.js  |   7 +
 .../ckeditor/plugins/notification/lang/fr.js  |   7 +
 .../ckeditor/plugins/notification/lang/gl.js  |   7 +
 .../ckeditor/plugins/notification/lang/hr.js  |   7 +
 .../ckeditor/plugins/notification/lang/hu.js  |   7 +
 .../ckeditor/plugins/notification/lang/id.js  |   7 +
 .../ckeditor/plugins/notification/lang/it.js  |   7 +
 .../ckeditor/plugins/notification/lang/ja.js  |   7 +
 .../ckeditor/plugins/notification/lang/km.js  |   7 +
 .../ckeditor/plugins/notification/lang/ko.js  |   7 +
 .../ckeditor/plugins/notification/lang/ku.js  |   7 +
 .../ckeditor/plugins/notification/lang/nb.js  |   7 +
 .../ckeditor/plugins/notification/lang/nl.js  |   7 +
 .../ckeditor/plugins/notification/lang/oc.js  |   7 +
 .../ckeditor/plugins/notification/lang/pl.js  |   7 +
 .../plugins/notification/lang/pt-br.js        |   7 +
 .../ckeditor/plugins/notification/lang/pt.js  |   7 +
 .../ckeditor/plugins/notification/lang/ru.js  |   7 +
 .../ckeditor/plugins/notification/lang/sk.js  |   7 +
 .../ckeditor/plugins/notification/lang/sv.js  |   7 +
 .../ckeditor/plugins/notification/lang/tr.js  |   7 +
 .../ckeditor/plugins/notification/lang/ug.js  |   7 +
 .../ckeditor/plugins/notification/lang/uk.js  |   7 +
 .../plugins/notification/lang/zh-cn.js        |   7 +
 .../ckeditor/plugins/notification/lang/zh.js  |   7 +
 .../ckeditor/plugins/notification/plugin.js   | 923 ++++++++++++++++++
 .../plugins/notificationaggregator/plugin.js  | 548 +++++++++++
 varbase.info.yml                              |   1 +
 120 files changed, 3741 insertions(+), 2 deletions(-)
 create mode 100644 images/embed.png
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/az.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/ca.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/cs.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/de-ch.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/de.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/en.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/eo.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/es-mx.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/es.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/eu.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/fr.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/gl.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/hr.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/hu.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/it.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/ja.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/km.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/ko.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/ku.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/mk.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/nb.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/nl.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/oc.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/pl.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/pt-br.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/pt.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/ru.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/sk.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/sv.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/tr.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/ug.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/uk.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/zh-cn.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/lang/zh.js
 create mode 100644 libraries/ckeditor/plugins/autoembed/plugin.js
 create mode 100644 libraries/ckeditor/plugins/autolink/plugin.js
 create mode 100644 libraries/ckeditor/plugins/embed/icons/embed.png
 create mode 100644 libraries/ckeditor/plugins/embed/icons/hidpi/embed.png
 create mode 100644 libraries/ckeditor/plugins/embed/plugin.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/dialogs/embedbase.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/az.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/ca.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/cs.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/da.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/de-ch.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/de.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/en.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/eo.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/es-mx.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/es.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/eu.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/fr.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/gl.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/hr.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/hu.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/id.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/it.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/ja.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/ko.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/ku.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/nb.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/nl.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/oc.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/pl.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/pt-br.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/pt.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/ru.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/sk.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/sv.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/tr.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/ug.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/uk.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/zh-cn.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/lang/zh.js
 create mode 100644 libraries/ckeditor/plugins/embedbase/plugin.js
 create mode 100644 libraries/ckeditor/plugins/embedsemantic/icons/embedsemantic.png
 create mode 100644 libraries/ckeditor/plugins/embedsemantic/icons/hidpi/embedsemantic.png
 create mode 100644 libraries/ckeditor/plugins/embedsemantic/plugin.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/az.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/ca.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/cs.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/da.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/de-ch.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/de.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/en.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/eo.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/es-mx.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/es.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/eu.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/fr.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/gl.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/hr.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/hu.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/id.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/it.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/ja.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/km.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/ko.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/ku.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/nb.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/nl.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/oc.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/pl.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/pt-br.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/pt.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/ru.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/sk.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/sv.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/tr.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/ug.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/uk.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/zh-cn.js
 create mode 100644 libraries/ckeditor/plugins/notification/lang/zh.js
 create mode 100644 libraries/ckeditor/plugins/notification/plugin.js
 create mode 100644 libraries/ckeditor/plugins/notificationaggregator/plugin.js

diff --git a/composer.json b/composer.json
index c51de557..49a331ba 100644
--- a/composer.json
+++ b/composer.json
@@ -135,7 +135,8 @@
     "drupal/entity_browser_enhanced": "1.0-beta5",
     "drupal/vmi": "1.0-beta2",
     "drupal/varbase_bootstrap_paragraphs": "4.x-dev#acd6df8043ffa883aed7913427a98f6845eb23ce",
-    "drupal/varbase_editor": "4.15",
+    "drupal/ckeditor_media_embed": "1.1",
+    "drupal/varbase_editor": "4.x-dev",
     "drupal/varbase_heroslider_media": "4.0-beta8",
     "drupal/varbase_carousels": "4.0-beta2",
     "drupal/varbase_total_control": "1.0-beta4",
@@ -280,6 +281,10 @@
       "drupal/responsive_preview": {
         "Issue #2899640: Responsive Preview shows 'Page not found' when multilingual site is enabled with Path-prefix setting":
         "https://www.drupal.org/files/issues/responsive_preview_with_path_prefix-2899640-2_0.patch"
+      },
+      "drupal/ckeditor_media_embed": {
+        "Issue #2900313: Add ability to embed tweets and other rich content in WYSIWYG":
+        "https://www.drupal.org/files/issues/embed_rich_content_in_WYSIWYG-2900313-2.patch"
       }
     }
   }
diff --git a/css/admin-toolbar-tools.css b/css/admin-toolbar-tools.css
index 720028aa..f8b6a6c1 100644
--- a/css/admin-toolbar-tools.css
+++ b/css/admin-toolbar-tools.css
@@ -8,3 +8,7 @@
 .adminimal-admin-toolbar .toolbar-icon-admin-toolbar-tools-help:hover:before {
   background-image: url(../files/images/varbase-x-small-emblem-white.png);
 }
+
+span .cke_button__embed_icon {
+  background-image:url('../images/embed.png') !important;
+}
diff --git a/drupal-org.make b/drupal-org.make
index 25c989a7..03ed59e6 100644
--- a/drupal-org.make
+++ b/drupal-org.make
@@ -256,6 +256,11 @@ projects[login_destination][download][url] = https://git.drupal.org/project/logi
 projects[login_destination][download][revision] = 98892eb84eba6fe69d4fc48dc5b1fdaccb21c8a7
 projects[login_destination][download][branch] = 8.x-1.x
 
+projects[ckeditor_media_embed][type] = module
+projects[ckeditor_media_embed][version] = 1.1
+;; Issue #2900313: Add ability to embed tweets and other rich content in WYSIWYG
+projects[ckeditor_media_embed][patch][] = https://www.drupal.org/files/issues/embed_rich_content_in_WYSIWYG-2900313-2.patch
+
 ;;;;;;;;;;;;;;;;;;;;;
 ;; Contrib modules for Varbase SEO.
 ;;;;;;;;;;;;;;;;;;;;;
@@ -430,7 +435,7 @@ projects[total_control][version] = 2.0-alpha2
 ;;;;;;;;;;;;;;;;;;;;;
 
 projects[varbase_editor][type] = module
-projects[varbase_editor][version] = 4.15
+projects[varbase_editor][version] = 4.x-dev
 
 projects[varbase_heroslider_media][type] = module
 projects[varbase_heroslider_media][version] = 4.0-beta8
diff --git a/images/embed.png b/images/embed.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2f8f853ac6d4efed31e0b6a3d70f104d48423ee
GIT binary patch
literal 3073
zcmV+c4F2<pP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003jNkl<Zc-oB9u`7j97{~F?y<Q6wneM-!EO$^0O6vXv7h#mmbc@9<R%MWlLPjK!
zSd?VBqLfAI&K64UV0qrUz3F}LS)MvQzwh}yzjIEhTCM7GRWO1pwA0OU7s5X5;~nQw
z=eq?YI0?ZkwlRdg6jB73#Uvgvfo0V3i%ld&fQ6_HoZ%9u*o{o4k^;a3Ua)~t++!fz
zw9zbbu!FG<@hUDbj3cy?OklHN`ys@~9pXFOMDI10Iz#LW@*ZmF&xoh-9X$)t^PQfW
zT20e#WM;1818e`ySdKJj@Qf*}XKXJOJ(Q8CxA??YM_@N$I~Q<;78awq7FU%D_wxYd
zxX%^zMsQo<rW$D<<^g&tl?puJ4dW5!APz8xpFBV*^PQ6jvKeC)uD<~QPZCJ@R{<TY
P00000NkvXXu0mjfc5Jls

literal 0
HcmV?d00001

diff --git a/libraries/ckeditor/plugins/autoembed/lang/az.js b/libraries/ckeditor/plugins/autoembed/lang/az.js
new file mode 100644
index 00000000..e6da287a
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/az.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'az', {
+	embeddingInProgress: 'Dahil etdiyiniz link yerləşdirilir...',
+	embeddingFailed: 'Bu cür linki avtomatik yerləşdirmək mövcud deyil.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/ca.js b/libraries/ckeditor/plugins/autoembed/lang/ca.js
new file mode 100644
index 00000000..8b700d96
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/ca.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'ca', {
+	embeddingInProgress: 'Provant d\'incrustar URL copiada...',
+	embeddingFailed: 'Aquesta URL no es pot incrustar automàticament.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/cs.js b/libraries/ckeditor/plugins/autoembed/lang/cs.js
new file mode 100644
index 00000000..9f0a4fff
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/cs.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'cs', {
+	embeddingInProgress: 'Pokus o vnoření vložené URL',
+	embeddingFailed: 'Tato URL nemůže být automaticky vnořena.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/de-ch.js b/libraries/ckeditor/plugins/autoembed/lang/de-ch.js
new file mode 100644
index 00000000..3c69faa9
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/de-ch.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'de-ch', {
+	embeddingInProgress: 'Einbetten der eingefügten URL wird versucht...',
+	embeddingFailed: 'Diese URL konnte nicht automatisch eingebettet werden.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/de.js b/libraries/ckeditor/plugins/autoembed/lang/de.js
new file mode 100644
index 00000000..c229c1d9
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/de.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'de', {
+	embeddingInProgress: 'Einbetten der eingefügten URL wird versucht...',
+	embeddingFailed: 'Diese URL konnte nicht automatisch eingebettet werden.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/en.js b/libraries/ckeditor/plugins/autoembed/lang/en.js
new file mode 100644
index 00000000..c7123838
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/en.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'en', {
+	embeddingInProgress: 'Trying to embed pasted URL...',
+	embeddingFailed: 'This URL could not be automatically embedded.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/eo.js b/libraries/ckeditor/plugins/autoembed/lang/eo.js
new file mode 100644
index 00000000..5afc0440
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/eo.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'eo', {
+	embeddingInProgress: 'Provas enkorpigi la algluitan URL ...',
+	embeddingFailed: 'Ne eblis enkorpigi aÅ­tomate tiun URL.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/es-mx.js b/libraries/ckeditor/plugins/autoembed/lang/es-mx.js
new file mode 100644
index 00000000..6dc8558c
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/es-mx.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'es-mx', {
+	embeddingInProgress: 'Tratando de empotrar la URL pegada...',
+	embeddingFailed: 'Esta URL no puede ser empotrada automáticamente.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/es.js b/libraries/ckeditor/plugins/autoembed/lang/es.js
new file mode 100644
index 00000000..e9cf8c90
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/es.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'es', {
+	embeddingInProgress: 'Intentando incrustar URL pegada...',
+	embeddingFailed: 'Está URL no pudo ser automáticamente incrustada.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/eu.js b/libraries/ckeditor/plugins/autoembed/lang/eu.js
new file mode 100644
index 00000000..b6291d80
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/eu.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'eu', {
+	embeddingInProgress: 'Itsatsitako URLa txertatzen saiatzen...',
+	embeddingFailed: 'URL hau ezin izan da automatikoki txertatu.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/fr.js b/libraries/ckeditor/plugins/autoembed/lang/fr.js
new file mode 100644
index 00000000..77c20434
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/fr.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'fr', {
+	embeddingInProgress: 'Incorporation de l\'URL collée...',
+	embeddingFailed: 'Cette URL n\'a pas pu être incorporée automatiquement.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/gl.js b/libraries/ckeditor/plugins/autoembed/lang/gl.js
new file mode 100644
index 00000000..844a7c58
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/gl.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'gl', {
+	embeddingInProgress: 'Tentando incrustar URL pegado...',
+	embeddingFailed: 'Non foi posíbel incrustar automaticamente este URL.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/hr.js b/libraries/ckeditor/plugins/autoembed/lang/hr.js
new file mode 100644
index 00000000..1f5335f6
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/hr.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'hr', {
+	embeddingInProgress: 'Pokušavam umetnuti URL...',
+	embeddingFailed: 'URL nije moguće umetnuti automatski.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/hu.js b/libraries/ckeditor/plugins/autoembed/lang/hu.js
new file mode 100644
index 00000000..8d54463b
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/hu.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'hu', {
+	embeddingInProgress: 'A beillesztett URL beágyazásának megkísérlése...',
+	embeddingFailed: 'Ezt az URL-t nem lehet automatikusan beágyazni.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/it.js b/libraries/ckeditor/plugins/autoembed/lang/it.js
new file mode 100644
index 00000000..9f037431
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/it.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'it', {
+	embeddingInProgress: 'Prova a incorporare l\'URL incollato...',
+	embeddingFailed: 'Non è stato possibile incorporare automaticamente questo URL.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/ja.js b/libraries/ckeditor/plugins/autoembed/lang/ja.js
new file mode 100644
index 00000000..0650e71e
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/ja.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'ja', {
+	embeddingInProgress: '貼り付けられたURLを埋め込み中...',
+	embeddingFailed: 'このURLは自動的に埋め込むことが出来ません。'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/km.js b/libraries/ckeditor/plugins/autoembed/lang/km.js
new file mode 100644
index 00000000..ca390fd7
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/km.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'km', {
+	embeddingInProgress: 'កំពុង​ព្យាយាម​បង្កប់ URL ដែល​បាន​បិទភ្ជាប់...',
+	embeddingFailed: 'មិន​អាច​បង្កប់ URL នេះ​ដោយ​ស្វ័យប្រវត្តិ​ទេ។'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/ko.js b/libraries/ckeditor/plugins/autoembed/lang/ko.js
new file mode 100644
index 00000000..d6ddeb55
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/ko.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'ko', {
+	embeddingInProgress: '붙여넣은 URL 첨부 시도 중...',
+	embeddingFailed: '이 URL은 자동으로 첨부할 수 없습니다.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/ku.js b/libraries/ckeditor/plugins/autoembed/lang/ku.js
new file mode 100644
index 00000000..d2a2a508
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/ku.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'ku', {
+	embeddingInProgress: 'لەهەوڵی لکاندنی بەستەری ناونیشانە...',
+	embeddingFailed: 'ئەم بەستەرە خۆکارانە ناتواندرێت بخرێتە ناوێ.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/mk.js b/libraries/ckeditor/plugins/autoembed/lang/mk.js
new file mode 100644
index 00000000..0e7da043
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/mk.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'mk', {
+	embeddingInProgress: 'Обид за вметнување копирано URL...',
+	embeddingFailed: 'Ова URL не може да биде вметнато автоматски.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/nb.js b/libraries/ckeditor/plugins/autoembed/lang/nb.js
new file mode 100644
index 00000000..73ec63a1
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/nb.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'nb', {
+	embeddingInProgress: 'Prøver å bygge inn innlimt URL...',
+	embeddingFailed: 'URL-en kunne ikke bli automatisk bygget inn.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/nl.js b/libraries/ckeditor/plugins/autoembed/lang/nl.js
new file mode 100644
index 00000000..b77eb1e7
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/nl.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'nl', {
+	embeddingInProgress: 'De geplakte URL wordt ingesloten...',
+	embeddingFailed: 'Deze URL kon niet automatisch ingesloten worden.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/oc.js b/libraries/ckeditor/plugins/autoembed/lang/oc.js
new file mode 100644
index 00000000..275a4ca4
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/oc.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'oc', {
+	embeddingInProgress: 'Incorporacion de l\'URL pegada...',
+	embeddingFailed: 'Aquesta URL a pas pogut èsser incorporada automaticament.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/pl.js b/libraries/ckeditor/plugins/autoembed/lang/pl.js
new file mode 100644
index 00000000..aea0e518
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/pl.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'pl', {
+	embeddingInProgress: 'Osadzanie wklejonego adresu URL...',
+	embeddingFailed: 'Ten adres URL multimediów nie może być automatycznie osadzony.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/pt-br.js b/libraries/ckeditor/plugins/autoembed/lang/pt-br.js
new file mode 100644
index 00000000..90342530
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/pt-br.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'pt-br', {
+	embeddingInProgress: 'Tentando embutir a URL colada...',
+	embeddingFailed: 'Esta URL não pode ser embutida automaticamente.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/pt.js b/libraries/ckeditor/plugins/autoembed/lang/pt.js
new file mode 100644
index 00000000..b3be44b2
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/pt.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'pt', {
+	embeddingInProgress: 'Trying to embed pasted URL...', // MISSING
+	embeddingFailed: 'Não foi possível embeber diretamente este URL.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/ru.js b/libraries/ckeditor/plugins/autoembed/lang/ru.js
new file mode 100644
index 00000000..ec8aba88
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/ru.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'ru', {
+	embeddingInProgress: 'Пытаемся встроить вставленный URL...',
+	embeddingFailed: 'Данный URL не может быть встроен автоматически.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/sk.js b/libraries/ckeditor/plugins/autoembed/lang/sk.js
new file mode 100644
index 00000000..39632450
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/sk.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'sk', {
+	embeddingInProgress: 'Snažím sa vložiť skopírovanú URL...',
+	embeddingFailed: 'Túto URL nebolo možné automaticky vložiť.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/sv.js b/libraries/ckeditor/plugins/autoembed/lang/sv.js
new file mode 100644
index 00000000..e35b960f
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/sv.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'sv', {
+	embeddingInProgress: 'Försöker bädda in inklistrad URL...',
+	embeddingFailed: 'Denna URL kunde inte automatiskt bäddas in.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/tr.js b/libraries/ckeditor/plugins/autoembed/lang/tr.js
new file mode 100644
index 00000000..51346e8e
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/tr.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'tr', {
+	embeddingInProgress: 'Yapıştırdığınız URL gömülmeye çalışılıyor...',
+	embeddingFailed: 'Bu URL otomatik olarak gömülemedi.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/ug.js b/libraries/ckeditor/plugins/autoembed/lang/ug.js
new file mode 100644
index 00000000..5cf73a79
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/ug.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'ug', {
+	embeddingInProgress: 'سىڭدۈرۈلگەن چاپلانغان URL نى سىناۋاتىدۇ…',
+	embeddingFailed: 'بۇ URL نى ئۆزلۈكىدىن سىڭدۈرەلمەيدۇ.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/uk.js b/libraries/ckeditor/plugins/autoembed/lang/uk.js
new file mode 100644
index 00000000..5fea30b7
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/uk.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'uk', {
+	embeddingInProgress: 'Намагаюсь вбудувати вставлене URL посилання...',
+	embeddingFailed: 'Це URl посилання не може бути автоматично вбудовано.'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/zh-cn.js b/libraries/ckeditor/plugins/autoembed/lang/zh-cn.js
new file mode 100644
index 00000000..ae6c67b7
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/zh-cn.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'zh-cn', {
+	embeddingInProgress: '正在尝试嵌入粘贴的 URL 里的媒体内容...',
+	embeddingFailed: '此 URL 无法自动嵌入媒体内容'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/lang/zh.js b/libraries/ckeditor/plugins/autoembed/lang/zh.js
new file mode 100644
index 00000000..dfad65df
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/lang/zh.js
@@ -0,0 +1,8 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+CKEDITOR.plugins.setLang( 'autoembed', 'zh', {
+	embeddingInProgress: '正在嘗試嵌入已貼上的 URL...',
+	embeddingFailed: '這個 URL 無法被自動嵌入。'
+} );
diff --git a/libraries/ckeditor/plugins/autoembed/plugin.js b/libraries/ckeditor/plugins/autoembed/plugin.js
new file mode 100644
index 00000000..54dd77ab
--- /dev/null
+++ b/libraries/ckeditor/plugins/autoembed/plugin.js
@@ -0,0 +1,214 @@
+/**
+ * @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 validLinkRegExp = /^<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>$/i;
+
+	CKEDITOR.plugins.add( 'autoembed', {
+		requires: 'autolink,undo',
+		lang: 'az,ca,cs,de,de-ch,en,eo,es,es-mx,eu,fr,gl,hr,hu,it,ja,km,ko,ku,mk,nb,nl,oc,pl,pt,pt-br,ru,sk,sv,tr,ug,uk,zh,zh-cn', // %REMOVE_LINE_CORE%
+		init: function( editor ) {
+			var currentId = 1,
+				embedCandidatePasted;
+
+			editor.on( 'paste', function( evt ) {
+				if ( evt.data.dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {
+					embedCandidatePasted = 0;
+					return;
+				}
+
+				var match = evt.data.dataValue.match( validLinkRegExp );
+
+				embedCandidatePasted = match != null && decodeURI( match[ 1 ] ) == decodeURI( match[ 2 ] );
+
+				// Expecting exactly one <a> tag spanning the whole pasted content.
+				// The tag has to have same href as content.
+				if ( embedCandidatePasted ) {
+					evt.data.dataValue = '<a data-cke-autoembed="' + ( ++currentId ) + '"' + evt.data.dataValue.substr( 2 );
+				}
+			}, null, null, 20 ); // Execute after autolink.
+
+			editor.on( 'afterPaste', function() {
+				// If one pasted an embeddable link and then undone the action, the link in the content holds the
+				// data-cke-autoembed attribute and may be embedded on *any* successive paste.
+				// This check ensures that autoEmbedLink is called only if afterPaste is fired *right after*
+				// embeddable link got into the content. (http://dev.ckeditor.com/ticket/13532)
+				if ( embedCandidatePasted ) {
+					autoEmbedLink( editor, currentId );
+				}
+			} );
+		}
+	} );
+
+	function autoEmbedLink( editor, id ) {
+		var anchor = editor.editable().findOne( 'a[data-cke-autoembed="' + id + '"]' ),
+			lang = editor.lang.autoembed,
+			notification;
+
+		if ( !anchor || !anchor.data( 'cke-saved-href' ) ) {
+			return;
+		}
+
+		var href = anchor.data( 'cke-saved-href' ),
+			widgetDef = CKEDITOR.plugins.autoEmbed.getWidgetDefinition( editor, href );
+
+		if ( !widgetDef ) {
+			CKEDITOR.warn( 'autoembed-no-widget-def' );
+			return;
+		}
+
+			// TODO Move this to a method in the widget plugin. http://dev.ckeditor.com/ticket/13408
+		var defaults = typeof widgetDef.defaults == 'function' ? widgetDef.defaults() : widgetDef.defaults,
+			element = CKEDITOR.dom.element.createFromHtml( widgetDef.template.output( defaults ) ),
+			instance,
+			wrapper = editor.widgets.wrapElement( element, widgetDef.name ),
+			temp = new CKEDITOR.dom.documentFragment( wrapper.getDocument() );
+
+		temp.append( wrapper );
+		instance = editor.widgets.initOn( element, widgetDef );
+
+		if ( !instance ) {
+			finalizeCreation();
+			return;
+		}
+
+		notification = editor.showNotification( lang.embeddingInProgress, 'info' );
+		instance.loadContent( href, {
+			noNotifications: true,
+			callback: function() {
+					// DOM might be invalidated in the meantime, so find the anchor again.
+				var anchor = editor.editable().findOne( 'a[data-cke-autoembed="' + id + '"]' );
+
+				// Anchor might be removed in the meantime.
+				if ( anchor ) {
+					var selection = editor.getSelection(),
+						insertRange = editor.createRange(),
+						editable = editor.editable();
+
+					// Save the changes in editor contents that happened *after* the link was pasted
+					// but before it gets embedded (i.e. user pasted and typed).
+					editor.fire( 'saveSnapshot' );
+
+					// Lock snapshot so we don't make unnecessary undo steps in
+					// editable.insertElement() below, which would include bookmarks. (http://dev.ckeditor.com/ticket/13429)
+					editor.fire( 'lockSnapshot', { dontUpdate: true } );
+
+					// Bookmark current selection. (http://dev.ckeditor.com/ticket/13429)
+					var bookmark = selection.createBookmarks( false )[ 0 ],
+						startNode = bookmark.startNode,
+						endNode = bookmark.endNode || startNode;
+
+					// When url is pasted, IE8 sets the caret after <a> element instead of inside it.
+					// So, if user hasn't changed selection, bookmark is inserted right after <a>.
+					// Then, after pasting embedded content, bookmark is still in DOM but it is
+					// inside the original element. After selection recreation it would end up before widget:
+					// <p>A <a /><bm /></p><p>B</p>  -->  <p>A <bm /></p><widget /><p>B</p>  -->  <p>A ^</p><widget /><p>B</p>
+					// We have to fix this IE8 behavior so it is the same as on other browsers.
+					if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && !bookmark.endNode && startNode.equals( anchor.getNext() ) ) {
+						anchor.append( startNode );
+					}
+
+					insertRange.setStartBefore( anchor );
+					insertRange.setEndAfter( anchor );
+
+					editable.insertElement( wrapper, insertRange );
+
+					// If both bookmarks are still in DOM, it means that selection was not inside
+					// an anchor that got substituted. We can safely recreate that selection. (http://dev.ckeditor.com/ticket/13429)
+					if ( editable.contains( startNode ) && editable.contains( endNode ) ) {
+						selection.selectBookmarks( [ bookmark ] );
+					} else {
+						// If one of bookmarks is not in DOM, clean up leftovers.
+						startNode.remove();
+						endNode.remove();
+					}
+
+					editor.fire( 'unlockSnapshot' );
+				}
+
+				notification.hide();
+				finalizeCreation();
+			},
+
+			errorCallback: function() {
+				notification.hide();
+				editor.widgets.destroy( instance, true );
+				editor.showNotification( lang.embeddingFailed, 'info' );
+			}
+		} );
+
+		function finalizeCreation() {
+			editor.widgets.finalizeCreation( temp );
+		}
+	}
+
+	CKEDITOR.plugins.autoEmbed = {
+		/**
+		 * Gets the definition of the widget that should be used to automatically embed the specified link.
+		 *
+		 * This method uses the value of the {@link CKEDITOR.config#autoEmbed_widget} option.
+		 *
+		 * @since 4.5
+		 * @member CKEDITOR.plugins.autoEmbed
+		 * @param {CKEDITOR.editor} editor
+		 * @param {String} url The URL to be embedded.
+		 * @returns {CKEDITOR.plugins.widget.definition/null} The definition of the widget to be used to embed the link.
+		 */
+		getWidgetDefinition: function( editor, url ) {
+			var opt = editor.config.autoEmbed_widget || 'embed,embedSemantic',
+				name,
+				widgets = editor.widgets.registered;
+
+			if ( typeof opt == 'string' ) {
+				opt = opt.split( ',' );
+
+				while ( ( name = opt.shift() ) ) {
+					if ( widgets[ name ] ) {
+						return widgets[ name ];
+					}
+				}
+			} else if ( typeof opt == 'function' ) {
+				return widgets[ opt( url ) ];
+			}
+
+			return null;
+		}
+	};
+
+	/**
+	 * Specifies the widget to use to automatically embed a link. The default value
+	 * of this option defines that either the [Media Embed](ckeditor.com/addon/embed) or
+	 * [Semantic Media Embed](ckeditor.com/addon/embedsemantic) widgets will be used, depending on which is enabled.
+	 *
+	 * The general behavior:
+	 *
+	 * * If a string (widget names separated by commas) is provided, then the first of the listed widgets which is registered
+	 *   will be used. For example, if `'foo,bar,bom'` is set and widgets `'bar'` and `'bom'` are registered, then `'bar'`
+	 *   will be used.
+	 * * If a callback is specified, then it will be executed with the URL to be embedded and it should return the
+	 *   name of the widget to be used. It allows to use different embed widgets for different URLs.
+	 *
+	 * Example:
+	 *
+	 *		// Defines that embedSemantic should be used (regardless of whether embed is defined).
+	 *		config.autoEmbed_widget = 'embedSemantic';
+	 *
+	 * Using with custom embed widgets:
+	 *
+	 *		config.autoEmbed_widget = 'customEmbed';
+	 *
+	 * **Note:** Plugin names are always lower case, while widget names are not, so widget names do not have to equal plugin names.
+	 * For example, there is the `embedsemantic` plugin and the `embedSemantic` widget.
+	 *
+	 * Read more in the [documentation](#!/guide/dev_media_embed-section-automatic-embedding-on-paste)
+	 * and see the [SDK sample](http://sdk.ckeditor.com/samples/mediaembed.html).
+	 *
+	 * @since 4.5
+	 * @cfg {String/Function} [autoEmbed_widget='embed,embedSemantic']
+	 * @member CKEDITOR.config
+	 */
+} )();
diff --git a/libraries/ckeditor/plugins/autolink/plugin.js b/libraries/ckeditor/plugins/autolink/plugin.js
new file mode 100644
index 00000000..831922ae
--- /dev/null
+++ b/libraries/ckeditor/plugins/autolink/plugin.js
@@ -0,0 +1,42 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+	'use strict';
+
+	// Regex by Imme Emosol.
+	var validUrlRegex = /^(https?|ftp):\/\/(-\.)?([^\s\/?\.#]+\.?)+(\/[^\s]*)?[^\s\.,]$/ig,
+		doubleQuoteRegex = /"/g;
+
+	CKEDITOR.plugins.add( 'autolink', {
+		requires: 'clipboard',
+
+		init: function( editor ) {
+			editor.on( 'paste', function( evt ) {
+				var data = evt.data.dataValue;
+
+				if ( evt.data.dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {
+					return;
+				}
+
+				// If we found "<" it means that most likely there's some tag and we don't want to touch it.
+				if ( data.indexOf( '<' ) > -1 ) {
+					return;
+				}
+
+				// http://dev.ckeditor.com/ticket/13419
+				data = data.replace( validUrlRegex , '<a href="' + data.replace( doubleQuoteRegex, '%22' ) + '">$&</a>' );
+
+				// If link was discovered, change the type to 'html'. This is important e.g. when pasting plain text in Chrome
+				// where real type is correctly recognized.
+				if ( data != evt.data.dataValue ) {
+					evt.data.type = 'html';
+				}
+
+				evt.data.dataValue = data;
+			} );
+		}
+	} );
+} )();
diff --git a/libraries/ckeditor/plugins/embed/icons/embed.png b/libraries/ckeditor/plugins/embed/icons/embed.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a9a73568eff8443f69985e68bc1f8039940b498
GIT binary patch
literal 389
zcmV;00eb$4P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00001b5ch_0Itp)
z=>Px$KS@MER5%f(Q#)>iFc8HOqRj=oh@Jw`(NaK@3vh*;Ag4&bN8kb}5CsiA1sxIs
z5ky4}0OAwRWM{(?uf%FyFmHZup0Ujov4S9Y)imuaAYa#2VT>tYVG#yPOW?0z7~aA#
z{8S;Rs_Hq*GEM~t?8&k$7<fX0X_|PR=YJy(Fqo!^5|Ln87Ho;*_*eIZ!1Fw|k3kCJ
z)Pn@`JYQNA#kOt4VoPYD_?p}R>iI{osX=&10m<1nga5Dsl1^j~DUeN*#eiJ;4`kCw
z2@v_dzruxzqKFkmfvKBgyf=+Vw*RUuOFW&MQ;;bDQrC6yevoYPlO$nCFpeV*xu-x(
z!@OY__%^DlLJL78===WLahz4W2`t=x(lljF)1X{k*HH=iR{|mJz3aLUvB#HfGhog+
jHnnZb>bl;ipZ9+N?)Ip<G5FTi00000NkvXXu0mjf#aE^X

literal 0
HcmV?d00001

diff --git a/libraries/ckeditor/plugins/embed/icons/hidpi/embed.png b/libraries/ckeditor/plugins/embed/icons/hidpi/embed.png
new file mode 100644
index 0000000000000000000000000000000000000000..97dc75475839dece3638850cd2d1628e1af4ed6b
GIT binary patch
literal 728
zcmV;}0w?{6P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px%l1W5CR9Fe^SIvqVK@c7_f;k1eB@F0EauCGaB_N2;5WM;fd5G*Qc=aK~gDiNC
zh&coW1rd*dL=eHhRCWAntDEV}=<Ws<(lAzc*H=|vRoBcosX&c(yB+TL`!BThk*;^=
z^I2*A(^M)IFqS0`%wd1oUz6%So6UaibUG^oq@O<)G-<V3VJ4FqlTjW@$hZK&C6VOo
z$MJZqbh}+c;uVZYad$eM^5gLsThAgZl}bLHPT!I9PaHr9Q083r$Prai?6CpnETe|5
zAY<r~SVDlZf6K;`$wZDN%GqQ0%H=Y%G_ly15b&{oY(UqZ5|w8CD}jE$A6?Ij$3~-J
zDiwzV0pNMfBrv1`dK1d$kZv3y;5&k9wQBJgjYig5XJ#opi%S!VHjNoG^N|4NDWppv
zwgPcMuk8U&ly6H6i@=Mlz>DjFtM3B0>v49F*Y*J0X%hdu2k1@cZ$f0nGU?eS#cAKV
z*`)%yEE@dOb2p9<(5yIU(zA65q9V;^(|VWmdOdUV&t@~r#7n?J-LTM^>IaXTs1VQw
z91oe?5Zjn=AOzOF=kxi)V~~(SKpWf|RNJvXH(Ra8+#;Y2lJ)>9Rj=2rGuOU2nAWpy
zFc_Fh2mxItu)9XGJxb02c<z#j@+SliheJSr%LRkXWFuy>SS&0=u~?KflX3M>%Kw4w
zcAJPX3|-0D`Yx`HtAo8%;3th-F88KZt666WpqA_mB_0lk<}8=XrPbYqLP7j6-qpjO
zRDeL=*6Ve!*=z#(JTos0uto+f^_=y-0W9!7oUksHO7C~O-B&Vr?E@#-U#(WgXBdVS
zJM6nYqyp3F^gA8F2l{v%(x=le7pT|B92L?MIAD0K=g|L`sK9S=!OemeK%%Pv0000<
KMNUMnLSTZg%~a6<

literal 0
HcmV?d00001

diff --git a/libraries/ckeditor/plugins/embed/plugin.js b/libraries/ckeditor/plugins/embed/plugin.js
new file mode 100644
index 00000000..2ecbccb2
--- /dev/null
+++ b/libraries/ckeditor/plugins/embed/plugin.js
@@ -0,0 +1,105 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+	'use strict';
+
+	CKEDITOR.plugins.add( 'embed', {
+		icons: 'embed', // %REMOVE_LINE_CORE%
+		hidpi: true, // %REMOVE_LINE_CORE%
+		requires: 'embedbase',
+
+		init: function( editor ) {
+			var widgetDefinition = CKEDITOR.plugins.embedBase.createWidgetBaseDefinition( editor );
+
+			if ( !editor.config.embed_provider ) {
+				CKEDITOR.error( 'embed-no-provider-url' );
+			}
+
+			// Extend the base definition with additional properties.
+			CKEDITOR.tools.extend( widgetDefinition, {
+				// Use a dialog exposed by the embedbase plugin.
+				dialog: 'embedBase',
+				button: editor.lang.embedbase.button,
+				allowedContent: 'div[!data-oembed-url]',
+				requiredContent: 'div[data-oembed-url]',
+				providerUrl: new CKEDITOR.template( editor.config.embed_provider || '' ),
+
+				// The filter element callback actually allows all divs with data-oembed-url,
+				// so registering styles to the filter is virtually unnecessary because
+				// classes won't be filtered out. However, registering them will make filter.check() work
+				// which may be important in some cases.
+				styleToAllowedContentRules: function( style ) {
+					// Retrieve classes defined in the style.
+					var classes = style.getClassesArray();
+
+					return {
+						div: {
+							propertiesOnly: true,
+							classes: classes,
+							attributes: '!data-oembed-url'
+						}
+					};
+				},
+
+				upcast: function( el, data ) {
+					if ( el.name == 'div' && el.attributes[ 'data-oembed-url' ] ) {
+						data.url = el.attributes[ 'data-oembed-url' ];
+
+						return true;
+					}
+				},
+
+				downcast: function( el ) {
+					el.attributes[ 'data-oembed-url' ] = this.data.url;
+				}
+			}, true );
+
+			// Register the definition as 'embed' widget.
+			editor.widgets.add( 'embed', widgetDefinition );
+
+			// Do not filter contents of the div[data-oembed-url] at all.
+			editor.filter.addElementCallback( function( el ) {
+				if ( 'data-oembed-url' in el.attributes ) {
+					return CKEDITOR.FILTER_SKIP_TREE;
+				}
+			} );
+		}
+	} );
+
+} )();
+
+/**
+ * A template for the URL of the provider endpoint. This URL will be queried for each resource to be embedded.
+ *
+ * It uses the following parameters:
+ *
+ *	* `url` &ndash; The URL of the requested media, e.g. `https://twitter.com/ckeditor/status/401373919157821441`.
+ *	* `callback` &ndash; The name of the globally available callback used for JSONP requests.
+ *
+ * For example:
+ *
+ *		config.embed_provider = '//example.com/api/oembed-proxy?resource-url={url}&callback={callback}';
+ *
+ * By default CKEditor does not use any provider, although there is a ready-to-use URL available via Iframely:
+ *
+ *		config.embed_provider = '//ckeditor.iframe.ly/api/oembed?url={url}&callback={callback}'
+ *
+ * However, this endpoint contains certain limitations, e.g. it cannot embed Google Maps content.
+ * It is recommended to set up an account on the [Iframely](https://iframely.com/) service for
+ * better control over embedded content.
+ *
+ * Read more in the [documentation](#!/guide/dev_media_embed)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/mediaembed.html).
+ *
+ * Refer to {@link CKEDITOR.plugins.embedBase.baseDefinition#providerUrl} for more information about content providers.
+ *
+ * **Important note:** Prior to version 4.7 this configuration option defaulted to the
+ * `//ckeditor.iframe.ly/api/oembed?url={url}&callback={callback}` string.
+ *
+ * @since 4.5
+ * @cfg {String} [embed_provider='']
+ * @member CKEDITOR.config
+ */
diff --git a/libraries/ckeditor/plugins/embedbase/dialogs/embedbase.js b/libraries/ckeditor/plugins/embedbase/dialogs/embedbase.js
new file mode 100644
index 00000000..014282f3
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/dialogs/embedbase.js
@@ -0,0 +1,99 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/* global alert */
+
+CKEDITOR.dialog.add( 'embedBase', function( editor ) {
+	'use strict';
+
+	var lang = editor.lang.embedbase;
+
+	return {
+		title: lang.title,
+		minWidth: 350,
+		minHeight: 50,
+
+		onLoad: function() {
+			var that = this,
+				loadContentRequest = null;
+
+			this.on( 'ok', function( evt ) {
+				// We're going to hide it manually, after remote response is fetched.
+				evt.data.hide = false;
+
+				// We don't want the widget system to finalize widget insertion (it happens with priority 20).
+				evt.stop();
+
+				// Indicate visually that waiting for the response (http://dev.ckeditor.com/ticket/13213).
+				that.setState( CKEDITOR.DIALOG_STATE_BUSY );
+
+				var url = that.getValueOf( 'info', 'url' );
+
+				loadContentRequest = that.widget.loadContent( url, {
+					noNotifications: true,
+
+					callback: function() {
+						if ( !that.widget.isReady() ) {
+							editor.widgets.finalizeCreation( that.widget.wrapper.getParent( true ) );
+						}
+
+						editor.fire( 'saveSnapshot' );
+
+						that.hide();
+						unlock();
+					},
+
+					errorCallback: function( messageTypeOrMessage ) {
+						that.getContentElement( 'info', 'url' ).select();
+
+						alert( that.widget.getErrorMessage( messageTypeOrMessage, url, 'Given' ) );
+
+						unlock();
+					}
+				} );
+			}, null, null, 15 );
+
+			this.on( 'cancel', function( evt ) {
+				if ( evt.data.hide && loadContentRequest ) {
+					loadContentRequest.cancel();
+					unlock();
+				}
+			} );
+
+			function unlock() {
+				// Visual waiting indicator is no longer needed (http://dev.ckeditor.com/ticket/13213).
+				that.setState( CKEDITOR.DIALOG_STATE_IDLE );
+				loadContentRequest = null;
+			}
+		},
+
+		contents: [
+			{
+				id: 'info',
+
+				elements: [
+					{
+						type: 'text',
+						id: 'url',
+						label: editor.lang.common.url,
+						required: true,
+
+						setup: function( widget ) {
+							this.setValue( widget.data.url );
+						},
+
+						validate: function() {
+							if ( !this.getDialog().widget.isUrlValid( this.getValue() ) ) {
+								return lang.unsupportedUrlGiven;
+							}
+
+							return true;
+						}
+					}
+				]
+			}
+		]
+	};
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/az.js b/libraries/ckeditor/plugins/embedbase/lang/az.js
new file mode 100644
index 00000000..d2a09bed
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/az.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'az', {
+	pathName: 'Multimedia obyektləri',
+	title: 'Multimedia obyektlərin quraşdırılması',
+	button: 'Multimedia obyekti quraşdır',
+	unsupportedUrlGiven: 'Daxil etdiyiniz linki dəstəklənmir',
+	unsupportedUrl: '{url} linki quraşdırıla bilməz',
+	fetchingFailedGiven: 'Daxil etdiyiniz linkdən gələn məlumat yanlışdır',
+	fetchingFailed: '{url} linkdən gələn məlumat yanlışdır',
+	fetchingOne: 'oEmbed tərəfindən cavabın yoxlanması...',
+	fetchingMany: 'oEmbed tərəfindən cavabların yoxlanması, {max}-dan {current} yerinə yetirilib...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/ca.js b/libraries/ckeditor/plugins/embedbase/lang/ca.js
new file mode 100644
index 00000000..236d5255
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/ca.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'ca', {
+	pathName: 'objecte multimèdia',
+	title: 'Objecte multimèdia incrustat',
+	button: 'Inserir objecte multimèdia incrustat',
+	unsupportedUrlGiven: 'La URL especificada no és compatible.',
+	unsupportedUrl: 'La URL {url} no és compatible pels objectes multimèdia incrustats.',
+	fetchingFailedGiven: 'No s\'ha pogut obtenir el contingut de la URL especificada.',
+	fetchingFailed: 'No s\'ha pogut obtenir el contingut de {url}.',
+	fetchingOne: 'Recuperant resposta de oEmbed...',
+	fetchingMany: 'Recuperant respostes dels oEmbed, {current} de {max} finalitzats...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/cs.js b/libraries/ckeditor/plugins/embedbase/lang/cs.js
new file mode 100644
index 00000000..6949e047
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/cs.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'cs', {
+	pathName: 'objekt média',
+	title: 'Vložení médií',
+	button: 'Vložit médium',
+	unsupportedUrlGiven: 'Zadaná URL není podporována.',
+	unsupportedUrl: 'URL {url} není podporována ',
+	fetchingFailedGiven: 'Pro zadanou adresu URL nelze získat obsah.',
+	fetchingFailed: 'Nelze získat obsah na {url}.',
+	fetchingOne: 'Získávání odpovědí oEmbed...',
+	fetchingMany: 'Získávání odpovědí oEmbed. {current} z {max} hotovo...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/da.js b/libraries/ckeditor/plugins/embedbase/lang/da.js
new file mode 100644
index 00000000..214ec621
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/da.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'da', {
+	pathName: 'media objekt',
+	title: 'Media Embed',
+	button: 'Indsæt Media Embed',
+	unsupportedUrlGiven: 'Den angivende URL er ikke undersøttet.',
+	unsupportedUrl: 'URLen {url} er ikke undersøttet af Media Embed.',
+	fetchingFailedGiven: 'Kunne ikke hente indholdet fra den angivende URL.',
+	fetchingFailed: 'Kunne ikke hente indholdet fra {url}.',
+	fetchingOne: 'Henter oEmbed-svar',
+	fetchingMany: 'Henter oEmbed-svar, {current} af {max} færdige...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/de-ch.js b/libraries/ckeditor/plugins/embedbase/lang/de-ch.js
new file mode 100644
index 00000000..47ee89c8
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/de-ch.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'de-ch', {
+	pathName: 'Medienobjekt',
+	title: 'Media Embed (Medieninhalte)',
+	button: 'Medieninhalte einfügen',
+	unsupportedUrlGiven: 'Die angegebene URL wird nicht unterstützt.',
+	unsupportedUrl: 'Die URL {url} wird von Media Embed nicht unterstützt.',
+	fetchingFailedGiven: 'Abrufen des Inhalts für die angegebene URL ist fehlgeschlagen.',
+	fetchingFailed: 'Abrufen des Inhalts für {url} ist fehlgeschlagen.',
+	fetchingOne: 'Empfangen der Medieninhalte...',
+	fetchingMany: 'Medieninhalte werden abgerufen, {current} von {max} empfangen...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/de.js b/libraries/ckeditor/plugins/embedbase/lang/de.js
new file mode 100644
index 00000000..5dd47e61
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/de.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'de', {
+	pathName: 'Medienobjekt',
+	title: 'Media Embed (Medieninhalte)',
+	button: 'Medieninhalte einfügen',
+	unsupportedUrlGiven: 'Die angegebene URL wird nicht unterstützt.',
+	unsupportedUrl: 'Die URL {url} wird von Media Embed nicht unterstützt.',
+	fetchingFailedGiven: 'Abrufen des Inhalts für die angegebene URL ist fehlgeschlagen.',
+	fetchingFailed: 'Abrufen des Inhalts für {url} ist fehlgeschlagen.',
+	fetchingOne: 'Empfangen der Medieninhalte...',
+	fetchingMany: 'Medieninhalte werden abgerufen, {current} von {max} empfangen...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/en.js b/libraries/ckeditor/plugins/embedbase/lang/en.js
new file mode 100644
index 00000000..70a785ea
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/en.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'en', {
+	pathName: 'media object',
+	title: 'Media Embed',
+	button: 'Insert Media Embed',
+	unsupportedUrlGiven: 'The specified URL is not supported.',
+	unsupportedUrl: 'The URL {url} is not supported by Media Embed.',
+	fetchingFailedGiven: 'Failed to fetch content for the given URL.',
+	fetchingFailed: 'Failed to fetch content for {url}.',
+	fetchingOne: 'Fetching oEmbed response...',
+	fetchingMany: 'Fetching oEmbed responses, {current} of {max} done...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/eo.js b/libraries/ckeditor/plugins/embedbase/lang/eo.js
new file mode 100644
index 00000000..e9d0782d
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/eo.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'eo', {
+	pathName: 'Datumportila objekto',
+	title: 'Enkorpigo de datumportilo',
+	button: 'Enmetu enkorpigitan datumportilon.',
+	unsupportedUrlGiven: 'la indikita URL ne estas subtenata.',
+	unsupportedUrl: 'La URL {url} ne estas subtenata de enkorpigo de datumportilo.',
+	fetchingFailedGiven: 'Rekuperi enhavon por la indikitan URL malsukcesis.',
+	fetchingFailed: 'Rekuperi enhavon por  {url} malsukcesis.',
+	fetchingOne: 'La respondo de la enkorpigita objekto estas serĉata ...',
+	fetchingMany: 'La respondoj de la enkorpigita objekto estas serĉataj, {current} el {max} faritaj...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/es-mx.js b/libraries/ckeditor/plugins/embedbase/lang/es-mx.js
new file mode 100644
index 00000000..a0c7f8f7
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/es-mx.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'es-mx', {
+	pathName: 'objeto multimedia',
+	title: 'Empotrar multimedia',
+	button: 'Insertar multimedia empotrado',
+	unsupportedUrlGiven: 'La URL especificada no es soportada.',
+	unsupportedUrl: 'La URL {url} no es soportada para empotrar multimedia',
+	fetchingFailedGiven: 'No se pudo obtener el contenido de la URL dada.',
+	fetchingFailed: 'No se pudo obtener el contenido de {url}.',
+	fetchingOne: 'Recuperar o Incrustar respuesta ...',
+	fetchingMany: 'Recuperar o Incrustar respuestas, {current} de {max} listo...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/es.js b/libraries/ckeditor/plugins/embedbase/lang/es.js
new file mode 100644
index 00000000..8e1bf924
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/es.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'es', {
+	pathName: 'objeto media',
+	title: 'Media incrustado',
+	button: 'Insertar Media incrustado',
+	unsupportedUrlGiven: 'La URL especificada no está soportada.',
+	unsupportedUrl: 'La URL {url} no está soportada por Medio Inscrustado.',
+	fetchingFailedGiven: 'Fallo al recuperar el contenido de la URL dada.',
+	fetchingFailed: 'Fallo al recuperar contenido de {url}.',
+	fetchingOne: 'Recuperando respuesta oEmbed...',
+	fetchingMany: 'Recuperando respuestas oEmbed, {current} de {max} hecho...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/eu.js b/libraries/ckeditor/plugins/embedbase/lang/eu.js
new file mode 100644
index 00000000..c8c41e4b
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/eu.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'eu', {
+	pathName: 'multimedia objektua',
+	title: 'Media Embed',
+	button: 'Txertatu edukia',
+	unsupportedUrlGiven: 'Ez dago zehazturiko URLarentzako euskarririk',
+	unsupportedUrl: 'Media Embed-ek ez dauka {url} URLarentzako euskarririk.',
+	fetchingFailedGiven: 'Huts egin du emandako URLetik edukia eskuratzean.',
+	fetchingFailed: 'Huts egin du {url}(e)tik edukia eskuratzean.',
+	fetchingOne: 'oEmbed erantzuna eskuratzen...',
+	fetchingMany: 'oEmbed erantzunak eskuratzen, {current} / {max}'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/fr.js b/libraries/ckeditor/plugins/embedbase/lang/fr.js
new file mode 100644
index 00000000..24096c6a
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/fr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'fr', {
+	pathName: 'objet média',
+	title: 'Incorporation de média',
+	button: 'Incorporer un média',
+	unsupportedUrlGiven: 'L\'URL spécifiée n\'est pas supportée.',
+	unsupportedUrl: 'L\'URL {url} n\'est pas supportée par l\'incorporation de média.',
+	fetchingFailedGiven: 'Échec de la récupération du contenu de l\'URL donnée.',
+	fetchingFailed: 'Échec de la récupération du contenu pour {url}.',
+	fetchingOne: 'Récupération de la réponse oEmbed...',
+	fetchingMany: 'Récupération des réponses oEmbed, {current} sur {max} effectué...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/gl.js b/libraries/ckeditor/plugins/embedbase/lang/gl.js
new file mode 100644
index 00000000..8666047a
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/gl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'gl', {
+	pathName: 'obxecto multimedia',
+	title: 'Multimedia integrado',
+	button: 'Inserir un  multimedia integrado',
+	unsupportedUrlGiven: 'O URL especificado non está admitido.',
+	unsupportedUrl: 'O URL {url} non está admitido polo multimedia integrado.',
+	fetchingFailedGiven: 'Non foi posíbel obter o contido do URL indicado.',
+	fetchingFailed: 'Non foi posíbel obter o contido der {url}.',
+	fetchingOne: 'Obtendo a resposta oEmbed...',
+	fetchingMany: 'Obtendo as respostas oEmbed, feito {current} de {max}...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/hr.js b/libraries/ckeditor/plugins/embedbase/lang/hr.js
new file mode 100644
index 00000000..4acfe6e2
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/hr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'hr', {
+	pathName: 'objekt medija',
+	title: 'Media Embed',
+	button: 'Umetanje Media Embed',
+	unsupportedUrlGiven: 'Navedeni URL nije podržan',
+	unsupportedUrl: 'URL {url} nije podržan od strane Media Embed-a.',
+	fetchingFailedGiven: 'Nije moguće dohvatiti sadržaj danog URL-a.',
+	fetchingFailed: 'Nije moguće dohvatiti sadržaj za {url}.',
+	fetchingOne: 'Dohvaćanje oEmbed odgovora...',
+	fetchingMany: 'Dohvaćanje oEmbed odgovora,  {current} od {max} gotovo...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/hu.js b/libraries/ckeditor/plugins/embedbase/lang/hu.js
new file mode 100644
index 00000000..805c4d2e
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/hu.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'hu', {
+	pathName: 'média objektum',
+	title: 'Média beágyazása',
+	button: 'Beágyazott média beszúrása',
+	unsupportedUrlGiven: 'A megadott URL nem támogatott.',
+	unsupportedUrl: 'Az URL-t {url} a média beágyazása nem támogatja.',
+	fetchingFailedGiven: 'Nem sikerült a megadott URL-hez tartalmat kinyerni.',
+	fetchingFailed: 'Nem sikerült az {url}-nek a tartalmát kinyerni.',
+	fetchingOne: 'oEmbed válasz kinyerése...',
+	fetchingMany: 'oEmbed válasz kinyerése folyamatban, {current} a {max}-ból kész...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/id.js b/libraries/ckeditor/plugins/embedbase/lang/id.js
new file mode 100644
index 00000000..a8f4cbaa
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/id.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'id', {
+	pathName: 'media object', // MISSING
+	title: 'Sisipkan Media',
+	button: 'Insert Media Embed', // MISSING
+	unsupportedUrlGiven: 'The specified URL is not supported.', // MISSING
+	unsupportedUrl: 'The URL {url} is not supported by Media Embed.', // MISSING
+	fetchingFailedGiven: 'Failed to fetch content for the given URL.', // MISSING
+	fetchingFailed: 'Gagal mengambil konten untuk {url}',
+	fetchingOne: 'Fetching oEmbed response...', // MISSING
+	fetchingMany: 'Fetching oEmbed responses, {current} of {max} done...' // MISSING
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/it.js b/libraries/ckeditor/plugins/embedbase/lang/it.js
new file mode 100644
index 00000000..72cf3a5b
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/it.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'it', {
+	pathName: 'oggetto multimediale',
+	title: 'Media incorporato',
+	button: 'Inserisci media incorporato',
+	unsupportedUrlGiven: 'L\'URL specificato non è supportato.',
+	unsupportedUrl: 'L\'URL {url} non è supportato da Media incorporato.',
+	fetchingFailedGiven: 'Non è stato possibile recuperareil contenuto per l\'URL specificato.',
+	fetchingFailed: 'Non è stato possibile recuperare il contenuto per {url}.',
+	fetchingOne: 'Recupero della risposta oEmbed...',
+	fetchingMany: 'Recupero delle risposta oEmbed, {current} di {max} completati...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/ja.js b/libraries/ckeditor/plugins/embedbase/lang/ja.js
new file mode 100644
index 00000000..a1fb0e4d
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/ja.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'ja', {
+	pathName: 'media object', // MISSING
+	title: 'Media Embed', // MISSING
+	button: 'Insert Media Embed', // MISSING
+	unsupportedUrlGiven: '指定されたURLはサポートされていません。',
+	unsupportedUrl: 'The URL {url} is not supported by Media Embed.', // MISSING
+	fetchingFailedGiven: 'Failed to fetch content for the given URL.', // MISSING
+	fetchingFailed: 'Failed to fetch content for {url}.', // MISSING
+	fetchingOne: 'Fetching oEmbed response...', // MISSING
+	fetchingMany: 'Fetching oEmbed responses, {current} of {max} done...' // MISSING
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/ko.js b/libraries/ckeditor/plugins/embedbase/lang/ko.js
new file mode 100644
index 00000000..c5db672b
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/ko.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'ko', {
+	pathName: '미디어 오브젝트',
+	title: '미디어 임베드',
+	button: '미디어 임베드 삽입',
+	unsupportedUrlGiven: '지원하지 않는 주소 형식입니다.',
+	unsupportedUrl: '입력하신 주소 {url}은 지원되지 않는 형식입니다.',
+	fetchingFailedGiven: '입력하신 주소에서 내용을 불러올 수 없습니다.',
+	fetchingFailed: '입력하신  주소 {url}에서 내용을 불러올 수 없습니다.',
+	fetchingOne: 'oEmbed 응답을 가져오는 중...',
+	fetchingMany: '총 {max} 개 중{current} 번째 oEmbed 응답을 가져오는 중...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/ku.js b/libraries/ckeditor/plugins/embedbase/lang/ku.js
new file mode 100644
index 00000000..4667de06
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/ku.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'ku', {
+	pathName: 'ڕاگەیاندنی بەرکار',
+	title: 'خستنەناوی ڕاگەیاندن',
+	button: 'خستنەناوی ڕاگەیاندن',
+	unsupportedUrlGiven: 'بەستەری نیشانکراو پشتیوان نەکراوە.',
+	unsupportedUrl: 'بەستەری {url} پشتیواننەککراوە لەلایەن خستنەناوی ڕاگەیاندن.',
+	fetchingFailedGiven: 'سەرکەوتوونەبوو لە هێنانی ناوەڕۆکی بەستەری دراو',
+	fetchingFailed: 'سەرکەوتوونەبوو لە هێنانەی ناوەڕۆکی ئەم بەستەرە {url}.',
+	fetchingOne: 'لە هەوڵی وەڵامی خستنەناوە',
+	fetchingMany: 'لە هەوڵی هێنانی خستنەناوە, {current} لە {max} کۆتایهاتووە...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/nb.js b/libraries/ckeditor/plugins/embedbase/lang/nb.js
new file mode 100644
index 00000000..1779a83a
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/nb.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'nb', {
+	pathName: 'mediaobjekt',
+	title: 'Media-innbygging',
+	button: 'Sett inn mediaobjekt',
+	unsupportedUrlGiven: 'Den oppgitte URL-en er ikke støttet.',
+	unsupportedUrl: 'URL-en {url} er ikke støttet av Media-innbygging.',
+	fetchingFailedGiven: 'Kunne ikke hente innhold for den oppgitte URL-en.',
+	fetchingFailed: 'Kunne ikke hente innhold for {url}.',
+	fetchingOne: 'Henter oEmbed-svar...',
+	fetchingMany: 'Henter oEmbed-svar, {current} av {max} fullført...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/nl.js b/libraries/ckeditor/plugins/embedbase/lang/nl.js
new file mode 100644
index 00000000..613487ec
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/nl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'nl', {
+	pathName: 'media object',
+	title: 'Mediareferentie',
+	button: 'Mediareferentie invoegen',
+	unsupportedUrlGiven: 'De opgegeven URL wordt niet ondersteund.',
+	unsupportedUrl: 'De URL {url} wordt niet ondersteund door Mediareferentie.',
+	fetchingFailedGiven: 'Kon de inhoud van de opgegeven URL niet ophalen',
+	fetchingFailed: 'Kon de inhoud van {url} niet ophalen.',
+	fetchingOne: 'Ophalen van oEmbed antwoord…',
+	fetchingMany: 'Ophalen van oEmbed antwoorden, {current} van {max} klaar…'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/oc.js b/libraries/ckeditor/plugins/embedbase/lang/oc.js
new file mode 100644
index 00000000..559f8ce1
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/oc.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'oc', {
+	pathName: 'objècte mèdia',
+	title: 'Incorporacion de mèdia',
+	button: 'Incorporar un mèdia',
+	unsupportedUrlGiven: 'L\'URL especificada es pas suportada.',
+	unsupportedUrl: 'L\'URL {url} es pas suportada per l\'incorporacion de mèdia.',
+	fetchingFailedGiven: 'Fracàs de la recuperacion del contengut de l\'URL donada.',
+	fetchingFailed: 'Fracàs de la recuperacion del contengut per {url}.',
+	fetchingOne: 'Recuperacion de la responsa oEmbed...',
+	fetchingMany: 'Recuperacion de las responsas oEmbed, {current} sus {max} efectuat...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/pl.js b/libraries/ckeditor/plugins/embedbase/lang/pl.js
new file mode 100644
index 00000000..d5d2d967
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/pl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'pl', {
+	pathName: 'obiekt multimediów',
+	title: 'Osadzenie multimediów (oEmbed)',
+	button: 'Osadź obiekt multimediów (oEmbed)',
+	unsupportedUrlGiven: 'Podany adres URL nie jest obsługiwany.',
+	unsupportedUrl: 'Adres URL {url} nie jest obsługiwany przez funkcjonalność osadzania multimediów.',
+	fetchingFailedGiven: 'Nie udało się pobrać zawartości dla podanego adresu URL.',
+	fetchingFailed: 'Nie udało się pobrać zawartości dla {url}.',
+	fetchingOne: 'Pobieranie odpowiedzi oEmbed...',
+	fetchingMany: 'Pobieranie odpowiedzi oEmbed, gotowe {current} z {max}...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/pt-br.js b/libraries/ckeditor/plugins/embedbase/lang/pt-br.js
new file mode 100644
index 00000000..46e89fc8
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/pt-br.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'pt-br', {
+	pathName: 'objeto de mídia',
+	title: 'Incorporação de Mídia',
+	button: 'Inserir Incorporação de Mídia',
+	unsupportedUrlGiven: 'A URL especificada não é suportada.',
+	unsupportedUrl: 'A UTL {url} não é suportada pela Incorporação de Mídia.',
+	fetchingFailedGiven: 'Falha ao obter conteúdo para a URL informada.',
+	fetchingFailed: 'Falha ao obter conteúdo para {url}.',
+	fetchingOne: 'Obtendo resposta oEmbed...',
+	fetchingMany: 'Obtendo respostas oEmbed, {current} de {max} completos...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/pt.js b/libraries/ckeditor/plugins/embedbase/lang/pt.js
new file mode 100644
index 00000000..d048caa2
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/pt.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'pt', {
+	pathName: 'objeto de media',
+	title: 'Embeber media',
+	button: 'Insert Media Embed', // MISSING
+	unsupportedUrlGiven: 'O URL especificado não é suportado.',
+	unsupportedUrl: 'The URL {url} is not supported by Media Embed.', // MISSING
+	fetchingFailedGiven: 'Failed to fetch content for the given URL.', // MISSING
+	fetchingFailed: 'Failed to fetch content for {url}.', // MISSING
+	fetchingOne: 'Fetching oEmbed response...', // MISSING
+	fetchingMany: 'Fetching oEmbed responses, {current} of {max} done...' // MISSING
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/ru.js b/libraries/ckeditor/plugins/embedbase/lang/ru.js
new file mode 100644
index 00000000..17ab9810
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/ru.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'ru', {
+	pathName: 'Медиа объект',
+	title: 'Медиаконтент',
+	button: 'Вставить Медиаконтент',
+	unsupportedUrlGiven: 'Данный URL не поддерживается.',
+	unsupportedUrl: 'URL {url} не поддерживается Media Embed.',
+	fetchingFailedGiven: 'Не удалось подгрузить содержимое для заданного URL',
+	fetchingFailed: 'Не удалось подгрузить содержимое для {url}',
+	fetchingOne: 'Подгружаем oEmbed ответ...',
+	fetchingMany: 'Подгружаем oEmbed ответы, {current} из {max} подгружено...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/sk.js b/libraries/ckeditor/plugins/embedbase/lang/sk.js
new file mode 100644
index 00000000..069f363b
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/sk.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'sk', {
+	pathName: 'media objekt',
+	title: 'Media Embed',
+	button: 'Vložte Media Embed',
+	unsupportedUrlGiven: 'Zadaná URL nie je podporovaná.',
+	unsupportedUrl: 'URL {url} nie je podporovaná Media Embedom.',
+	fetchingFailedGiven: 'Nepodarilo sa získať obsah zo zadanej URL.',
+	fetchingFailed: 'Nepodarilo sa získať obsah z {url}.',
+	fetchingOne: 'Získavanie oEmbed odpovede...',
+	fetchingMany: 'Získavanie oEmbed odpovede, {current} z {max} hotových...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/sv.js b/libraries/ckeditor/plugins/embedbase/lang/sv.js
new file mode 100644
index 00000000..944df0df
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/sv.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'sv', {
+	pathName: 'mediaobjekt',
+	title: 'Mediainbäddning',
+	button: 'Lägg in mediainbäddning',
+	unsupportedUrlGiven: 'Den angivna URL:en stöds inte.',
+	unsupportedUrl: 'URL:en {url} stöds inte av mediainbäddningen.',
+	fetchingFailedGiven: 'Lyckades inte hämta innehållet från den angivna URL:en.',
+	fetchingFailed: 'Lyckades inte hämta innehåll från {url}.',
+	fetchingOne: 'Hämtar oEmbed-svar...',
+	fetchingMany: 'Hämtar oEmbed-svar, {current} av {max} färdiga...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/tr.js b/libraries/ckeditor/plugins/embedbase/lang/tr.js
new file mode 100644
index 00000000..ab314e89
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/tr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'tr', {
+	pathName: 'medya nesnesi',
+	title: 'Gömülmüş Medya',
+	button: 'Gömülü Medya Ekle',
+	unsupportedUrlGiven: 'BelirtmiÅŸ olduÄŸunuz URL desteklenmiyor.',
+	unsupportedUrl: 'Belirttiğiniz URL {url} gömülü medya tarafından desteklenmiyor.',
+	fetchingFailedGiven: 'Vermiş olduğunuz URL\'nin içeriği alınamadı.',
+	fetchingFailed: '{url} içeriği alınamadı.',
+	fetchingOne: 'oEmbed cevabı alınıyor...',
+	fetchingMany: 'oEmbed cevabı alınıyor, {current} / {max} tamamlandı...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/ug.js b/libraries/ckeditor/plugins/embedbase/lang/ug.js
new file mode 100644
index 00000000..d7c6eeb3
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/ug.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'ug', {
+	pathName: 'ۋاسىتە ئوبيېكتى',
+	title: 'سىڭدۈرمە ۋاسىتە',
+	button: 'سىڭدۈرمە ۋاسىتە قىستۇر',
+	unsupportedUrlGiven: 'The specified URL is not supported.', // MISSING
+	unsupportedUrl: 'The URL {url} is not supported by Media Embed.', // MISSING
+	fetchingFailedGiven: 'Failed to fetch content for the given URL.', // MISSING
+	fetchingFailed: 'Failed to fetch content for {url}.', // MISSING
+	fetchingOne: 'Fetching oEmbed response...', // MISSING
+	fetchingMany: 'Fetching oEmbed responses, {current} of {max} done...' // MISSING
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/uk.js b/libraries/ckeditor/plugins/embedbase/lang/uk.js
new file mode 100644
index 00000000..9556f829
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/uk.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'uk', {
+	pathName: 'Медіаоб’єкт',
+	title: 'Медіаконтент',
+	button: 'Вставити медіаконтент',
+	unsupportedUrlGiven: 'Вказане URL посилання не підтримується.',
+	unsupportedUrl: 'URL посилання {url} не підтримується медіаконтентом.',
+	fetchingFailedGiven: 'Не вдалося отримати контент для даного URL посилання.',
+	fetchingFailed: 'Не вдалося отримати контент для {url}.',
+	fetchingOne: 'Отримання oEmbed відповіді...',
+	fetchingMany: 'Отримання {current} із {max} oEmbed відповідей завершено....'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/zh-cn.js b/libraries/ckeditor/plugins/embedbase/lang/zh-cn.js
new file mode 100644
index 00000000..a25640d9
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/zh-cn.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'zh-cn', {
+	pathName: '媒体对象',
+	title: '嵌入媒体',
+	button: '插入媒体',
+	unsupportedUrlGiven: '不支持指定的 URL',
+	unsupportedUrl: '嵌入媒体不支持此 URL {url}',
+	fetchingFailedGiven: '无法抓取此 URL 的内容',
+	fetchingFailed: '无法抓取 {url} 的内容',
+	fetchingOne: '正在抓取...',
+	fetchingMany: '正在抓取,{max} 中的 {current} ...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/lang/zh.js b/libraries/ckeditor/plugins/embedbase/lang/zh.js
new file mode 100644
index 00000000..aa8f7300
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/lang/zh.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'embedbase', 'zh', {
+	pathName: '媒體元件',
+	title: '內嵌媒體',
+	button: '插入內嵌媒體',
+	unsupportedUrlGiven: '不支援指定的 URL。',
+	unsupportedUrl: '內嵌媒體不支援 URL {url} 。',
+	fetchingFailedGiven: '抓取指定 URL 的內容失敗。',
+	fetchingFailed: '抓取 {url} 的內容失敗。',
+	fetchingOne: '正在抓取 oEmbed 回應...',
+	fetchingMany: '正在抓取 oEmbed 回應,{max} 中的 {current} 已完成...'
+} );
diff --git a/libraries/ckeditor/plugins/embedbase/plugin.js b/libraries/ckeditor/plugins/embedbase/plugin.js
new file mode 100644
index 00000000..7161f973
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedbase/plugin.js
@@ -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() {
+	'use strict';
+
+	/**
+	 * JSONP communication.
+	 *
+	 * @private
+	 * @singleton
+	 * @class CKEDITOR.plugins.embedBase._jsonp
+	 */
+	var Jsonp = {
+		/**
+		 * Creates a `<script>` element and attaches it to the document `<body>`.
+		 *
+		 * @private
+		 */
+		_attachScript: function( url, errorCallback ) {
+			// ATM we cannot use CKE scriptloader here, because it will make sure that script
+			// with given URL is added only once.
+			var script = new CKEDITOR.dom.element( 'script' );
+			script.setAttribute( 'src', url );
+			script.on( 'error', errorCallback );
+
+			CKEDITOR.document.getBody().append( script );
+
+			return script;
+		},
+
+		/**
+		 * Sends a request using the JSONP technique.
+		 *
+		 * @param {CKEDITOR.template} urlTemplate The template of the URL to be requested. All properties
+		 * passed in `urlParams` can be used, plus a `{callback}`, which represents a JSONP callback, must be defined.
+		 * @param {Object} urlParams Parameters to be passed to the `urlTemplate`.
+		 * @param {Function} callback
+		 * @param {Function} [errorCallback]
+		 * @returns {Object} The request object with a `cancel()` method.
+		 */
+		sendRequest: function( urlTemplate, urlParams, callback, errorCallback ) {
+			var request = {};
+			urlParams = urlParams || {};
+
+			var callbackKey = CKEDITOR.tools.getNextNumber(),
+				scriptElement;
+
+			urlParams.callback = 'CKEDITOR._.jsonpCallbacks[' + callbackKey + ']';
+
+			CKEDITOR._.jsonpCallbacks[ callbackKey ] = function( response ) {
+				// On IEs scripts are sometimes loaded synchronously. It is bad for two reasons:
+				// * nature of sendRequest() is unstable,
+				// * scriptElement does not exist yet.
+				setTimeout( function() {
+					cleanUp();
+					callback( response );
+				} );
+			};
+
+			scriptElement = this._attachScript( urlTemplate.output( urlParams ), function() {
+				cleanUp();
+				errorCallback && errorCallback();
+			} );
+
+			request.cancel = cleanUp;
+
+			function cleanUp() {
+				if ( scriptElement ) {
+					scriptElement.remove();
+					delete CKEDITOR._.jsonpCallbacks[ callbackKey ];
+					scriptElement = null;
+				}
+			}
+
+			return request;
+		}
+	};
+
+	CKEDITOR.plugins.add( 'embedbase', {
+		lang: 'az,ca,cs,da,de,de-ch,en,eo,es,es-mx,eu,fr,gl,hr,hu,id,it,ja,ko,ku,nb,nl,oc,pl,pt,pt-br,ru,sk,sv,tr,ug,uk,zh,zh-cn', // %REMOVE_LINE_CORE%
+		requires: 'dialog,widget,notificationaggregator',
+
+		onLoad: function() {
+			CKEDITOR._.jsonpCallbacks = {};
+		},
+
+		init: function() {
+			CKEDITOR.dialog.add( 'embedBase', this.path + 'dialogs/embedbase.js' );
+		}
+	} );
+
+	/**
+	 * Creates a new embed widget base definition. After other necessary properties are filled this definition
+	 * may be {@link CKEDITOR.plugins.widget.repository#add registered} as a new, independent widget for
+	 * embedding content.
+	 *
+	 * By default an embed widget is set up to work with [oEmbed providers](http://www.oembed.com/) using JSONP
+	 * requests, such as [Iframely](https://iframely.com/) or [Noembed](https://noembed.com/). It can be,
+	 * however, easily configured to use other providers and communication methods, including custom systems
+	 * or local embed databases.
+	 *
+	 * See example usage of this method in:
+	 *
+	 * * [/plugins/embed/plugin.js](https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/embed/plugin.js)
+	 * * [/plugins/embedsemantic/plugin.js](https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/embedsemantic/plugin.js)
+	 *
+	 * Note that both these plugins reuse the [dialog](https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/embedbase/dialogs/embedbase.js)
+	 * defined by the `embedbase` plugin. Integration of the asynchronous way of loading content with a dialog requires additional
+	 * effort. Check the dialog's code for more details.
+	 *
+	 * @static
+	 * @param {CKEDITOR.editor} editor
+	 * @returns {CKEDITOR.plugins.embedBase.baseDefinition}
+	 * @member CKEDITOR.plugins.embedBase
+	 */
+	function createWidgetBaseDefinition( editor ) {
+		var aggregator,
+			lang = editor.lang.embedbase;
+
+		/**
+		 * An embed widget base definition. It predefines a few {@link CKEDITOR.plugins.widget.definition widget definition}
+		 * properties such as {@link #mask}, {@link #template} and {@link #pathName} and adds methods related to
+		 * content embedding.
+		 *
+		 * To create a base definition use the {@link CKEDITOR.plugins.embedBase#createWidgetBaseDefinition} method.
+		 *
+		 * Note: For easier browsing of this class's API you can hide inherited method using the "Show" drop-down
+		 * on the right-hand side.
+		 *
+		 * @abstract
+		 * @class CKEDITOR.plugins.embedBase.baseDefinition
+		 * @extends CKEDITOR.plugins.widget.definition
+		 */
+		return {
+			mask: true,
+			template: '<div></div>',
+			pathName: lang.pathName,
+
+			/**
+			 * Response cache. This cache object will be shared between all instances of this widget.
+			 *
+			 * @private
+			 */
+			_cache: {},
+
+			/**
+			 * A regular expression to pre-validate URLs.
+			 *
+			 * See:
+			 *
+			 * * [https://iframely.com/docs/providers],
+			 * * {@link #isUrlValid}.
+			 */
+			urlRegExp: /^((https?:)?\/\/|www\.)/i,
+
+			/**
+			 * The template used to generate the URL of the content provider. Content provider is a service
+			 * which the embed widget will request in order to get an [oEmbed](http://www.oembed.com/) response that
+			 * can be transformed into content which can be embedded in the editor.
+			 *
+			 * Example content providers are:
+			 *
+			 * * [Iframely](https://iframely.com/),
+			 * * [Noembed](https://noembed.com/).
+			 *
+			 * Both Iframely and Noembed are **proxy** services which support **JSONP requests**, hence they are not limited by the
+			 * same-origin policy. Unfortunately, usually oEmbed services exposed by real content providers
+			 * like YouTube or Twitter do not support XHR with CORS or do not support oEmbed at all which makes it
+			 * impossible or hard to get such content to be embedded in the editor. This problem is solved by proxy content providers
+			 * like Iframely and Noembed.
+			 *
+			 * This property must be defined after creating an embed widget base definition.
+			 *
+			 * By default two values are passed to the template:
+			 *
+			 * * `{url}` &ndash; The URL of the resource to be embedded.
+			 * * `{callback}` &ndash; The JSONP callback to be executed.
+			 *
+			 * Example value:
+			 *
+			 *		widgetDefinition.providerUrl = new CKEDITOR.template(
+			 *			'//ckeditor.iframe.ly/api/oembed?url={url}&callback={callback}'
+			 *		);
+			 *
+			 * @property {CKEDITOR.template} providerUrl
+			 */
+
+			init: function() {
+				this.on( 'sendRequest', function( evt ) {
+					this._sendRequest( evt.data );
+				}, this, null, 999 );
+
+				// Expose the widget in the dialog - needed to trigger loadContent() and do error handling.
+				this.on( 'dialog', function( evt ) {
+					evt.data.widget = this;
+				}, this );
+
+				this.on( 'handleResponse', function( evt ) {
+					if ( evt.data.html ) {
+						return;
+					}
+
+					var retHtml = this._responseToHtml( evt.data.url, evt.data.response );
+
+					if ( retHtml !== null ) {
+						evt.data.html = retHtml;
+					} else {
+						evt.data.errorMessage = 'unsupportedUrl';
+						evt.cancel();
+					}
+				}, this, null, 999 );
+			},
+
+			/**
+			 * Loads content for a given resource URL by requesting the {@link #providerUrl provider}.
+			 *
+			 * Usually widgets are controlled by the {@link CKEDITOR.plugins.widget#setData} method. However,
+			 * loading content is an asynchronous operation due to client-server communication, and it would not
+			 * be possible to pass callbacks to the {@link CKEDITOR.plugins.widget#setData} method so this new method
+			 * is defined for embed widgets.
+			 *
+			 * This method fires two events that allow to customize widget behavior without changing its code:
+			 *
+			 * * {@link #sendRequest},
+			 * * {@link #handleResponse} (if the request was successful).
+			 *
+			 * Note: This method is always asynchronous, even if the cache was hit.
+			 *
+			 * Example usage:
+			 *
+			 *		var url = 'https://twitter.com/reinmarpl/status/573118615274315776';
+			 *		widget.loadContent( url, {
+			 *			callback: function() {
+			 *				// Success. It is a good time to save a snapshot.
+			 *				editor.fire( 'saveSnapshot' );
+			 *				console.log( widget.data.url ); // The above URL. It is only changed
+			 *												// once the content is successfully loaded.
+			 *			},
+			 *
+			 *			errorCallback: function( message ) {
+			 *				editor.showNotification( widget.getErrorMessage( message, url ), 'warning' );
+			 *			}
+			 *		} );
+			 *
+			 * @param {String} url Resource URL to be embedded.
+			 * @param {Object} opts
+			 * @param {Function} [opts.callback] Callback called when content was successfully loaded into the editor.
+			 * @param {Function} [opts.errorCallback] Callback called when an error occurred.
+			 * @param {String} opts.errorCallback.messageTypeOrMessage See {@link #getErrorMessage}.
+			 * @param {Boolean} [opts.noNotifications] Do not show notifications (useful when the dialog is open).
+			 * @returns {CKEDITOR.plugins.embedBase.request}
+			 */
+			loadContent: function( url, opts ) {
+				opts = opts || {};
+
+				var that = this,
+					cachedResponse = this._getCachedResponse( url ),
+					request = {
+						noNotifications: opts.noNotifications,
+						url: url,
+						callback: finishLoading,
+						errorCallback: function( msg ) {
+							that._handleError( request, msg );
+							if ( opts.errorCallback ) {
+								opts.errorCallback( msg );
+							}
+						}
+					};
+
+				if ( cachedResponse ) {
+					// Keep the async nature (it caused a bug the very first day when the loadContent()
+					// was synchronous when cache was hit :D).
+					setTimeout( function() {
+						finishLoading( cachedResponse );
+					} );
+					return;
+				}
+
+				if ( !opts.noNotifications ) {
+					request.task = this._createTask();
+				}
+
+				// The execution will be followed by #sendRequest's listener.
+				this.fire( 'sendRequest', request );
+
+				function finishLoading( response ) {
+					request.response = response;
+
+					// Check if widget is still valid.
+					if ( !that.editor.widgets.instances[ that.id ] ) {
+						CKEDITOR.warn( 'embedbase-widget-invalid' );
+
+						if ( request.task ) {
+							request.task.done();
+						}
+
+						return;
+					}
+
+					if ( that._handleResponse( request ) ) {
+						that._cacheResponse( url, response );
+						if ( opts.callback ) {
+							opts.callback();
+						}
+					}
+				}
+
+				return request;
+			},
+
+			/**
+			 * Checks whether the URL is valid. Usually the content provider makes the final validation
+			 * as only the provider knows what kind of URLs are accepted. However, to give the user some immediate feedback
+			 * a synchronous validation is performed using the {@link #urlRegExp} pattern and the {@link #validateUrl} event.
+			 *
+			 * @param {String} url The URL to check.
+			 * @returns {Boolean} Whether the URL is valid (supported).
+			 */
+			isUrlValid: function( url ) {
+				return this.urlRegExp.test( url ) && this.fire( 'validateUrl', url ) !== false;
+			},
+
+			/**
+			 * Generates an error message based on the message type (with a possible suffix) or
+			 * the custom message template.
+			 *
+			 * This method is used when showing a notification or an alert (in a dialog) about an error.
+			 * Usually it is used with an error type which is a string from the `editor.lang.embedbase` object.
+			 *
+			 * There are two error types available at the moment: `'unsupportedUrl'` and `'fetchingFailed'`.
+			 * Additionally, both can be suffixed with `'Given'`. See the language entries to see the difference.
+			 * Inside the dialog this method is used with a suffix and to generate a notification message it is
+			 * used without a suffix.
+			 *
+			 * Additionally, a custom message may be passed and just like language entries, it can use the `{url}`
+			 * placeholder.
+			 *
+			 * While {@link #handleResponse handling the response} you can set an error message or its type. It will
+			 * be passed to this method later.
+			 *
+			 *		widget.on( 'handleResponse', function( evt ) {
+			 *			if ( evt.data.response.type != 'rich' ) {
+			 *				evt.data.errorMessage = '{url} cannot be embedded. Only rich type is supported.';
+			 *				evt.cancel();
+			 *
+			 *				// Or:
+			 *				evt.data.errorMessage = 'unsupportedUrl.';
+			 *				evt.cancel();
+			 *			}
+			 *		} );
+			 *
+			 * If you need to display your own error:
+			 *
+			 *		editor.showNotification(
+			 *			widget.getErrorMessage( '{url} cannot be embedded. Only rich type is supported.', wrongUrl )
+			 *		);
+			 *
+			 * Or with a message type:
+			 *
+			 *		editor.showNotification(
+			 *			widget.getErrorMessage( 'unsupportedUrl', wrongUrl )
+			 *		);
+			 *
+			 * @param {String} messageTypeOrMessage
+			 * @param {String} [url]
+			 * @param {String} [suffix]
+			 * @returns {String}
+			 */
+			getErrorMessage: function( messageTypeOrMessage, url, suffix ) {
+				var message = editor.lang.embedbase[ messageTypeOrMessage + ( suffix || '' ) ];
+				if ( !message ) {
+					message = messageTypeOrMessage;
+				}
+
+				return new CKEDITOR.template( message ).output( { url: url || '' } );
+			},
+
+			/**
+			 * Sends the request to the {@link #providerUrl provider} using
+			 * the {@link CKEDITOR.plugins.embedBase._jsonp JSONP} technique.
+			 *
+			 * @private
+			 * @param {CKEDITOR.plugins.embedBase.request} request
+			 */
+			_sendRequest: function( request ) {
+				var that = this,
+					jsonpRequest = Jsonp.sendRequest(
+						this.providerUrl,
+						{
+							url: encodeURIComponent( request.url )
+						},
+						request.callback,
+						function() {
+							request.errorCallback( 'fetchingFailed' );
+						}
+					);
+
+				request.cancel = function() {
+					jsonpRequest.cancel();
+					that.fire( 'requestCanceled', request );
+				};
+			},
+
+			/**
+			 * Handles the response of a successful request.
+			 *
+			 * Fires the {@link #handleResponse} event in order to convert the oEmbed response
+			 * to HTML that can be embedded.
+			 *
+			 * If the response can be handled, the {@link #_setContent content is set}.
+			 *
+			 * @private
+			 * @param {CKEDITOR.plugins.embedBase.request} request
+			 * @returns {Boolean} Whether the response can be handled. Returns `false` if {@link #handleResponse}
+			 * was canceled or the default listener could not convert oEmbed response into embeddable HTML.
+			 */
+			_handleResponse: function( request ) {
+				var evtData = {
+					url: request.url,
+					html: '',
+					response: request.response
+				};
+
+				if ( this.fire( 'handleResponse', evtData ) !== false ) {
+					if ( request.task ) {
+						request.task.done();
+					}
+
+					this._setContent( request.url, evtData.html );
+					return true;
+				} else {
+					request.errorCallback( evtData.errorMessage );
+					return false;
+				}
+			},
+
+			/**
+			 * Handles an error. An error can be caused either by a request failure or an unsupported
+			 * oEmbed response type.
+			 *
+			 * @private
+			 * @param {CKEDITOR.plugins.embedBase.request} request
+			 * @param {String} messageTypeOrMessage See {@link #getErrorMessage}.
+			 */
+			_handleError: function( request, messageTypeOrMessage ) {
+				if ( request.task ) {
+					request.task.cancel();
+
+					if ( !request.noNotifications ) {
+						editor.showNotification( this.getErrorMessage( messageTypeOrMessage, request.url ), 'warning' );
+					}
+				}
+			},
+
+			/**
+			 * Returns embeddable HTML for an oEmbed response if it is of the `photo`, `video` or `rich` type.
+			 *
+			 * @private
+			 * @param {Object} response The oEmbed response.
+			 * @returns {String/null} HTML string to be embedded or `null` if this response type is not supported.
+			 */
+			_responseToHtml: function( url, response ) {
+				if ( response.type == 'photo' ) {
+					return '<img src="' + CKEDITOR.tools.htmlEncodeAttr( response.url ) + '" ' +
+						'alt="' + CKEDITOR.tools.htmlEncodeAttr( response.title || '' ) + '" style="max-width:100%;height:auto" />';
+				} else if ( response.type == 'video' || response.type == 'rich' ) {
+					// Embedded iframes are added to page's focus list. Adding negative tabindex attribute
+					// removes their ability to be focused by user. (http://dev.ckeditor.com/ticket/14538)
+					response.html = response.html.replace( /<iframe/g, '<iframe tabindex="-1"' );
+
+					return response.html;
+				}
+
+				return null;
+			},
+
+			/**
+			 * The very final step of {@link #loadContent content loading}. The `url` data property is changed
+			 * and the content is embedded ({@link CKEDITOR.plugins.widget#element}'s HTML is set).
+			 *
+			 * @private
+			 * @param {String} url The resource URL.
+			 * @param {String} content HTML content to be embedded.
+			 */
+			_setContent: function( url, content ) {
+				this.setData( 'url', url );
+				this.element.setHtml( content );
+			},
+
+			/**
+			 * Creates a notification aggregator task.
+			 *
+			 * @private
+			 * @returns {CKEDITOR.plugins.notificationAggregator.task}
+			 */
+			_createTask: function() {
+				if ( !aggregator || aggregator.isFinished() ) {
+					aggregator = new CKEDITOR.plugins.notificationAggregator( editor, lang.fetchingMany, lang.fetchingOne );
+
+					aggregator.on( 'finished', function() {
+						aggregator.notification.hide();
+					} );
+				}
+
+				return aggregator.createTask();
+			},
+
+			/**
+			 * Caches the provider response.
+			 *
+			 * @private
+			 * @param {String} url
+			 * @param {Object} response
+			 */
+			_cacheResponse: function( url, response ) {
+				this._cache[ url ] = response;
+			},
+
+			/**
+			 * Returns the cached response.
+			 *
+			 * @private
+			 * @param {String} url
+			 * @returns {Object/undefined} Response or `undefined` if the cache was missed.
+			 */
+			_getCachedResponse: function( url ) {
+				return this._cache[ url ];
+			}
+		};
+
+		/**
+		 * Fired by the {@link #isUrlValid} method. Cancel the event to make the URL invalid.
+		 *
+		 * @event validateUrl
+		 * @param {String} data The URL being validated.
+		 */
+
+		/**
+		 * Fired by the {@link #loadContent} method to dispatch a request to the provider.
+		 * You can cancel this event and send the request using a different technique.
+		 * By default, if the event is not stopped or canceled a request will be sent
+		 * using the JSONP technique.
+		 *
+		 *		widget.on( 'sendRequest', function( evt ) {
+		 *			var request = evt.data;
+		 *
+		 *			// Send the request using a technique of your choice (XHR with CORS for instance).
+		 *			myApp.requestOembedProvider( request.url, function( err, response ) {
+		 *				if ( err ) {
+		 *					request.errorCallback( err );
+		 *				} else {
+		 *					request.callback( response );
+		 *				}
+		 *			} );
+		 *
+		 *			// Do not call other listeners, so the default behavior (JSONP request)
+		 *			// will not be executed.
+		 *			evt.stop();
+		 *		} );
+		 *
+		 * @event sendRequest
+		 * @param {CKEDITOR.plugins.embedBase.request} data
+		 */
+
+		/**
+		 * Fired after receiving a response from the {@link #providerUrl provider}.
+		 * This event listener job is to turn the oEmbed response to embeddable HTML by setting
+		 * `evt.data.html`.
+		 *
+		 *		widget.on( 'handleReaponse', function( evt ) {
+		 *			evt.data.html = customOembedToHtmlConverter( evt.data.response );
+		 *		} );
+		 *
+		 * This event can also be canceled to indicate that the response cannot be handled. In such
+		 * case the `evt.data.errorMessage` must be set (see {@link #getErrorMessage}).
+		 *
+		 *		widget.on( 'handleReaponse', function( evt ) {
+		 *			if ( evt.data.response.type == 'photo' ) {
+		 *				// Will display the editor.lang.embedbase.unsupportedUrl(Given) message.
+		 *				evt.data.errorMessage = 'unsupportedUrl';
+		 *				evt.cancel();
+		 *			}
+		 *		} );
+		 *
+		 * This event has a default late-listener (with a priority of `999`) that, if `evt.data.html` has not
+		 * been set yet, will try to handle the response by using the {@link #_responseToHtml} method.
+		 *
+		 * @event handleResponse
+		 * @param {Object} data
+		 * @param {String} data.url The resource URL.
+		 * @param {Object} data.response The oEmbed response.
+		 * @param {String} [data.html=''] The HTML which will be embedded.
+		 * @param {String} [data.errorMessage] The error message or message type (see {@link #getErrorMessage})
+		 * that must be set if this event is canceled to indicate an unsupported oEmbed response.
+		 */
+	}
+
+	/**
+	 * Class representing the request object. It is created by the {@link CKEDITOR.plugins.embedBase.baseDefinition#loadContent}
+	 * method and is passed to other methods and events of this class.
+	 *
+	 * @abstract
+	 * @class CKEDITOR.plugins.embedBase.request
+	 */
+
+	/**
+	 * The resource URL to be embedded (not the {@link CKEDITOR.plugins.embedBase.baseDefinition#providerUrl provider URL}).
+	 *
+	 * @property {String} url
+	 */
+
+	/**
+	 * Success callback to be executed once a response to a request is received.
+	 *
+	 * @property {Function} [callback]
+	 * @param {Object} response The response object.
+	 */
+
+	/**
+	 * Callback executed in case of an error.
+	 *
+	 * @property {Function} [errorCallback]
+	 * @param {String} messageTypeOrMessage See {@link CKEDITOR.plugins.embedBase.baseDefinition#getErrorMessage}.
+	 */
+
+	/**
+	 * Task that should be resolved once the request is done.
+	 *
+	 * @property {CKEDITOR.plugins.notificationAggregator.task} [task]
+	 */
+
+	/**
+	 * Response object. It is set once a response is received.
+	 *
+	 * @property {Object} [response]
+	 */
+
+	/**
+	 * Cancels the request.
+	 *
+	 * @method cancel
+	 */
+
+	CKEDITOR.plugins.embedBase = {
+		createWidgetBaseDefinition: createWidgetBaseDefinition,
+		_jsonp: Jsonp
+	};
+
+} )();
diff --git a/libraries/ckeditor/plugins/embedsemantic/icons/embedsemantic.png b/libraries/ckeditor/plugins/embedsemantic/icons/embedsemantic.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a9a73568eff8443f69985e68bc1f8039940b498
GIT binary patch
literal 389
zcmV;00eb$4P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00001b5ch_0Itp)
z=>Px$KS@MER5%f(Q#)>iFc8HOqRj=oh@Jw`(NaK@3vh*;Ag4&bN8kb}5CsiA1sxIs
z5ky4}0OAwRWM{(?uf%FyFmHZup0Ujov4S9Y)imuaAYa#2VT>tYVG#yPOW?0z7~aA#
z{8S;Rs_Hq*GEM~t?8&k$7<fX0X_|PR=YJy(Fqo!^5|Ln87Ho;*_*eIZ!1Fw|k3kCJ
z)Pn@`JYQNA#kOt4VoPYD_?p}R>iI{osX=&10m<1nga5Dsl1^j~DUeN*#eiJ;4`kCw
z2@v_dzruxzqKFkmfvKBgyf=+Vw*RUuOFW&MQ;;bDQrC6yevoYPlO$nCFpeV*xu-x(
z!@OY__%^DlLJL78===WLahz4W2`t=x(lljF)1X{k*HH=iR{|mJz3aLUvB#HfGhog+
jHnnZb>bl;ipZ9+N?)Ip<G5FTi00000NkvXXu0mjf#aE^X

literal 0
HcmV?d00001

diff --git a/libraries/ckeditor/plugins/embedsemantic/icons/hidpi/embedsemantic.png b/libraries/ckeditor/plugins/embedsemantic/icons/hidpi/embedsemantic.png
new file mode 100644
index 0000000000000000000000000000000000000000..97dc75475839dece3638850cd2d1628e1af4ed6b
GIT binary patch
literal 728
zcmV;}0w?{6P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px%l1W5CR9Fe^SIvqVK@c7_f;k1eB@F0EauCGaB_N2;5WM;fd5G*Qc=aK~gDiNC
zh&coW1rd*dL=eHhRCWAntDEV}=<Ws<(lAzc*H=|vRoBcosX&c(yB+TL`!BThk*;^=
z^I2*A(^M)IFqS0`%wd1oUz6%So6UaibUG^oq@O<)G-<V3VJ4FqlTjW@$hZK&C6VOo
z$MJZqbh}+c;uVZYad$eM^5gLsThAgZl}bLHPT!I9PaHr9Q083r$Prai?6CpnETe|5
zAY<r~SVDlZf6K;`$wZDN%GqQ0%H=Y%G_ly15b&{oY(UqZ5|w8CD}jE$A6?Ij$3~-J
zDiwzV0pNMfBrv1`dK1d$kZv3y;5&k9wQBJgjYig5XJ#opi%S!VHjNoG^N|4NDWppv
zwgPcMuk8U&ly6H6i@=Mlz>DjFtM3B0>v49F*Y*J0X%hdu2k1@cZ$f0nGU?eS#cAKV
z*`)%yEE@dOb2p9<(5yIU(zA65q9V;^(|VWmdOdUV&t@~r#7n?J-LTM^>IaXTs1VQw
z91oe?5Zjn=AOzOF=kxi)V~~(SKpWf|RNJvXH(Ra8+#;Y2lJ)>9Rj=2rGuOU2nAWpy
zFc_Fh2mxItu)9XGJxb02c<z#j@+SliheJSr%LRkXWFuy>SS&0=u~?KflX3M>%Kw4w
zcAJPX3|-0D`Yx`HtAo8%;3th-F88KZt666WpqA_mB_0lk<}8=XrPbYqLP7j6-qpjO
zRDeL=*6Ve!*=z#(JTos0uto+f^_=y-0W9!7oUksHO7C~O-B&Vr?E@#-U#(WgXBdVS
zJM6nYqyp3F^gA8F2l{v%(x=le7pT|B92L?MIAD0K=g|L`sK9S=!OemeK%%Pv0000<
KMNUMnLSTZg%~a6<

literal 0
HcmV?d00001

diff --git a/libraries/ckeditor/plugins/embedsemantic/plugin.js b/libraries/ckeditor/plugins/embedsemantic/plugin.js
new file mode 100644
index 00000000..58ceb081
--- /dev/null
+++ b/libraries/ckeditor/plugins/embedsemantic/plugin.js
@@ -0,0 +1,114 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+	'use strict';
+
+	CKEDITOR.plugins.add( 'embedsemantic', {
+		icons: 'embedsemantic', // %REMOVE_LINE_CORE%
+		hidpi: true, // %REMOVE_LINE_CORE%
+		requires: 'embedbase',
+
+		onLoad: function() {
+			this.registerOembedTag();
+		},
+
+		init: function( editor ) {
+			var widgetDefinition = CKEDITOR.plugins.embedBase.createWidgetBaseDefinition( editor ),
+				origInit = widgetDefinition.init;
+
+			CKEDITOR.tools.extend( widgetDefinition, {
+				// Use a dialog exposed by the embedbase plugin.
+				dialog: 'embedBase',
+				button: editor.lang.embedbase.button,
+				allowedContent: 'oembed',
+				requiredContent: 'oembed',
+				styleableElements: 'oembed',
+				// Share config with the embed plugin.
+				providerUrl: new CKEDITOR.template(
+					editor.config.embed_provider ||
+					'//ckeditor.iframe.ly/api/oembed?url={url}&callback={callback}'
+				),
+
+				init: function() {
+					var that = this;
+
+					origInit.call( this );
+
+					// Need to wait for #ready with the initial content loading, because on #init there's no data yet.
+					this.once( 'ready', function() {
+						// When widget is created using dialog, the dialog's code will handle loading the content
+						// (because it handles success and error), so do load the content only when loading data.
+						if ( this.data.loadOnReady ) {
+							this.loadContent( this.data.url, {
+								callback: function() {
+									// Do not load the content again on widget's next initialization (e.g. after undo or paste).
+									// Plus, this is a small trick that we change loadOnReady now, inside the callback.
+									// It guarantees that if the content was not loaded (an error occurred or someone
+									// undid/copied sth to fast) the content will be loaded on the next initialization.
+									that.setData( 'loadOnReady', false );
+									editor.fire( 'updateSnapshot' );
+								}
+							} );
+						}
+					} );
+				},
+
+				upcast: function( element, data ) {
+					if ( element.name != 'oembed' ) {
+						return;
+					}
+
+					var text = element.children[ 0 ],
+						div;
+
+					if ( text && text.type == CKEDITOR.NODE_TEXT && text.value ) {
+						data.url = text.value;
+						data.loadOnReady = true;
+						div = new CKEDITOR.htmlParser.element( 'div' );
+						element.replaceWith( div );
+
+						// Transfer widget classes from data to widget element (http://dev.ckeditor.com/ticket/13199).
+						div.attributes[ 'class' ] = element.attributes[ 'class' ];
+
+						return div;
+					}
+				},
+
+				downcast: function( element ) {
+					var ret = new CKEDITOR.htmlParser.element( 'oembed' );
+					ret.add( new CKEDITOR.htmlParser.text( this.data.url ) );
+
+					// Transfer widget classes from widget element back to data (http://dev.ckeditor.com/ticket/13199).
+					if ( element.attributes[ 'class' ] ) {
+						ret.attributes[ 'class' ] = element.attributes[ 'class' ];
+					}
+
+					return ret;
+				}
+			}, true );
+
+			editor.widgets.add( 'embedSemantic', widgetDefinition );
+		},
+
+		// Extends CKEDITOR.dtd so editor accepts <oembed> tag.
+		registerOembedTag: function() {
+			var dtd = CKEDITOR.dtd,
+				name;
+
+			// The oembed tag may contain text only.
+			dtd.oembed = { '#': 1 };
+
+			// Register oembed tag as allowed child, in each tag that can contain a div.
+			// It also registers the oembed tag in objects like $block, $blockLimit, etc.
+			for ( name in dtd ) {
+				if ( dtd[ name ].div ) {
+					dtd[ name ].oembed = 1;
+				}
+			}
+		}
+	} );
+
+} )();
diff --git a/libraries/ckeditor/plugins/notification/lang/az.js b/libraries/ckeditor/plugins/notification/lang/az.js
new file mode 100644
index 00000000..4f496874
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/az.js
@@ -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.plugins.setLang( 'notification', 'az', {
+	closed: 'Xəbərdarlıq pəncərəsi bağlanıb'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/ca.js b/libraries/ckeditor/plugins/notification/lang/ca.js
new file mode 100644
index 00000000..003b1585
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/ca.js
@@ -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.plugins.setLang( 'notification', 'ca', {
+	closed: 'Notificació tancada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/cs.js b/libraries/ckeditor/plugins/notification/lang/cs.js
new file mode 100644
index 00000000..7010669f
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/cs.js
@@ -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.plugins.setLang( 'notification', 'cs', {
+	closed: 'Oznámení zavřeno.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/da.js b/libraries/ckeditor/plugins/notification/lang/da.js
new file mode 100644
index 00000000..59edbc68
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/da.js
@@ -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.plugins.setLang( 'notification', 'da', {
+	closed: 'Notefikation lukket.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/de-ch.js b/libraries/ckeditor/plugins/notification/lang/de-ch.js
new file mode 100644
index 00000000..d12540ad
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/de-ch.js
@@ -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.plugins.setLang( 'notification', 'de-ch', {
+	closed: 'Benachrichtigung geschlossen.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/de.js b/libraries/ckeditor/plugins/notification/lang/de.js
new file mode 100644
index 00000000..806a8d2f
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/de.js
@@ -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.plugins.setLang( 'notification', 'de', {
+	closed: 'Benachrichtigung geschlossen.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/en.js b/libraries/ckeditor/plugins/notification/lang/en.js
new file mode 100644
index 00000000..23297f14
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/en.js
@@ -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.plugins.setLang( 'notification', 'en', {
+	closed: 'Notification closed.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/eo.js b/libraries/ckeditor/plugins/notification/lang/eo.js
new file mode 100644
index 00000000..f9f24dd2
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/eo.js
@@ -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.plugins.setLang( 'notification', 'eo', {
+	closed: 'Sciigo fermita'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/es-mx.js b/libraries/ckeditor/plugins/notification/lang/es-mx.js
new file mode 100644
index 00000000..e88ea36b
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/es-mx.js
@@ -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.plugins.setLang( 'notification', 'es-mx', {
+	closed: 'Notificación cerrada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/es.js b/libraries/ckeditor/plugins/notification/lang/es.js
new file mode 100644
index 00000000..d186eb8f
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/es.js
@@ -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.plugins.setLang( 'notification', 'es', {
+	closed: 'Notificación cerrada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/eu.js b/libraries/ckeditor/plugins/notification/lang/eu.js
new file mode 100644
index 00000000..d1f44dc2
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/eu.js
@@ -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.plugins.setLang( 'notification', 'eu', {
+	closed: 'Jakinarazpena itxita.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/fr.js b/libraries/ckeditor/plugins/notification/lang/fr.js
new file mode 100644
index 00000000..1f93a897
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/fr.js
@@ -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.plugins.setLang( 'notification', 'fr', {
+	closed: 'Notification fermée.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/gl.js b/libraries/ckeditor/plugins/notification/lang/gl.js
new file mode 100644
index 00000000..fa54787a
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/gl.js
@@ -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.plugins.setLang( 'notification', 'gl', {
+	closed: 'Notificación pechada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/hr.js b/libraries/ckeditor/plugins/notification/lang/hr.js
new file mode 100644
index 00000000..84d6789a
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/hr.js
@@ -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.plugins.setLang( 'notification', 'hr', {
+	closed: 'Obavijest zatvorena.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/hu.js b/libraries/ckeditor/plugins/notification/lang/hu.js
new file mode 100644
index 00000000..0db63f4b
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/hu.js
@@ -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.plugins.setLang( 'notification', 'hu', {
+	closed: 'Értesítés bezárva.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/id.js b/libraries/ckeditor/plugins/notification/lang/id.js
new file mode 100644
index 00000000..5e7ec7a7
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/id.js
@@ -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.plugins.setLang( 'notification', 'id', {
+	closed: 'Pemberitahuan ditutup'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/it.js b/libraries/ckeditor/plugins/notification/lang/it.js
new file mode 100644
index 00000000..35e0bfa6
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/it.js
@@ -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.plugins.setLang( 'notification', 'it', {
+	closed: 'Notifica chiusa.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/ja.js b/libraries/ckeditor/plugins/notification/lang/ja.js
new file mode 100644
index 00000000..9c917751
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/ja.js
@@ -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.plugins.setLang( 'notification', 'ja', {
+	closed: '通知を閉じました。'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/km.js b/libraries/ckeditor/plugins/notification/lang/km.js
new file mode 100644
index 00000000..cb3ba92b
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/km.js
@@ -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.plugins.setLang( 'notification', 'km', {
+	closed: 'បាន​បិទ​ការ​ផ្ដល់​ដំណឹង។'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/ko.js b/libraries/ckeditor/plugins/notification/lang/ko.js
new file mode 100644
index 00000000..78f06996
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/ko.js
@@ -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.plugins.setLang( 'notification', 'ko', {
+	closed: '알림이 닫힘.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/ku.js b/libraries/ckeditor/plugins/notification/lang/ku.js
new file mode 100644
index 00000000..9ca9e27f
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/ku.js
@@ -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.plugins.setLang( 'notification', 'ku', {
+	closed: 'ئاگادارکەرەوەکە داخرا.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/nb.js b/libraries/ckeditor/plugins/notification/lang/nb.js
new file mode 100644
index 00000000..0e941281
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/nb.js
@@ -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.plugins.setLang( 'notification', 'nb', {
+	closed: 'Varsling lukket.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/nl.js b/libraries/ckeditor/plugins/notification/lang/nl.js
new file mode 100644
index 00000000..d53e1147
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/nl.js
@@ -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.plugins.setLang( 'notification', 'nl', {
+	closed: 'Melding gesloten.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/oc.js b/libraries/ckeditor/plugins/notification/lang/oc.js
new file mode 100644
index 00000000..60da9ca7
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/oc.js
@@ -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.plugins.setLang( 'notification', 'oc', {
+	closed: 'Notificacion tampada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/pl.js b/libraries/ckeditor/plugins/notification/lang/pl.js
new file mode 100644
index 00000000..5adbe046
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/pl.js
@@ -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.plugins.setLang( 'notification', 'pl', {
+	closed: 'Powiadomienie zostało zamknięte.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/pt-br.js b/libraries/ckeditor/plugins/notification/lang/pt-br.js
new file mode 100644
index 00000000..b5a49805
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/pt-br.js
@@ -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.plugins.setLang( 'notification', 'pt-br', {
+	closed: 'Notificação fechada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/pt.js b/libraries/ckeditor/plugins/notification/lang/pt.js
new file mode 100644
index 00000000..6546eb4f
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/pt.js
@@ -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.plugins.setLang( 'notification', 'pt', {
+	closed: 'Notificação encerrada.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/ru.js b/libraries/ckeditor/plugins/notification/lang/ru.js
new file mode 100644
index 00000000..ee644a11
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/ru.js
@@ -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.plugins.setLang( 'notification', 'ru', {
+	closed: 'Уведомление закрыто'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/sk.js b/libraries/ckeditor/plugins/notification/lang/sk.js
new file mode 100644
index 00000000..56132ebc
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/sk.js
@@ -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.plugins.setLang( 'notification', 'sk', {
+	closed: 'Notifikácia zatvorená.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/sv.js b/libraries/ckeditor/plugins/notification/lang/sv.js
new file mode 100644
index 00000000..3ce23680
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/sv.js
@@ -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.plugins.setLang( 'notification', 'sv', {
+	closed: 'Notifiering stängd.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/tr.js b/libraries/ckeditor/plugins/notification/lang/tr.js
new file mode 100644
index 00000000..4cd2ed4f
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/tr.js
@@ -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.plugins.setLang( 'notification', 'tr', {
+	closed: 'Uyarılar kapatıldı.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/ug.js b/libraries/ckeditor/plugins/notification/lang/ug.js
new file mode 100644
index 00000000..07b8c600
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/ug.js
@@ -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.plugins.setLang( 'notification', 'ug', {
+	closed: 'ئوقتۇرۇش تاقالدى.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/uk.js b/libraries/ckeditor/plugins/notification/lang/uk.js
new file mode 100644
index 00000000..91b77248
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/uk.js
@@ -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.plugins.setLang( 'notification', 'uk', {
+	closed: 'Сповіщення закрито.'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/zh-cn.js b/libraries/ckeditor/plugins/notification/lang/zh-cn.js
new file mode 100644
index 00000000..697d153e
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/zh-cn.js
@@ -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.plugins.setLang( 'notification', 'zh-cn', {
+	closed: '通知已关闭'
+} );
diff --git a/libraries/ckeditor/plugins/notification/lang/zh.js b/libraries/ckeditor/plugins/notification/lang/zh.js
new file mode 100644
index 00000000..d3eb04e4
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/lang/zh.js
@@ -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.plugins.setLang( 'notification', 'zh', {
+	closed: '通知已關閉。'
+} );
diff --git a/libraries/ckeditor/plugins/notification/plugin.js b/libraries/ckeditor/plugins/notification/plugin.js
new file mode 100644
index 00000000..a61d940c
--- /dev/null
+++ b/libraries/ckeditor/plugins/notification/plugin.js
@@ -0,0 +1,923 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview The "Notification" plugin.
+ *
+ */
+
+'use strict';
+
+CKEDITOR.plugins.add( 'notification', {
+	lang: 'az,ca,cs,da,de,de-ch,en,eo,es,es-mx,eu,fr,gl,hr,hu,id,it,ja,km,ko,ku,nb,nl,oc,pl,pt,pt-br,ru,sk,sv,tr,ug,uk,zh,zh-cn', // %REMOVE_LINE_CORE%
+	requires: 'toolbar',
+
+	init: function( editor ) {
+		editor._.notificationArea = new Area( editor );
+
+		// Overwrites default `editor.showNotification`.
+		editor.showNotification = function( message, type, progressOrDuration ) {
+			var progress, duration;
+
+			if ( type == 'progress' ) {
+				progress = progressOrDuration;
+			} else {
+				duration = progressOrDuration;
+			}
+
+			var notification = new CKEDITOR.plugins.notification( editor, {
+				message: message,
+				type: type,
+				progress: progress,
+				duration: duration
+			} );
+
+			notification.show();
+
+			return notification;
+		};
+
+		// Close the last notification on ESC.
+		editor.on( 'key', function( evt ) {
+			if ( evt.data.keyCode == 27 ) { /* ESC */
+				var notifications = editor._.notificationArea.notifications;
+
+				if ( !notifications.length ) {
+					return;
+				}
+
+				// As long as this is not a common practice to inform screen-reader users about actions, in this case
+				// this is the best solution (unfortunately there is no standard for accessibility for notifications).
+				// Notification has an `alert` aria role what means that it does not get a focus nor is needed to be
+				// closed (unlike `alertdialog`). However notification will capture ESC key so we need to inform user
+				// why it does not do other actions.
+				say( editor.lang.notification.closed );
+
+				// Hide last.
+				notifications[ notifications.length - 1 ].hide();
+
+				evt.cancel();
+			}
+		} );
+
+		// Send the message to the screen readers.
+		function say( text ) {
+			var message = new CKEDITOR.dom.element( 'div' );
+			message.setStyles( {
+				position: 'fixed',
+				'margin-left': '-9999px'
+			} );
+			message.setAttributes( {
+				'aria-live': 'assertive',
+				'aria-atomic': 'true'
+			} );
+			message.setText( text );
+
+			CKEDITOR.document.getBody().append( message );
+
+			setTimeout( function() {
+				message.remove();
+			}, 100 );
+		}
+	}
+} );
+
+/**
+ * Notification class. Notifications are used to display short messages to the user. They might be used to show the result of
+ * asynchronous actions or information about changes in the editor content. It is recommended to use them instead of
+ * alert dialogs. They should **not** be used if a user response is required nor with dialog windows (e.g. in dialog validation).
+ *
+ * There are four types of notifications available, see the {@link #type} property.
+ *
+ * Note that the notification constructor only creates a notification instance. To show it, use the {@link #show} method:
+ *
+ *		var notification = new CKEDITOR.plugins.notification( editor, { message: 'Foo' } );
+ *		notification.show();
+ *
+ * You can also use the {@link CKEDITOR.editor#showNotification} method:
+ *
+ *		editor.showNotification( 'Foo' );
+ *
+ * All of the notification actions: ({@link #show}, {@link #update} and {@link #hide}) fire cancelable events
+ * on the related {@link CKEDITOR.editor} instance so you can integrate editor notifications with your website notifications.
+ *
+ * Refer to the [Notifications](http://docs.ckeditor.com/#!/guide/dev_notifications) article for more information about this feature.
+ *
+ * @since 4.5
+ * @class CKEDITOR.plugins.notification
+ * @constructor Create a notification object. Call {@link #show} to show the created notification.
+ * @param {CKEDITOR.editor} editor The editor instance.
+ * @param {Object} options
+ * @param {String} options.message The message displayed in the notification.
+ * @param {String} [options.type='info'] Notification type, see {@link #type}.
+ * @param {Number} [options.progress=0] If the type is `progress` this may be a progress from 0 to 1.
+ * @param {Number} [options.duration] How long the notification will be visible, see {@link #duration}.
+ */
+function Notification( editor, options ) {
+	CKEDITOR.tools.extend( this, options, {
+		editor: editor,
+		id: 'cke-' + CKEDITOR.tools.getUniqueId(),
+		area: editor._.notificationArea
+	} );
+
+	if ( !options.type ) {
+		this.type = 'info';
+	}
+
+	this.element = this._createElement();
+
+	// Don't allow dragging on notification (http://dev.ckeditor.com/ticket/13184).
+	editor.plugins.clipboard && CKEDITOR.plugins.clipboard.preventDefaultDropOnElement( this.element );
+}
+
+/**
+ * The editor instance.
+ *
+ * @readonly
+ * @property {CKEDITOR.editor} editor
+ */
+
+/**
+ * Message displayed in the notification.
+ *
+ * @readonly
+ * @property {String} message
+ */
+
+/**
+ * Notification type. There are four types available:
+ *
+ * * `info` (default) &ndash; Information for the user (e.g. "File is uploading.", "ACF modified content."),
+ * * `warning` &ndash; Warning or error message (e.g. "This type of file is not supported.",
+ * "You cannot paste the script."),
+ * * `success` &ndash; Information that an operation finished successfully (e.g. "File uploaded.", "Data imported.").
+ * * `progress` &ndash; Information about the progress of an operation. When the operation is done, the notification
+ * type should be changed to `success`.
+ *
+ * @readonly
+ * @property {String} type
+ */
+
+/**
+ * If the notification {@link #type} is `'progress'`, this is the progress from `0` to `1`.
+ *
+ * @readonly
+ * @property {Number} progress
+ */
+
+/**
+ * Notification duration. Determines after how many milliseconds the notification should close automatically.
+ * `0` means that the notification will not close automatically and that the user needs to close it manually.
+ * The default value for `warning` and `progress` notifications is `0`. For `info` and `success` the value can
+ * either be set through the {@link CKEDITOR.config#notification_duration} configuration option or equals `5000`
+ * if the configuration option is not set.
+ *
+ * @readonly
+ * @property {Number} duration
+ */
+
+/**
+ * Unique notification ID.
+ *
+ * @readonly
+ * @property {Number} id
+ */
+
+/**
+ * Notification DOM element. There is one element per notification. It is created when the notification is created,
+ * even if it is not shown. If the notification is hidden, the element is detached from the document but not deleted.
+ * It will be reused if the notification is shown again.
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.element} element
+ */
+
+/**
+ * {@link CKEDITOR.plugins.notification.area Notification area} reference.
+ *
+ * @readonly
+ * @property {CKEDITOR.plugins.notification.area} area
+ */
+
+Notification.prototype = {
+	/**
+	 * Adds the notification element to the notification area. The notification will be hidden automatically if
+	 * {@link #duration} is set.
+	 *
+	 * Fires the {@link CKEDITOR.editor#notificationShow} event.
+	 */
+	show: function() {
+		if ( this.editor.fire( 'notificationShow', { notification: this } ) === false ) {
+			return;
+		}
+
+		this.area.add( this );
+
+		this._hideAfterTimeout();
+	},
+
+	/**
+	 * Updates the notification object and element.
+	 *
+	 * Fires the {@link CKEDITOR.editor#notificationUpdate} event.
+	 *
+	 * @param {Object} options
+	 * @param {String} [options.message] {@link #message}
+	 * @param {String} [options.type] {@link #type}
+	 * @param {Number} [options.progress] {@link #progress}
+	 * @param {Number} [options.duration] {@link #duration}
+	 * @param {Boolean} [options.important=false] If the update is important, the notification will be shown
+	 * if it was hidden and read by screen readers.
+	 */
+	update: function( options ) {
+		var show = true;
+
+		if ( this.editor.fire( 'notificationUpdate', { notification: this, options: options } ) === false ) {
+			// The idea of cancelable event is to let user create his own way of displaying notification, so if
+			// `notificationUpdate` event will be canceled there will be no interaction with notification area, but on
+			// the other hand the logic should work anyway so object will be updated (including `element` property).
+			// Note: we can safely update the element's attributes below, because this element is created inside
+			// the constructor. If the notificatinShow event was canceled as well, the element is detached from DOM.
+			show = false;
+		}
+
+		var element = this.element,
+			messageElement = element.findOne( '.cke_notification_message' ),
+			progressElement = element.findOne( '.cke_notification_progress' ),
+			type = options.type;
+
+		element.removeAttribute( 'role' );
+
+		// Change type to progress if `options.progress` is set.
+		if ( options.progress && this.type != 'progress' ) {
+			type = 'progress';
+		}
+
+		if ( type ) {
+			element.removeClass( this._getClass() );
+			element.removeAttribute( 'aria-label' );
+
+			this.type = type;
+
+			element.addClass( this._getClass() );
+			element.setAttribute( 'aria-label', this.type );
+
+			if ( this.type == 'progress' && !progressElement ) {
+				progressElement = this._createProgressElement();
+				progressElement.insertBefore( messageElement );
+			} else if ( this.type != 'progress' && progressElement ) {
+				progressElement.remove();
+			}
+		}
+
+		if ( options.message !== undefined ) {
+			this.message = options.message;
+			messageElement.setHtml( this.message );
+		}
+
+		if ( options.progress !== undefined ) {
+			this.progress = options.progress;
+
+			if ( progressElement ) {
+				progressElement.setStyle( 'width', this._getPercentageProgress() );
+			}
+		}
+
+		if ( show && options.important ) {
+			element.setAttribute( 'role', 'alert' );
+
+			if ( !this.isVisible() ) {
+				this.area.add( this );
+			}
+		}
+
+		// Overwrite even if it is undefined.
+		this.duration = options.duration;
+
+		this._hideAfterTimeout();
+	},
+
+	/**
+	 * Removes the notification element from the notification area.
+	 *
+	 * Fires the {@link CKEDITOR.editor#notificationHide} event.
+	 */
+	hide: function() {
+		if ( this.editor.fire( 'notificationHide', { notification: this } ) === false ) {
+			return;
+		}
+
+		this.area.remove( this );
+	},
+
+	/**
+	 * Returns `true` if the notification is in the notification area.
+	 *
+	 * @returns {Boolean} `true` if the notification is in the notification area.
+	 */
+	isVisible: function() {
+		return CKEDITOR.tools.indexOf( this.area.notifications, this ) >= 0;
+	},
+
+	/**
+	 * Creates the notification DOM element.
+	 *
+	 * @private
+	 * @returns {CKEDITOR.dom.element} Notification DOM element.
+	 */
+	_createElement: function() {
+		var notification = this,
+			notificationElement, notificationMessageElement, notificationCloseElement,
+			close = this.editor.lang.common.close;
+
+		notificationElement = new CKEDITOR.dom.element( 'div' );
+		notificationElement.addClass( 'cke_notification' );
+		notificationElement.addClass( this._getClass() );
+		notificationElement.setAttributes( {
+			id: this.id,
+			role: 'alert',
+			'aria-label': this.type
+		} );
+
+		if ( this.type == 'progress' )
+			notificationElement.append( this._createProgressElement() );
+
+		notificationMessageElement = new CKEDITOR.dom.element( 'p' );
+		notificationMessageElement.addClass( 'cke_notification_message' );
+		notificationMessageElement.setHtml( this.message );
+		notificationElement.append( notificationMessageElement );
+
+		notificationCloseElement = CKEDITOR.dom.element.createFromHtml(
+			'<a class="cke_notification_close" href="javascript:void(0)" title="' + close + '" role="button" tabindex="-1">' +
+				'<span class="cke_label">X</span>' +
+			'</a>' );
+		notificationElement.append( notificationCloseElement );
+
+		notificationCloseElement.on( 'click', function() {
+			// Focus editor on close (http://dev.ckeditor.com/ticket/12865)
+			notification.editor.focus();
+
+			notification.hide();
+		} );
+
+		return notificationElement;
+	},
+
+	/**
+	 * Gets the notification CSS class.
+	 *
+	 * @private
+	 * @returns {String} Notification CSS class.
+	 */
+	_getClass: function() {
+		return ( this.type == 'progress' ) ?
+			'cke_notification_info' :
+			( 'cke_notification_' + this.type );
+	},
+
+	/**
+	 * Creates a progress element for the notification element.
+	 *
+	 * @private
+	 * @returns {CKEDITOR.dom.element} Progress element for the notification element.
+	 */
+	_createProgressElement: function() {
+		var element = new CKEDITOR.dom.element( 'span' );
+		element.addClass( 'cke_notification_progress' );
+		element.setStyle( 'width', this._getPercentageProgress() );
+		return element;
+	},
+
+	/**
+	 * Gets the progress as a percentage (ex. `0.3` -> `30%`).
+	 *
+	 * @private
+	 * @returns {String} Progress as a percentage.
+	 */
+	_getPercentageProgress: function() {
+		return Math.round( ( this.progress || 0 ) * 100 ) + '%';
+	},
+
+	/**
+	 * Hides the notification after a timeout.
+	 *
+	 * @private
+	 */
+	_hideAfterTimeout: function() {
+		var notification = this,
+			duration;
+
+		if ( this._hideTimeoutId ) {
+			clearTimeout( this._hideTimeoutId );
+		}
+
+		if ( typeof this.duration == 'number' ) {
+			duration = this.duration;
+		} else if ( this.type == 'info' || this.type == 'success' ) {
+			duration = ( typeof this.editor.config.notification_duration == 'number' ) ?
+				this.editor.config.notification_duration :
+				5000;
+		}
+
+		if ( duration ) {
+			notification._hideTimeoutId = setTimeout( function() {
+				notification.hide();
+			}, duration );
+		}
+	}
+};
+
+/**
+ * Notification area is an area where all notifications are put. The area is laid out dynamically.
+ * When the first notification is added, the area is shown and all listeners are added.
+ * When the last notification is removed, the area is hidden and all listeners are removed.
+ *
+ * @since 4.5
+ * @private
+ * @class CKEDITOR.plugins.notification.area
+ * @constructor
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
+function Area( editor ) {
+	var that = this;
+
+	this.editor = editor;
+	this.notifications = [];
+	this.element = this._createElement();
+	this._uiBuffer = CKEDITOR.tools.eventsBuffer( 10, this._layout, this );
+	this._changeBuffer = CKEDITOR.tools.eventsBuffer( 500, this._layout, this );
+
+	editor.on( 'destroy', function() {
+		that._removeListeners();
+		that.element.remove();
+	} );
+}
+
+/**
+ * The editor instance.
+ *
+ * @readonly
+ * @property {CKEDITOR.editor} editor
+ */
+
+/**
+ * The array of added notifications.
+ *
+ * @readonly
+ * @property {Array} notifications
+ */
+
+/**
+ * Notification area DOM element. This element is created when the area object is created. It will be attached to the document
+ * when the first notification is added and removed when the last notification is removed.
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.element} element
+ */
+
+/**
+ * Notification width. Cached for performance reasons.
+ *
+ * @private
+ * @property {CKEDITOR.dom.element} _notificationWidth
+ */
+
+/**
+ * Notification margin. Cached for performance reasons.
+ *
+ * @private
+ * @property {CKEDITOR.dom.element} _notificationMargin
+ */
+
+/**
+ * Event buffer object for UI events to optimize performance.
+ *
+ * @private
+ * @property {Object} _uiBuffer
+ */
+
+/**
+ * Event buffer object for editor change events to optimize performance.
+ *
+ * @private
+ * @property {Object} _changeBuffer
+ */
+
+Area.prototype = {
+	/**
+	 * Adds the notification to the notification area. If it is the first notification, the area will also be attached to
+	 * the document and listeners will be attached.
+	 *
+	 * Note that the proper way to show a notification is to call the {@link CKEDITOR.plugins.notification#show} method.
+	 *
+	 * @param {CKEDITOR.plugins.notification} notification Notification to add.
+	 */
+	add: function( notification ) {
+		this.notifications.push( notification );
+
+		this.element.append( notification.element );
+
+		if ( this.element.getChildCount() == 1 ) {
+			CKEDITOR.document.getBody().append( this.element );
+			this._attachListeners();
+		}
+
+		this._layout();
+	},
+
+	/**
+	 * Removes the notification from the notification area. If it is the last notification, the area will also be
+	 * detached from the document and listeners will be detached.
+	 *
+	 * Note that the proper way to hide a notification is to call the {@link CKEDITOR.plugins.notification#hide} method.
+	 *
+	 * @param {CKEDITOR.plugins.notification} notification Notification to remove.
+	 */
+	remove: function( notification ) {
+		var i = CKEDITOR.tools.indexOf( this.notifications, notification );
+
+		if ( i < 0 ) {
+			return;
+		}
+
+		this.notifications.splice( i, 1 );
+
+		notification.element.remove();
+
+		if ( !this.element.getChildCount() ) {
+			this._removeListeners();
+			this.element.remove();
+		}
+	},
+
+	/**
+	 * Creates the notification area element.
+	 *
+	 * @private
+	 * @returns {CKEDITOR.dom.element} Notification area element.
+	 */
+	_createElement: function() {
+		var editor = this.editor,
+			config = editor.config,
+			notificationArea = new CKEDITOR.dom.element( 'div' );
+
+		notificationArea.addClass( 'cke_notifications_area' );
+		notificationArea.setAttribute( 'id', 'cke_notifications_area_' + editor.name );
+		notificationArea.setStyle( 'z-index', config.baseFloatZIndex - 2 );
+
+		return notificationArea;
+	},
+
+	/**
+	 * Attaches listeners to the notification area.
+	 *
+	 * @private
+	 */
+	_attachListeners: function() {
+		var win = CKEDITOR.document.getWindow(),
+			editor = this.editor;
+
+		win.on( 'scroll', this._uiBuffer.input );
+		win.on( 'resize', this._uiBuffer.input );
+		editor.on( 'change', this._changeBuffer.input );
+		editor.on( 'floatingSpaceLayout', this._layout, this, null, 20 );
+		editor.on( 'blur', this._layout, this, null, 20 );
+	},
+
+	/**
+	 * Detaches listeners from the notification area.
+	 *
+	 * @private
+	 */
+	_removeListeners: function() {
+		var win = CKEDITOR.document.getWindow(),
+			editor = this.editor;
+
+		win.removeListener( 'scroll', this._uiBuffer.input );
+		win.removeListener( 'resize', this._uiBuffer.input );
+		editor.removeListener( 'change', this._changeBuffer.input );
+		editor.removeListener( 'floatingSpaceLayout', this._layout );
+		editor.removeListener( 'blur', this._layout );
+	},
+
+	/**
+	 * Sets the position of the notification area based on the editor content, toolbar as well as
+	 * viewport position and dimensions.
+	 *
+	 * @private
+	 */
+	_layout: function() {
+		var area = this.element,
+			editor = this.editor,
+			contentsRect = editor.ui.contentsElement.getClientRect(),
+			contentsPos = editor.ui.contentsElement.getDocumentPosition(),
+			top = editor.ui.space( 'top' ),
+			topRect = top.getClientRect(),
+			areaRect = area.getClientRect(),
+			notification,
+			notificationWidth = this._notificationWidth,
+			notificationMargin = this._notificationMargin,
+			win = CKEDITOR.document.getWindow(),
+			scrollPos = win.getScrollPosition(),
+			viewRect = win.getViewPaneSize(),
+			body = CKEDITOR.document.getBody(),
+			bodyPos = body.getDocumentPosition(),
+			cssLength = CKEDITOR.tools.cssLength;
+
+		// Cache for optimization
+		if ( !notificationWidth || !notificationMargin ) {
+			notification = this.element.getChild( 0 );
+			notificationWidth = this._notificationWidth = notification.getClientRect().width;
+			notificationMargin = this._notificationMargin =
+				parseInt( notification.getComputedStyle( 'margin-left' ), 10 ) +
+				parseInt( notification.getComputedStyle( 'margin-right' ), 10 );
+		}
+
+		// --------------------------------------- Horizontal layout ----------------------------------------
+
+		// +---Viewport-------------------------------+          +---Viewport-------------------------------+
+		// |                                          |          |                                          |
+		// | +---Toolbar----------------------------+ |          | +---Content----------------------------+ |
+		// | |                                      | |          | |                                      | |
+		// | +---Content----------------------------+ |          | |                                      | |
+		// | |                                      | |          | +---Toolbar----------------------+     | |
+		// | |      +------Notification------+      | |          | |                                |     | |
+		// | |                                      | |    OR    | +--------------------------------+     | |
+		// | |                                      | |          | |                                      | |
+		// | |                                      | |          | |      +------Notification------+      | |
+		// | |                                      | |          | |                                      | |
+		// | |                                      | |          | |                                      | |
+		// | +--------------------------------------+ |          | +--------------------------------------+ |
+		// +------------------------------------------+          +------------------------------------------+
+		if ( top.isVisible() &&
+			topRect.bottom > contentsRect.top &&
+			topRect.bottom < contentsRect.bottom - areaRect.height ) {
+			setBelowToolbar();
+
+		// +---Viewport-------------------------------+
+		// |                                          |
+		// | +---Content----------------------------+ |
+		// | |                                      | |
+		// | |      +------Notification------+      | |
+		// | |                                      | |
+		// | |                                      | |
+		// | |                                      | |
+		// | +--------------------------------------+ |
+		// |                                          |
+		// +------------------------------------------+
+		} else if ( contentsRect.top > 0 ) {
+			setTopStandard();
+
+		//   +---Content----------------------------+
+		//   |                                      |
+		// +---Viewport-------------------------------+
+		// | |                                      | |
+		// | |      +------Notification------+      | |
+		// | |                                      | |
+		// | |                                      | |
+		// | |                                      | |
+		// | +--------------------------------------+ |
+		// |                                          |
+		// +------------------------------------------+
+		} else if ( contentsPos.y + contentsRect.height - areaRect.height > scrollPos.y ) {
+			setTopFixed();
+
+		//   +---Content----------------------------+              +---Content----------------------------+
+		//   |                                      |              |                                      |
+		//   |                                      |              |                                      |
+		//   |                                      |              |      +------Notification------+      |
+		//   |                                      |              |                                      |
+		//   |                                      |      OR      +--------------------------------------+
+		// +---Viewport-------------------------------+
+		// | |      +------Notification------+      | |          +---Viewport-------------------------------+
+		// | |                                      | |          |                                          |
+		// | +--------------------------------------+ |          |                                          |
+		// |                                          |          |                                          |
+		// +------------------------------------------+          +------------------------------------------+
+		} else {
+			setBottom();
+		}
+
+		function setTopStandard() {
+			area.setStyles( {
+				position: 'absolute',
+				top: cssLength( contentsPos.y )
+			} );
+		}
+
+		function setBelowToolbar() {
+			area.setStyles( {
+				position: 'fixed',
+				top: cssLength( topRect.bottom )
+			} );
+		}
+
+		function setTopFixed() {
+			area.setStyles( {
+				position: 'fixed',
+				top: 0
+			} );
+		}
+
+		function setBottom() {
+			area.setStyles( {
+				position: 'absolute',
+				top: cssLength( contentsPos.y + contentsRect.height - areaRect.height )
+			} );
+		}
+
+		// ---------------------------------------- Vertical layout -----------------------------------------
+
+		var leftBase = area.getStyle( 'position' ) == 'fixed' ?
+			contentsRect.left :
+			body.getComputedStyle( 'position' ) != 'static' ? contentsPos.x - bodyPos.x : contentsPos.x;
+
+		// Content is narrower than notification
+		if ( contentsRect.width < notificationWidth + notificationMargin ) {
+
+			// +---Viewport-------------------------------+
+			// |                                          |
+			// |                 +---Content------------+ |
+			// |                 |                      | |
+			// |             +------Notification------+ | |
+			// |                 |                      | |
+			// |                 +----------------------+ |
+			// |                                          |
+			// +------------------------------------------+
+			if ( contentsPos.x + notificationWidth + notificationMargin > scrollPos.x + viewRect.width ) {
+				setRight();
+
+			// +---Viewport-------------------------------+               +---Viewport--------------------------+
+			// |                                          |               |                                     |
+			// |     +---Content------------+             |            +---Content------------+                 |
+			// |     |                      |             |            |  |                   |                 |
+			// |     | +------Notification------+         |    OR      | +------Notification------+             |
+			// |     |                      |             |            |  |                   |                 |
+			// |     +----------------------+             |            +----------------------+                 |
+			// |                                          |               |                                     |
+			// +------------------------------------------+               +-------------------------------------+
+			} else {
+				setLeft();
+			}
+
+		// Content is wider than notification.
+		} else {
+
+			//                       +--+Viewport+------------------------+
+			//                       |                                    |
+			//                       |             +---Content-----------------------------------------+
+			//                       |             |                      |                            |
+			//                       |             | +-----+Notification+-----+                        |
+			//                       |             |                      |                            |
+			//                       |             |                      |                            |
+			//                       |             |                      |                            |
+			//                       |             +---------------------------------------------------+
+			//                       |                                    |
+			//                       +------------------------------------+
+			if ( contentsPos.x + notificationWidth + notificationMargin > scrollPos.x + viewRect.width ) {
+				setLeft();
+
+			//                       +---Viewport-------------------------+
+			//                       |                                    |
+			//                       |  +---Content----------------------------------------------+
+			//                       |  |                                 |                      |
+			//                       |  |      +------Notification------+ |                      |
+			//                       |  |                                 |                      |
+			//                       |  |                                 |                      |
+			//                       |  +--------------------------------------------------------+
+			//                       |                                    |
+			//                       +------------------------------------+
+			} else if ( contentsPos.x + contentsRect.width / 2 +
+				notificationWidth / 2 + notificationMargin > scrollPos.x + viewRect.width ) {
+				setRightFixed();
+
+			//                       +---Viewport-------------------------+
+			//                       |                                    |
+			//   +---Content----------------------------+                 |
+			//   |                   |                  |                 |
+			//   |           +------Notification------+ |                 |
+			//   |                   |                  |                 |
+			//   |                   |                  |                 |
+			//   +--------------------------------------+                 |
+			//                       |                                    |
+			//                       +------------------------------------+
+			} else if ( contentsRect.left + contentsRect.width - notificationWidth - notificationMargin < 0 ) {
+				setRight();
+
+			//                       +---Viewport-------------------------+
+			//                       |                                    |
+			// +---Content---------------------------------------------+  |
+			// |                     |                                 |  |
+			// |                     | +------Notification------+      |  |
+			// |                     |                                 |  |
+			// |                     |                                 |  |
+			// +-------------------------------------------------------+  |
+			//                       |                                    |
+			//                       +------------------------------------+
+			} else if ( contentsRect.left + contentsRect.width / 2 - notificationWidth / 2 < 0 ) {
+				setLeftFixed();
+
+			//                       +---Viewport-------------------------+
+			//                       |                                    |
+			//                       | +---Content----------------------+ |
+			//                       | |                                | |
+			//                       | |    +-----Notification-----+    | |
+			//                       | |                                | |
+			//                       | |                                | |
+			//                       | +--------------------------------+ |
+			//                       |                                    |
+			//                       +------------------------------------+
+			} else {
+				setCenter();
+			}
+		}
+
+		function setLeft() {
+			area.setStyle( 'left', cssLength( leftBase ) );
+		}
+
+		function setLeftFixed() {
+			area.setStyle( 'left', cssLength( leftBase - contentsPos.x + scrollPos.x ) );
+		}
+
+		function setCenter() {
+			area.setStyle( 'left', cssLength( leftBase + contentsRect.width / 2 - notificationWidth / 2 - notificationMargin / 2 ) );
+		}
+
+		function setRight() {
+			area.setStyle( 'left', cssLength( leftBase + contentsRect.width - notificationWidth - notificationMargin ) );
+		}
+
+		function setRightFixed() {
+			area.setStyle( 'left', cssLength( leftBase - contentsPos.x + scrollPos.x + viewRect.width -
+				notificationWidth - notificationMargin ) );
+		}
+	}
+};
+
+CKEDITOR.plugins.notification = Notification;
+
+/**
+ * After how many milliseconds the notification of the `info` and `success`
+ * {@link CKEDITOR.plugins.notification#type type} should close automatically.
+ * `0` means that notifications will not close automatically.
+ * Note that `warning` and `progress` notifications will never close automatically.
+ *
+ * Refer to the [Notifications](http://docs.ckeditor.com/#!/guide/dev_notifications) article
+ * for more information about this feature.
+ *
+ * @since 4.5
+ * @cfg {Number} [notification_duration=5000]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Event fired when the {@link CKEDITOR.plugins.notification#show} method is called, before the
+ * notification is shown. If this event is canceled, the notification will not be shown.
+ *
+ * Using this event allows you to fully customize how a notification will be shown. It may be used to integrate
+ * the CKEditor notification system with your web page notifications.
+ *
+ * @since 4.5
+ * @event notificationShow
+ * @member CKEDITOR.editor
+ * @param data
+ * @param {CKEDITOR.plugins.notification} data.notification Notification which will be shown.
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
+
+/**
+ * Event fired when the {@link CKEDITOR.plugins.notification#update} method is called, before the
+ * notification is updated. If this event is canceled, the notification will not be shown even if the update was important,
+ * but the object will be updated anyway. Note that canceling this event does not prevent updating {@link #element}
+ * attributes, but if {@link #notificationShow} was canceled as well, this element is detached from the DOM.
+ *
+ * Using this event allows you to fully customize how a notification will be updated. It may be used to integrate
+ * the CKEditor notification system with your web page notifications.
+ *
+ * @since 4.5
+ * @event notificationUpdate
+ * @member CKEDITOR.editor
+ * @param data
+ * @param {CKEDITOR.plugins.notification} data.notification Notification which will be updated.
+ * Note that it contains the data that has not been updated yet.
+ * @param {Object} data.options Update options, see {@link CKEDITOR.plugins.notification#update}.
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
+
+/**
+ * Event fired when the {@link CKEDITOR.plugins.notification#hide} method is called, before the
+ * notification is hidden. If this event is canceled, the notification will not be hidden.
+ *
+ * Using this event allows you to fully customize how a notification will be hidden. It may be used to integrate
+ * the CKEditor notification system with your web page notifications.
+ *
+ * @since 4.5
+ * @event notificationHide
+ * @member CKEDITOR.editor
+ * @param data
+ * @param {CKEDITOR.plugins.notification} data.notification Notification which will be hidden.
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
diff --git a/libraries/ckeditor/plugins/notificationaggregator/plugin.js b/libraries/ckeditor/plugins/notificationaggregator/plugin.js
new file mode 100644
index 00000000..ad2ae4a9
--- /dev/null
+++ b/libraries/ckeditor/plugins/notificationaggregator/plugin.js
@@ -0,0 +1,548 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview The "Notification Aggregator" plugin.
+ *
+ */
+
+( function() {
+	'use strict';
+
+	CKEDITOR.plugins.add( 'notificationaggregator', {
+		requires: 'notification'
+	} );
+
+	/**
+	 * An aggregator of multiple tasks (progresses) which should be displayed using one
+	 * {@link CKEDITOR.plugins.notification notification}.
+	 *
+	 * Once all the tasks are done, it means that the whole process is finished and the {@link #finished}
+	 * event will be fired.
+	 *
+	 * New tasks can be created after the previous set of tasks is finished. This will continue the process and
+	 * fire the {@link #finished} event again when it is done.
+	 *
+	 * Simple usage example:
+	 *
+	 *		// Declare one aggregator that will be used for all tasks.
+	 *		var aggregator;
+	 *
+	 *		// ...
+	 *
+	 *		// Create a new aggregator if the previous one finished all tasks.
+	 *		if ( !aggregator || aggregator.isFinished() ) {
+	 *			// Create a new notification aggregator instance.
+	 *			aggregator = new CKEDITOR.plugins.notificationAggregator( editor, 'Loading process, step {current} of {max}...' );
+	 *
+	 *			// Change the notification type to 'success' on finish.
+	 *			aggregator.on( 'finished', function() {
+	 *				aggregator.notification.update( { message: 'Done', type: 'success' } );
+	 *			} );
+	 *		}
+	 *
+	 *		// Create 3 tasks.
+	 *		var taskA = aggregator.createTask(),
+	 *			taskB = aggregator.createTask(),
+	 *			taskC = aggregator.createTask();
+	 *
+	 *		// At this point the notification contains a message: "Loading process, step 0 of 3...".
+	 *
+	 *		// Let's close the first one immediately.
+	 *		taskA.done(); // "Loading process, step 1 of 3...".
+	 *
+	 *		// One second later the message will be: "Loading process, step 2 of 3...".
+	 *		setTimeout( function() {
+	 *			taskB.done();
+	 *		}, 1000 );
+	 *
+	 *		// Two seconds after the previous message the last task will be completed, meaning that
+	 *		// the notification will be closed.
+	 *		setTimeout( function() {
+	 *			taskC.done();
+	 *		}, 3000 );
+	 *
+	 * @since 4.5
+	 * @class CKEDITOR.plugins.notificationAggregator
+	 * @mixins CKEDITOR.event
+	 * @constructor Creates a notification aggregator instance.
+	 * @param {CKEDITOR.editor} editor
+	 * @param {String} message The template for the message to be displayed in the notification. The template can use
+	 * the following variables:
+	 *
+	 * * `{current}` &ndash; The number of completed tasks.
+	 * * `{max}` &ndash; The number of tasks.
+	 * * `{percentage}` &ndash; The progress (number 0-100).
+	 *
+	 * @param {String/null} [singularMessage=null] An optional template for the message to be displayed in the notification
+	 * when there is only one task remaining.  This template can use the same variables as the `message` template.
+	 * If `null`, then the `message` template will be used.
+	 */
+	function Aggregator( editor, message, singularMessage ) {
+		/**
+		 * @readonly
+		 * @property {CKEDITOR.editor} editor
+		 */
+		this.editor = editor;
+
+		/**
+		 * Notification created by the aggregator.
+		 *
+		 * The notification object is modified as aggregator tasks are being closed.
+		 *
+		 * @readonly
+		 * @property {CKEDITOR.plugins.notification/null}
+		 */
+		this.notification = null;
+
+		/**
+		 * A template for the notification message.
+		 *
+		 * The template can use the following variables:
+		 *
+		 * * `{current}` &ndash; The number of completed tasks.
+		 * * `{max}` &ndash; The number of tasks.
+		 * * `{percentage}` &ndash; The progress (number 0-100).
+		 *
+		 * @private
+		 * @property {CKEDITOR.template}
+		 */
+		this._message = new CKEDITOR.template( message );
+
+		/**
+		 * A template for the notification message used when only one task is loading.
+		 *
+		 * Sometimes there might be a need to specify a special message when there
+		 * is only one task loading, and to display standard messages in other cases.
+		 *
+		 * For example, you might want to show a message "Translating a widget" rather than
+		 * "Translating widgets (1 of 1)", but still you would want to have a message
+		 * "Translating widgets (2 of 3)" if more widgets are being translated at the same
+		 * time.
+		 *
+		 * Template variables are the same as in {@link #_message}.
+		 *
+		 * @private
+		 * @property {CKEDITOR.template/null}
+		 */
+		this._singularMessage = singularMessage ? new CKEDITOR.template( singularMessage ) : null;
+
+		// Set the _tasks, _totalWeights, _doneWeights, _doneTasks properties.
+		this._tasks = [];
+		this._totalWeights = 0;
+		this._doneWeights = 0;
+		this._doneTasks = 0;
+
+		/**
+		 * Array of tasks tracked by the aggregator.
+		 *
+		 * @private
+		 * @property {CKEDITOR.plugins.notificationAggregator.task[]} _tasks
+		 */
+
+		/**
+		 * Stores the sum of declared weights for all contained tasks.
+		 *
+		 * @private
+		 * @property {Number} _totalWeights
+		 */
+
+		/**
+		 * Stores the sum of done weights for all contained tasks.
+		 *
+		 * @private
+		 * @property {Number} _doneWeights
+		 */
+
+		/**
+		 * Stores the count of tasks done.
+		 *
+		 * @private
+		 * @property {Number} _doneTasks
+		 */
+	}
+
+	Aggregator.prototype = {
+		/**
+		 * Creates a new task that can be updated to indicate the progress.
+		 *
+		 * @param [options] Options object for the task creation.
+		 * @param [options.weight] For more information about weight, see the
+		 * {@link CKEDITOR.plugins.notificationAggregator.task} overview.
+		 * @returns {CKEDITOR.plugins.notificationAggregator.task} An object that represents the task state, and allows
+		 * for its manipulation.
+		 */
+		createTask: function( options ) {
+			options = options || {};
+
+			var initialTask = !this.notification,
+				task;
+
+			if ( initialTask ) {
+				// It's a first call.
+				this.notification = this._createNotification();
+			}
+
+			task = this._addTask( options );
+
+			task.on( 'updated', this._onTaskUpdate, this );
+			task.on( 'done', this._onTaskDone, this );
+			task.on( 'canceled', function() {
+				this._removeTask( task );
+			}, this );
+
+			// Update the aggregator.
+			this.update();
+
+			if ( initialTask ) {
+				this.notification.show();
+			}
+
+			return task;
+		},
+
+		/**
+		 * Triggers an update on the aggregator, meaning that its UI will be refreshed.
+		 *
+		 * When all the tasks are done, the {@link #finished} event is fired.
+		 */
+		update: function() {
+			this._updateNotification();
+
+			if ( this.isFinished() ) {
+				this.fire( 'finished' );
+			}
+		},
+
+		/**
+		 * Returns a number from `0` to `1` representing the done weights to total weights ratio
+		 * (showing how many of the tasks are done).
+		 *
+		 * Note: For an empty aggregator (without any tasks created) it will return `1`.
+		 *
+		 * @returns {Number} Returns the percentage of tasks done as a number ranging from `0` to `1`.
+		 */
+		getPercentage: function() {
+			// In case there are no weights at all we'll return 1.
+			if ( this.getTaskCount() === 0 ) {
+				return 1;
+			}
+
+			return this._doneWeights / this._totalWeights;
+		},
+
+		/**
+		 * @returns {Boolean} Returns `true` if all notification tasks are done
+		 * (or there are no tasks at all).
+		 */
+		isFinished: function() {
+			return this.getDoneTaskCount() === this.getTaskCount();
+		},
+
+		/**
+		 * @returns {Number} Returns a total tasks count.
+		 */
+		getTaskCount: function() {
+			return this._tasks.length;
+		},
+
+		/**
+		 * @returns {Number} Returns the number of tasks done.
+		 */
+		getDoneTaskCount: function() {
+			return this._doneTasks;
+		},
+
+		/**
+		 * Updates the notification content.
+		 *
+		 * @private
+		 */
+		_updateNotification: function() {
+			this.notification.update( {
+				message: this._getNotificationMessage(),
+				progress: this.getPercentage()
+			} );
+		},
+
+		/**
+		 * Returns a message used in the notification.
+		 *
+		 * @private
+		 * @returns {String}
+		 */
+		_getNotificationMessage: function() {
+			var tasksCount = this.getTaskCount(),
+				doneTasks = this.getDoneTaskCount(),
+				templateParams = {
+					current: doneTasks,
+					max: tasksCount,
+					percentage: Math.round( this.getPercentage() * 100 )
+				},
+				template;
+
+			// If there's only one remaining task and we have a singular message, we should use it.
+			if ( tasksCount == 1 && this._singularMessage ) {
+				template = this._singularMessage;
+			} else {
+				template = this._message;
+			}
+
+			return template.output( templateParams );
+		},
+
+		/**
+		 * Creates a notification object.
+		 *
+		 * @private
+		 * @returns {CKEDITOR.plugins.notification}
+		 */
+		_createNotification: function() {
+			return new CKEDITOR.plugins.notification( this.editor, {
+				type: 'progress'
+			} );
+		},
+
+		/**
+		 * Creates a {@link CKEDITOR.plugins.notificationAggregator.task} instance based
+		 * on `options`, and adds it to the task list.
+		 *
+		 * @private
+		 * @param options Options object coming from the {@link #createTask} method.
+		 * @returns {CKEDITOR.plugins.notificationAggregator.task}
+		 */
+		_addTask: function( options ) {
+			var task = new Task( options.weight );
+			this._tasks.push( task );
+			this._totalWeights += task._weight;
+			return task;
+		},
+
+		/**
+		 * Removes a given task from the {@link #_tasks} array and updates the UI.
+		 *
+		 * @private
+		 * @param {CKEDITOR.plugins.notificationAggregator.task} task Task to be removed.
+		 */
+		_removeTask: function( task ) {
+			var index = CKEDITOR.tools.indexOf( this._tasks, task );
+
+			if ( index !== -1 ) {
+				// If task was already updated with some weight, we need to remove
+				// this weight from our cache.
+				if ( task._doneWeight ) {
+					this._doneWeights -= task._doneWeight;
+				}
+
+				this._totalWeights -= task._weight;
+
+				this._tasks.splice( index, 1 );
+				// And we also should inform the UI about this change.
+				this.update();
+			}
+		},
+
+		/**
+		 * A listener called on the {@link CKEDITOR.plugins.notificationAggregator.task#update} event.
+		 *
+		 * @private
+		 * @param {CKEDITOR.eventInfo} evt Event object of the {@link CKEDITOR.plugins.notificationAggregator.task#update} event.
+		 */
+		_onTaskUpdate: function( evt ) {
+			this._doneWeights += evt.data;
+			this.update();
+		},
+
+		/**
+		 * A listener called on the {@link CKEDITOR.plugins.notificationAggregator.task#event-done} event.
+		 *
+		 * @private
+		 * @param {CKEDITOR.eventInfo} evt Event object of the {@link CKEDITOR.plugins.notificationAggregator.task#event-done} event.
+		 */
+		_onTaskDone: function() {
+			this._doneTasks += 1;
+			this.update();
+		}
+	};
+
+	CKEDITOR.event.implementOn( Aggregator.prototype );
+
+	/**
+	 * # Overview
+	 *
+	 * This type represents a single task in the aggregator, and exposes methods to manipulate its state.
+	 *
+	 * ## Weights
+	 *
+	 * Task progess is based on its **weight**.
+	 *
+	 * As you create a task, you need to declare its weight. As you want the update to inform about the
+	 * progress, you will need to {@link #update} the task, telling how much of this weight is done.
+	 *
+	 * For example, if you declare that your task has a weight that equals `50` and then call `update` with `10`,
+	 * you will end up with telling that the task is done in 20%.
+	 *
+	 * ### Example Usage of Weights
+	 *
+	 * Let us say that you use tasks for file uploading.
+	 *
+	 * A single task is associated with a single file upload. You can use the file size in bytes as a weight,
+	 * and then as the file upload progresses you just call the `update` method with the number of bytes actually
+	 * downloaded.
+	 *
+	 * @since 4.5
+	 * @class CKEDITOR.plugins.notificationAggregator.task
+	 * @mixins CKEDITOR.event
+	 * @constructor Creates a task instance for notification aggregator.
+	 * @param {Number} [weight=1]
+	 */
+	function Task( weight ) {
+		/**
+		 * Total weight of the task.
+		 *
+		 * @private
+		 * @property {Number}
+		 */
+		this._weight = weight || 1;
+
+		/**
+		 * Done weight of the task.
+		 *
+		 * @private
+		 * @property {Number}
+		 */
+		this._doneWeight = 0;
+
+		/**
+		 * Indicates when the task is canceled.
+		 *
+		 * @private
+		 * @property {Boolean}
+		 */
+		this._isCanceled = false;
+	}
+
+	Task.prototype = {
+		/**
+		 * Marks the task as done.
+		 */
+		done: function() {
+			this.update( this._weight );
+		},
+
+		/**
+		 * Updates the done weight of a task.
+		 *
+		 * @param {Number} weight Number indicating how much of the total task {@link #_weight} is done.
+		 */
+		update: function( weight ) {
+			// If task is already done or canceled there is no need to update it, and we don't expect
+			// progress to be reversed.
+			if ( this.isDone() || this.isCanceled() ) {
+				return;
+			}
+
+			// Note that newWeight can't be higher than _doneWeight.
+			var newWeight = Math.min( this._weight, weight ),
+				weightChange = newWeight - this._doneWeight;
+
+			this._doneWeight = newWeight;
+
+			// Fire updated event even if task is done in order to correctly trigger updating the
+			// notification's message. If we wouldn't do this, then the last weight change would be ignored.
+			this.fire( 'updated', weightChange );
+
+			if ( this.isDone() ) {
+				this.fire( 'done' );
+			}
+		},
+
+		/**
+		 * Cancels the task (the task will be removed from the aggregator).
+		 */
+		cancel: function() {
+			// If task is already done or canceled.
+			if ( this.isDone() || this.isCanceled() ) {
+				return;
+			}
+
+			// Mark task as canceled.
+			this._isCanceled = true;
+
+			// We'll fire cancel event it's up to aggregator to listen for this event,
+			// and remove the task.
+			this.fire( 'canceled' );
+		},
+
+		/**
+		 * Checks if the task is done.
+		 *
+		 * @returns {Boolean}
+		 */
+		isDone: function() {
+			return this._weight === this._doneWeight;
+		},
+
+		/**
+		 * Checks if the task is canceled.
+		 *
+		 * @returns {Boolean}
+		 */
+		isCanceled: function() {
+			return this._isCanceled;
+		}
+	};
+
+	CKEDITOR.event.implementOn( Task.prototype );
+
+	/**
+	 * Fired when all tasks are done. When this event occurs, the notification may change its type to `success` or be hidden:
+	 *
+	 *		aggregator.on( 'finished', function() {
+	 *			if ( aggregator.getTaskCount() == 0 ) {
+	 *				aggregator.notification.hide();
+	 *			} else {
+	 *				aggregator.notification.update( { message: 'Done', type: 'success' } );
+	 *			}
+	 *		} );
+	 *
+	 * @event finished
+	 * @member CKEDITOR.plugins.notificationAggregator
+	 */
+
+	/**
+	 * Fired upon each weight update of the task.
+	 *
+	 *		var myTask = new Task( 100 );
+	 *		myTask.update( 30 );
+	 *		// Fires updated event with evt.data = 30.
+	 *		myTask.update( 40 );
+	 *		// Fires updated event with evt.data = 10.
+	 *		myTask.update( 20 );
+	 *		// Fires updated event with evt.data = -20.
+	 *
+	 * @event updated
+	 * @param {Number} data The difference between the new weight and the previous one.
+	 * @member CKEDITOR.plugins.notificationAggregator.task
+	 */
+
+	/**
+	 * Fired when the task is done.
+	 *
+	 * @event done
+	 * @member CKEDITOR.plugins.notificationAggregator.task
+	 */
+
+	/**
+	 * Fired when the task is canceled.
+	 *
+	 * @event canceled
+	 * @member CKEDITOR.plugins.notificationAggregator.task
+	 */
+
+	// Expose Aggregator type.
+	CKEDITOR.plugins.notificationAggregator = Aggregator;
+	CKEDITOR.plugins.notificationAggregator.task = Task;
+} )();
diff --git a/varbase.info.yml b/varbase.info.yml
index c96e5d48..d1e7aeab 100644
--- a/varbase.info.yml
+++ b/varbase.info.yml
@@ -106,6 +106,7 @@ dependencies:
   - better_exposed_filters
   - link_attributes
   - login_destination
+  - ckeditor_media_embed
 
 themes:
   # Contrib themes.
-- 
GitLab