From d9c524fd9d2f155743bb59975513ec23ec219fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pauli=20=C3=98ster=C3=B8?= Date: Thu, 13 Oct 2016 16:35:30 -0200 Subject: [PATCH 001/135] Overload to CompositeC1WebPage.Function(...) to allow custom FunctionContextContainer Marking C1HtmlHelper.Function(...) that doesn't accept a FunctionContextContainer as obsolete, since they behave differently whether you pass one or not which isn't what would expect. --- Composite/AspNet/Razor/C1HtmlHelper.cs | 3 +++ Composite/AspNet/Razor/CompositeC1WebPage.cs | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Composite/AspNet/Razor/C1HtmlHelper.cs b/Composite/AspNet/Razor/C1HtmlHelper.cs index 9e3376a83b..eb10c4e012 100644 --- a/Composite/AspNet/Razor/C1HtmlHelper.cs +++ b/Composite/AspNet/Razor/C1HtmlHelper.cs @@ -407,6 +407,7 @@ public IHtmlString Markup(IEnumerable xNodes) /// /// Function name. /// + [Obsolete("Use Function method directly on the Razor page")] public IHtmlString Function(string name) { return Function(name, null); @@ -418,6 +419,7 @@ public IHtmlString Function(string name) /// Function name. /// The parameters. /// + [Obsolete("Use Function method directly on the Razor page")] public IHtmlString Function(string name, object parameters) { return Function(name, Functions.ObjectToDictionary(parameters)); @@ -429,6 +431,7 @@ public IHtmlString Function(string name, object parameters) /// Function name. /// The parameters. /// + [Obsolete("Use Function method directly on the Razor page")] public IHtmlString Function(string name, IDictionary parameters) { return Function(name, parameters, new FunctionContextContainer()); diff --git a/Composite/AspNet/Razor/CompositeC1WebPage.cs b/Composite/AspNet/Razor/CompositeC1WebPage.cs index e9d278be86..d33b696bf2 100644 --- a/Composite/AspNet/Razor/CompositeC1WebPage.cs +++ b/Composite/AspNet/Razor/CompositeC1WebPage.cs @@ -133,9 +133,20 @@ public IHtmlString Function(string name, object parameters) /// public IHtmlString Function(string name, IDictionary parameters) { - return Html.C1().Function(name, parameters, GetFunctionContext()); + return Function(name, parameters, GetFunctionContext()); } + /// + /// Executes a C1 Function. + /// + /// Function name. + /// The parameters. + /// The FunctionContextContainer used to execute the function. + /// + public IHtmlString Function(string name, IDictionary parameters, FunctionContextContainer functionContextContainer) + { + return Html.C1().Function(name, parameters, functionContextContainer); + } private FunctionContextContainer GetFunctionContext() { From 25337fd0f3e8329588099fa8edd4e93ed8d5af80 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Fri, 28 Oct 2016 15:57:51 +0300 Subject: [PATCH 002/135] Package installation / uninstallation tests 0. Commands (installCommercialPackage and uninstallLocalPackage) added 1. Installing and uninstalling a free package: Package Creator (Available Packages) 2. Installing and uninstalling a 30-day trial package: Extranet (Available Packages) 3. Uninstalling a package installed locally and installing it from the server (YouTube) --- .../e2e/commands/installCommercialPackage.js | 32 +++++++++++++++++++ .../e2e/commands/uninstallLocalPackage.js | 24 ++++++++++++++ .../packages/InstallUninstallExtranet.js | 21 ++++++++++++ .../InstallUninstallPackageCreator.js | 21 ++++++++++++ .../suite/packages/UninstallInstallYouTube.js | 21 ++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 Website/test/e2e/commands/installCommercialPackage.js create mode 100644 Website/test/e2e/commands/uninstallLocalPackage.js create mode 100644 Website/test/e2e/suite/packages/InstallUninstallExtranet.js create mode 100644 Website/test/e2e/suite/packages/InstallUninstallPackageCreator.js create mode 100644 Website/test/e2e/suite/packages/UninstallInstallYouTube.js diff --git a/Website/test/e2e/commands/installCommercialPackage.js b/Website/test/e2e/commands/installCommercialPackage.js new file mode 100644 index 0000000000..afaa1abb2a --- /dev/null +++ b/Website/test/e2e/commands/installCommercialPackage.js @@ -0,0 +1,32 @@ +var events = require('events'); + +function InstallPackage() { + events.EventEmitter.call(this); +} + +InstallPackage.prototype.command = function (category,packageName) { + this.client.api + .selectPerspective("System") + .openTreeNode("Available Packages") + .openTreeNode(category) + .selectTreeNodeAction(packageName, "Install") + .clickDialogButton("Next") + .clickLabel("I accept the license agreement") + .clickDialogButton("Next") + .clickDialogButton("Next") + .clickDialogButton("Next") + .clickDialogButton("Finish") + .pause(5000) + .refresh() + + this.client.api + .selectPerspective("System") + .openTreeNode("Packages","Installed Packages") + .openTreeNode("Installed Packages",category) + .assertTreeNodeHasChild(category,packageName) + .refresh() + + return this.client.api; +}; + +module.exports = InstallPackage; diff --git a/Website/test/e2e/commands/uninstallLocalPackage.js b/Website/test/e2e/commands/uninstallLocalPackage.js new file mode 100644 index 0000000000..8da3f535bb --- /dev/null +++ b/Website/test/e2e/commands/uninstallLocalPackage.js @@ -0,0 +1,24 @@ +var events = require('events'); + +function InstallPackage() { + events.EventEmitter.call(this); +} + +InstallPackage.prototype.command = function (packageName) { + this.client.api + .selectPerspective("System") + .openTreeNode("Packages","Installed Packages") + .openTreeNode("Installed Packages","Local Packages") + .assertTreeNodeHasChild("Local Packages",packageName) + .selectTreeNodeAction(packageName,"Package Info") + .clickLabel("Uninstall") + .clickDialogButton("Next") + .clickDialogButton("Next") + .clickDialogButton("Finish") + .pause(5000) + .refresh() + + return this.client.api; +}; + +module.exports = InstallPackage; diff --git a/Website/test/e2e/suite/packages/InstallUninstallExtranet.js b/Website/test/e2e/suite/packages/InstallUninstallExtranet.js new file mode 100644 index 0000000000..408361f4d0 --- /dev/null +++ b/Website/test/e2e/suite/packages/InstallUninstallExtranet.js @@ -0,0 +1,21 @@ +module.exports = { + '@tags': ['InstallPackage'], + beforeEach: function (browser) { + browser.url(browser.launchUrl + '/Composite/top.aspx'); + var content = browser.page.content(); + content + .prepare("Content"); + }, + 'Install Extranet': function (browser) { + + browser + .installCommercialPackage("Composite.Community", "Composite.Community.Extranet") + + browser + .uninstallPackage("Composite.Community", "Composite.Community.Extranet") + + }, + afterEach: function (browser, done) { + done(); + } +} \ No newline at end of file diff --git a/Website/test/e2e/suite/packages/InstallUninstallPackageCreator.js b/Website/test/e2e/suite/packages/InstallUninstallPackageCreator.js new file mode 100644 index 0000000000..41e5d7da0c --- /dev/null +++ b/Website/test/e2e/suite/packages/InstallUninstallPackageCreator.js @@ -0,0 +1,21 @@ +module.exports = { + '@tags': ['InstallPackage'], + beforeEach: function (browser) { + browser.url(browser.launchUrl + '/Composite/top.aspx'); + var content = browser.page.content(); + content + .prepare(); + }, + 'Install Package Creator': function (browser) { + + browser + .installPackage("Composite.Tools","Composite.Tools.PackageCreator") + + browser + .uninstallPackage("Composite.Tools","Composite.Tools.PackageCreator") + + }, + afterEach: function (browser, done) { + done(); + } +} diff --git a/Website/test/e2e/suite/packages/UninstallInstallYouTube.js b/Website/test/e2e/suite/packages/UninstallInstallYouTube.js new file mode 100644 index 0000000000..1420979035 --- /dev/null +++ b/Website/test/e2e/suite/packages/UninstallInstallYouTube.js @@ -0,0 +1,21 @@ +module.exports = { + '@tags': ['InstallPackage'], + beforeEach: function (browser) { + browser.url(browser.launchUrl + '/Composite/top.aspx'); + var content = browser.page.content(); + content + .prepare("Content"); + }, + 'Install Extranet': function (browser) { + + browser + .uninstallLocalPackage("Composite.Media.YouTube") + + browser + .installPackage("Composite.Media", "Composite.Media.YouTube") + + }, + afterEach: function (browser, done) { + done(); + } +} \ No newline at end of file From 8e27ee1971d33a4810bd73228cb7f98817775f14 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Tue, 1 Nov 2016 10:42:05 +0200 Subject: [PATCH 003/135] Local Package Installation / Unistallation 1. New command: installLocalPackage 2. New test: install and unistall a local package (Orckestra.Demo.Contacts) 3. A test package Orckestra.Demo.Contacts that installs a simple global data type. --- .../test/e2e/commands/installLocalPackage.js | 28 ++++++++++++++++++ .../packages/InstallUninstallLocalPackage.js | 20 +++++++++++++ .../packages/Orckestra.Demo.Contacts.zip | Bin 0 -> 1449 bytes 3 files changed, 48 insertions(+) create mode 100644 Website/test/e2e/commands/installLocalPackage.js create mode 100644 Website/test/e2e/suite/packages/InstallUninstallLocalPackage.js create mode 100644 Website/test/e2e/suite/packages/Orckestra.Demo.Contacts.zip diff --git a/Website/test/e2e/commands/installLocalPackage.js b/Website/test/e2e/commands/installLocalPackage.js new file mode 100644 index 0000000000..54ae497a88 --- /dev/null +++ b/Website/test/e2e/commands/installLocalPackage.js @@ -0,0 +1,28 @@ +var events = require('events'); + +function InstallPackage() { + events.EventEmitter.call(this); +} + +InstallPackage.prototype.command = function (packagePath, packageName) { + this.client.api + .selectPerspective("System") + .selectTreeNodeAction("Packages", "Install Local Package...") + .setFileFieldValue("Package file", packagePath + "\\" + packageName + '.zip') + .clickDialogButton("Next") + .clickDialogButton("Next") + .clickDialogButton("Finish") + .pause(5000) + .refresh() + + this.client.api + .selectPerspective("System") + .openTreeNode("Packages","Installed Packages") + .openTreeNode("Installed Packages","Local Packages") + .assertTreeNodeHasChild("Local Packages",packageName) + .refresh() + + return this.client.api; +}; + +module.exports = InstallPackage; diff --git a/Website/test/e2e/suite/packages/InstallUninstallLocalPackage.js b/Website/test/e2e/suite/packages/InstallUninstallLocalPackage.js new file mode 100644 index 0000000000..d6ced8cfcc --- /dev/null +++ b/Website/test/e2e/suite/packages/InstallUninstallLocalPackage.js @@ -0,0 +1,20 @@ +module.exports = { + '@tags': ['InstallPackage'], + beforeEach: function (browser) { + browser.url(browser.launchUrl + '/Composite/top.aspx'); + var content = browser.page.content(); + content + .prepare("Content"); + }, + 'install a local package': function (browser) { + + browser + .installLocalPackage(require('path').resolve(__dirname),"Orckestra.Demo.Contacts") + + browser + .uninstallLocalPackage("Orckestra.Demo.Contacts") + }, + afterEach: function (browser, done) { + done(); + } +} \ No newline at end of file diff --git a/Website/test/e2e/suite/packages/Orckestra.Demo.Contacts.zip b/Website/test/e2e/suite/packages/Orckestra.Demo.Contacts.zip new file mode 100644 index 0000000000000000000000000000000000000000..4822dcc4fb2b86cfbec88a43612d9fc809f9f59f GIT binary patch literal 1449 zcmV;a1y=e{O9KQH000080MvL~Nq=OcJ~0IV0L~Wx01E&B0BLS>bYX04E_iKh?O5Ma z+c*$@=4S4H(D-J`3w9F6iESWspeY^ZT3`z8JiDSdz$ zLahC?yW0Ie$>{j)L&4E^kcyRJ+S+mk>4I4;=XH70j>0vEyn zI0uQ$RG|(FHu9!g&kj4C`}_NVl*O!6OhX_*cZBK`SeRJ_2;G@2Jg~+?$Hp_>_mljtDm2VI+NfgiRb(jYZIj~^cDtVOyIc_|C54IBwvnAKiM zatBIF9E_nTgLkFSm}uppi7czxc0mwul_GTa828g6$pO0+|X%Fdu`)jH{FLQX*}#G9J*Z zlBV#WP$~HQxU+$E9>$=EWHameq^6HT7)^MYVU8%)80q;8kS@`JEr`^mKkh8gwf*aC zZQxpK&n2E%2DMy0V**QN(p)FO2C`1sAWkVoEmdz#ej~4?nc;?np!RX&Y8veH7>wtJ zUyO{+Lam=&zys9!_fRE%MeIk0tVDM;Fr7CO7WJqf&`g%!83nn}!Uqr_u?E_BSMRw~ z?sX0GTyw3ZX`_|K8?KMW8{;kXf{xyNt4e)D!*CGB1MCypiwx6~o^O~R`$30{%g?<;`Yt=3pl-YM0>#BTfkY<{%O;@#vsdpuXcA+)Ms-p%FOr|(%r{|cf#>8<3 z{G0)&myhXv#7f)8CbU`bC&zi$<|W|v&1hkJGcmt^J&f(g=@CLrMNgF~33G}tRNsZV zA*E^6x^>NdK}{c7&dff)RNPsWaYpLgw+86!j$qAy!`zT#22#)MT6bizhFZ?xf<77j zXZ|hdrZV;mp+V+`7&{8(`u0SToPCMCtl>tU&~BPVsXrVJhJJ*5W`By%lE&FuS$EF;iaDcBgXfhX_U|Vw@2c4rqAf{gjZe=YUfhfF5XYg9 zX%rjcWtpF*S=WcSJBTsu4hJ~dB;MM7^t;gSM%(7S5CIp#_dkM|=;>&G82uYIA__S+ zDVg?Hjc@mT#plAhzyBW@Y`cb*+BO9~yM+f`o9oegMkk}N56--84av%%xIyG3Q^Og>v?y;qsNl+0Y)UUl{oI?M0?rz9QtIl)F}N!<6d zG|v4n3!!hu;!k#}&GvY^S27X4( zKQ7SA!z7NPVcgv!vG)aL{23DKze?<-B<5O%PAQcdlzP?K|EV*F+jd#dI#|8tvY`4d zdT;Nz^LWMPZZ=Ji)^9nt-cYVygVu(VA5cpH0u%rg000080MvL~Nq=OcJ~0IV0L~Wx z01E&B0000000000000000001KZgX^DY-}!gZER3W1qJ{B000310RTAw003GA00000 DgnYG? literal 0 HcmV?d00001 From c4fd856da63295d32075b994f74400d009442632 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Tue, 1 Nov 2016 15:48:49 +0200 Subject: [PATCH 004/135] Website Language Installation/Unistallation 1. Commands to install and unistall website languages: installLocale, uninstallLocale 2. Test: InstallUninstallWebsiteLanguage (that uses these commands) --- Website/test/e2e/commands/installLocale.js | 24 +++++++++++++++++++ Website/test/e2e/commands/uninstallLocale.js | 21 ++++++++++++++++ .../InstallUninstallWebsiteLanguage.js | 20 ++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 Website/test/e2e/commands/installLocale.js create mode 100644 Website/test/e2e/commands/uninstallLocale.js create mode 100644 Website/test/e2e/suite/locales/InstallUninstallWebsiteLanguage.js diff --git a/Website/test/e2e/commands/installLocale.js b/Website/test/e2e/commands/installLocale.js new file mode 100644 index 0000000000..610f9b7cc3 --- /dev/null +++ b/Website/test/e2e/commands/installLocale.js @@ -0,0 +1,24 @@ +var events = require('events'); + +function InstallLocale() { + events.EventEmitter.call(this); +} + +InstallLocale.prototype.command = function (language, code) { + + this.client.api + .selectPerspective("System") + .selectTreeNodeAction("Languages", "Add Language") + .clickDataBySibilings("Languages") + .clickLabel(language) + .assertFieldValue(null, "URL mapping name", code) + .clickDialogButton("OK") + + .openTreeNode("Languages") + .assertTreeNodeHasChild("Languages", language) + .refresh() + + return this.client.api; +}; + +module.exports = InstallLocale; diff --git a/Website/test/e2e/commands/uninstallLocale.js b/Website/test/e2e/commands/uninstallLocale.js new file mode 100644 index 0000000000..286bd8a00b --- /dev/null +++ b/Website/test/e2e/commands/uninstallLocale.js @@ -0,0 +1,21 @@ +var events = require('events'); + +function InstallLocale() { + events.EventEmitter.call(this); +} + +InstallLocale.prototype.command = function (language) { + + this.client.api + .selectPerspective("System") + .openTreeNode("Languages") + .selectTreeNodeAction(language, "Remove Language") + .clickDialogButton("OK") + + .openTreeNode("Languages") + .assertTreeNodeHasNoChild("Languages", language) + + return this.client.api; +}; + +module.exports = InstallLocale; diff --git a/Website/test/e2e/suite/locales/InstallUninstallWebsiteLanguage.js b/Website/test/e2e/suite/locales/InstallUninstallWebsiteLanguage.js new file mode 100644 index 0000000000..3710ad39ce --- /dev/null +++ b/Website/test/e2e/suite/locales/InstallUninstallWebsiteLanguage.js @@ -0,0 +1,20 @@ +module.exports = { + '@tags': ['InstallLocale'], + beforeEach: function (browser) { + browser.url(browser.launchUrl + '/Composite/top.aspx'); + var content = browser.page.content(); + content + .prepare("Content"); + }, + 'Install and uninstall a website language': function (browser) { + + browser + .installLocale("French, Canada", "fr") + + browser + .uninstallLocale("French, Canada") + }, + afterEach: function (browser, done) { + done(); + } +} \ No newline at end of file From 226424e52044405df802e70bfe599ada9bd2d108 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Tue, 1 Nov 2016 16:57:57 +0200 Subject: [PATCH 005/135] Website Installation (Other Language) - WIP 1. Command: installWebsite (extracted from installSite.js) 2. Test: InstallSiteWithOtherLanguage.js - WIP --- Website/test/e2e/commands/installWebsite.js | 143 ++++++++++++++++++ .../locales/InstallSiteWithOtherLanguage.js | 24 +++ 2 files changed, 167 insertions(+) create mode 100644 Website/test/e2e/commands/installWebsite.js create mode 100644 Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js diff --git a/Website/test/e2e/commands/installWebsite.js b/Website/test/e2e/commands/installWebsite.js new file mode 100644 index 0000000000..1cb5781ad7 --- /dev/null +++ b/Website/test/e2e/commands/installWebsite.js @@ -0,0 +1,143 @@ +var events = require('events'); + +function InstallWebsite() { + events.EventEmitter.call(this); +} + +InstallWebsite.prototype.command = function (expectedLanguage, newLanguage, newLanguageCode) { + var browser = this.client.api; + + browser + // The “Welcome” page of the setup wizard appears. + .waitForElementVisible('#intro', browser.globals.timeouts.little) + // All the requirements are met (checked). + .waitForElementVisible('#introtestsuccess', browser.globals.timeouts.basic) + // The “Next” button is available and enabled + .waitForElementVisible('#introtestsuccessbutton', browser.globals.timeouts.little) + // 2 Click “Next”. The “License” page of the setup wizard appears. + .click('#introtestsuccessbutton') + + // The “Accept” check box is present and unchecked + .waitForElementVisible('#licenseaccept', browser.globals.timeouts.little); + browser.expect.element('#licenseaccept').to.not.have.attribute('checked'); + // The “Next” button is available but disabled + browser.expect.element('#setupbutton').to.have.attribute('isdisabled'); + // 3 Check the “Accept” check box. The check mark appears in the “Accept” check box. + browser.click('#licenseaccept'); + // The “Next” button gets enabled. + browser.expect.element('#setupbutton').to.not.have.attribute('isdisabled'); + // 4 Click “Next”. The “Setup” page of the setup wizard appears. + + browser + .click('#setupbutton') + // The “Starter Site” radio button is present and selected + .waitForElementVisible('#setup', browser.globals.timeouts.little); + browser.expect.element('#setup h1').text.to.contain('Setup'); + // The “Venus” radio button is present and selected. + browser.expect + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > radiobutton') + .to.have.attribute('ischecked', 'true'); + browser.expect + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') + .text.to.equal('Starter sites'); + browser.expect + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(1) > radiobutton') + .to.have.attribute('ischecked', 'true'); + browser.expect + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') + .text.to.equal('Venus'); + // The “Next” button is available and enabled + browser.expect.element('#navsetup clickbutton[label="Next"]').to.not.have.attribute('isdisabled'); + // 5 Click “Next”. The “Language” page of the setup wizard appears. + browser + .click('#navsetup clickbutton[label="Next"]') + + .waitForElementVisible('#language', browser.globals.timeouts.little); + // A language is selected. (It must be based on the user’s locale.) + browser.expect.element('#websitelanguage').value.to.equal(expectedLanguage); + + // {{ + + // change the language + if(newLanguage) + { + browser.setValue('#websitelanguage', newLanguage); + } + if(newLanguageCode) + { + browser.expect.element('#websitelanguage').value.to.equal(newLanguageCode); + } + + // }} + + // The “Next” button is available and enabled + browser.expect.element('#navlanguage clickbutton[label="Next"]').to.not.have.attribute('isdisabled'); + // 6 Click “Next”. The “Create Login” page of the setup wizard appears. + browser + .click('#navlanguage clickbutton[label="Next"]') + .waitForElementVisible('#login', browser.globals.timeouts.little); + // The “Start CMS” button is available but disabled. + browser.expect + .element('#navlogin clickbutton[label="Start CMS"]') + .to.have.attribute('isdisabled'); + // The “Username” field is filled with the value ‘admin’. + browser.expect.element('#username').value.to.equal('admin'); + + // The “Regional settings” field is set to the same language as in Step 5. + // {{ + if(newLanguageCode) + { + browser.expect.element('#consolelanguage').value.to.equal(newLanguageCode); + } + // }} + + // 7 Fill the “Email” field. Value: “john.doe@contoso.com” + browser.click('#email'); + browser.setValue('#email', 'john.doe@contoso.com'); + // The field is filled with the value. + browser.expect.element('#email').value.to.equal('john.doe@contoso.com') + // The “Start CMS” button is still disabled. + browser.expect + .element('#navlogin clickbutton[label="Start CMS"]') + .to.have.attribute('isdisabled'); + // 8 Fill the “Password” field. Value: “123456” + browser.click('#password'); + browser.setValue('#password', '123456') + // The field is filled with the value. + browser.expect.element('#password') + .value.to.equal('123456'); + // The value is masked. + browser.expect.element('#password') + .to.have.attribute('type', 'password') + // The “Start CMS” button is still disabled. + browser.expect + .element('#navlogin clickbutton[label="Start CMS"]') + .to.have.attribute('isdisabled'); + // 9 Fill the “Repeat Password” field. Value: “123456” + browser.click('#passcheck'); + browser.setValue('#passcheck', '123456') + // The field is filled with the value. + browser.expect.element('#passcheck') + .value.to.equal('123456'); + // The value is masked. + browser.expect.element('#passcheck') + .to.have.attribute('type', 'password') + // The “Start CMS” button gets enabled. + browser.expect + .element('#navlogin clickbutton[label="Start CMS"]') + .to.not.have.attribute('isdisabled'); + // 10 Click “Start CMS”. + browser.click('#navlogin clickbutton[label="Start CMS"]'); + // The screen with “You starting site being downloaded + // and installed…” appears showing the installation progress and + // other screens succeed each other. + browser + .waitForElementVisible('#loading', browser.globals.timeouts.little) + // Eventually, the user logs in successfully and the CMS Console appears. + .waitForElementNotPresent('#loading', browser.globals.timeouts.save) + .waitForElementVisible('body', browser.globals.timeouts.basic) + .page.appWindow() + .waitForFrameLoad('@appFrame', browser.globals.timeouts.basic); +}; + +module.exports = InstallWebsite; \ No newline at end of file diff --git a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js new file mode 100644 index 0000000000..4264a6705d --- /dev/null +++ b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js @@ -0,0 +1,24 @@ +var resetSite = require('../../reset.js'); + +module.exports = { + '@tags': ['install'], + before: function (browser, done) { + resetSite(function (err) { + if (err) { + browser.end(); + console.error(err); + process.exit(1); + } + done(); + }); + }, + beforeEach: function (browser) { + // 1 Launch an uninitialized website. + browser + .url(browser.launchUrl + '/Composite/top.aspx') + .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); + }, + 'install Venus starter site': function (browser) { + browser.installWebsite('en-US', 'French (CA)', 'fr-CA') + } +} From 79691b184e6035a4c979f5370481ebf762e662a2 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Wed, 2 Nov 2016 11:13:14 +0200 Subject: [PATCH 006/135] Website Installation (Other Language) 1. Test: 000_setup/installSite.js updated: uses installWebsite.js command now 2. Test: locales/InstallSiteWithOtherLanguage.js finalized: uses French (CA) and asserts the GUI and the locale are changed accordingly; rolls back the website back to English (US)English --- .../test/e2e/suite/000_setup/installSite.js | 107 +----------------- .../locales/InstallSiteWithOtherLanguage.js | 31 ++++- 2 files changed, 26 insertions(+), 112 deletions(-) diff --git a/Website/test/e2e/suite/000_setup/installSite.js b/Website/test/e2e/suite/000_setup/installSite.js index 4655cf19ff..6a15a64b07 100644 --- a/Website/test/e2e/suite/000_setup/installSite.js +++ b/Website/test/e2e/suite/000_setup/installSite.js @@ -21,111 +21,6 @@ module.exports = { .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); }, 'install Venus starter site': function (browser) { - browser - // The “Welcome” page of the setup wizard appears. - .waitForElementVisible('#intro', browser.globals.timeouts.little) - // All the requirements are met (checked). - .waitForElementVisible('#introtestsuccess', browser.globals.timeouts.basic) - // The “Next” button is available and enabled - .waitForElementVisible('#introtestsuccessbutton', browser.globals.timeouts.little) - // 2 Click “Next”. The “License” page of the setup wizard appears. - .click('#introtestsuccessbutton') - // The “Accept” check box is present and unchecked - .waitForElementVisible('#licenseaccept', browser.globals.timeouts.little); - browser.expect.element('#licenseaccept').to.not.have.attribute('checked'); - // The “Next” button is available but disabled - browser.expect.element('#setupbutton').to.have.attribute('isdisabled'); - // 3 Check the “Accept” check box. The check mark appears in the “Accept” check box. - browser.click('#licenseaccept'); - // The “Next” button gets enabled. - browser.expect.element('#setupbutton').to.not.have.attribute('isdisabled'); - // 4 Click “Next”. The “Setup” page of the setup wizard appears. - browser - .click('#setupbutton') - // The “Starter Site” radio button is present and selected - .waitForElementVisible('#setup', browser.globals.timeouts.little); - browser.expect.element('#setup h1').text.to.contain('Setup'); - // The “Venus” radio button is present and selected. - browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > radiobutton') - .to.have.attribute('ischecked', 'true'); - browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') - .text.to.equal('Starter sites'); - browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(1) > radiobutton') - .to.have.attribute('ischecked', 'true'); - browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') - .text.to.equal('Venus'); - // The “Next” button is available and enabled - browser.expect.element('#navsetup clickbutton[label="Next"]').to.not.have.attribute('isdisabled'); - // 5 Click “Next”. The “Language” page of the setup wizard appears. - browser - .click('#navsetup clickbutton[label="Next"]') - .waitForElementVisible('#language', browser.globals.timeouts.little); - // A language is selected. (It must be based on the user’s locale.) - browser.expect.element('#websitelanguage').value.to.equal(expectedLanguage); - // The “Next” button is available and enabled - browser.expect.element('#navlanguage clickbutton[label="Next"]').to.not.have.attribute('isdisabled'); - // 6 Click “Next”. The “Create Login” page of the setup wizard appears. - browser - .click('#navlanguage clickbutton[label="Next"]') - .waitForElementVisible('#login', browser.globals.timeouts.little); - // The “Start CMS” button is available but disabled. - browser.expect - .element('#navlogin clickbutton[label="Start CMS"]') - .to.have.attribute('isdisabled'); - // The “Username” field is filled with the value ‘admin’. - browser.expect.element('#username').value.to.equal('admin'); - // The “Regional settings” field is set to the same language as in Step 5. - browser.expect.element('#consolelanguage').value.to.equal(expectedLanguage); - // 7 Fill the “Email” field. Value: “john.doe@contoso.com” - browser.click('#email'); - browser.setValue('#email', 'john.doe@contoso.com'); - // The field is filled with the value. - browser.expect.element('#email').value.to.equal('john.doe@contoso.com') - // The “Start CMS” button is still disabled. - browser.expect - .element('#navlogin clickbutton[label="Start CMS"]') - .to.have.attribute('isdisabled'); - // 8 Fill the “Password” field. Value: “123456” - browser.click('#password'); - browser.setValue('#password', '123456') - // The field is filled with the value. - browser.expect.element('#password') - .value.to.equal('123456'); - // The value is masked. - browser.expect.element('#password') - .to.have.attribute('type', 'password') - // The “Start CMS” button is still disabled. - browser.expect - .element('#navlogin clickbutton[label="Start CMS"]') - .to.have.attribute('isdisabled'); - // 9 Fill the “Repeat Password” field. Value: “123456” - browser.click('#passcheck'); - browser.setValue('#passcheck', '123456') - // The field is filled with the value. - browser.expect.element('#passcheck') - .value.to.equal('123456'); - // The value is masked. - browser.expect.element('#passcheck') - .to.have.attribute('type', 'password') - // The “Start CMS” button gets enabled. - browser.expect - .element('#navlogin clickbutton[label="Start CMS"]') - .to.not.have.attribute('isdisabled'); - // 10 Click “Start CMS”. - browser.click('#navlogin clickbutton[label="Start CMS"]'); - // The screen with “You starting site being downloaded - // and installed
” appears showing the installation progress and - // other screens succeed each other. - browser - .waitForElementVisible('#loading', browser.globals.timeouts.little) - // Eventually, the user logs in successfully and the CMS Console appears. - .waitForElementNotPresent('#loading', browser.globals.timeouts.save) - .waitForElementVisible('body', browser.globals.timeouts.basic) - .page.appWindow() - .waitForFrameLoad('@appFrame', browser.globals.timeouts.basic); + browser.installWebsite(expectedLanguage) } } diff --git a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js index 4264a6705d..11e82611c4 100644 --- a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js +++ b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js @@ -2,23 +2,42 @@ var resetSite = require('../../reset.js'); module.exports = { '@tags': ['install'], - before: function (browser, done) { + beforeEach: function (browser) { + // 0 Reset the website resetSite(function (err) { if (err) { browser.end(); console.error(err); process.exit(1); } - done(); }); - }, - beforeEach: function (browser) { // 1 Launch an uninitialized website. browser .url(browser.launchUrl + '/Composite/top.aspx') .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); }, - 'install Venus starter site': function (browser) { - browser.installWebsite('en-US', 'French (CA)', 'fr-CA') + + 'install Venus starter site with French (CA)': function (browser) { + browser + .installWebsite('en-US', 'French (CA)', 'fr-CA') + + // assert the GUI and the website language is French + browser + .selectPerspective("SystĂšme") + .openTreeNode("Langues") + .assertTreeNodeHasChild("Langues", "Français, Canada") + + }, + + 'reinstall Venus starter site with English (US)': function (browser) { + browser.installWebsite('en-US') + + // assert the GUI and the website language is English + browser + .selectPerspective("System") + .openTreeNode("Languages") + .assertTreeNodeHasChild("Languages", "English, US") } + + } From a96cc708c5d435d78563ca5a816e7024f9c21857 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Wed, 2 Nov 2016 11:43:16 +0200 Subject: [PATCH 007/135] Notepad++ API plugin update The plugin for Noetpad++ updated with 5 new commands --- .../e2e/ApiLang/Notepad++/Nightwatch.UDL.xml | 2 +- .../test/e2e/ApiLang/Notepad++/nightwatch.xml | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml b/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml index f7bf81287d..df03ad54bb 100644 --- a/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml +++ b/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml @@ -24,7 +24,7 @@ - assertBrowserContainsAttribute assertBrowserContains assertFieldValue assertTreeNodeHasChild assertTreeNodeIsEmpty assertTreeNodeIsNotEmpty clickDataBySibilings clickDialogButton clickInFrame clickLabel clickSave replaceTextInCodeMirror selectEditOnContent clickText closeDocumentTab changeElementContent doubleClickSelector enterFrame leaveFrame openTreeNode replaceContent rightClickSelector selectActionFromToolbar selectContentTab selectDialog selectDocumentTab selectFrame selectFrameWithXpath selectPerspective selectTreeNodeAction setFieldValueInFieldGroup setFieldValue setFileFieldValue switchContentTab topFrame waitForFrameLoad acceptChanges acceptFunctionEdit assertTreeNodeHasNoChild submitFormData installPackage uninstallPackage + assertBrowserContainsAttribute assertBrowserContains assertFieldValue assertTreeNodeHasChild assertTreeNodeIsEmpty assertTreeNodeIsNotEmpty clickDataBySibilings clickDialogButton clickInFrame clickLabel clickSave replaceTextInCodeMirror selectEditOnContent clickText closeDocumentTab changeElementContent doubleClickSelector enterFrame leaveFrame openTreeNode replaceContent rightClickSelector selectActionFromToolbar selectContentTab selectDialog selectDocumentTab selectFrame selectFrameWithXpath selectPerspective selectTreeNodeAction setFieldValueInFieldGroup setFieldValue setFileFieldValue switchContentTab topFrame waitForFrameLoad acceptChanges acceptFunctionEdit assertTreeNodeHasNoChild submitFormData installPackage uninstallPackage installCommercialPackage installLocalPackage uninstallLocalPackage installLocale uninstallLocale installWebsite browser editor2 editor beforeEach afterEach done diff --git a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml index 483f9a7927..ef19b94b07 100644 --- a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml +++ b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml @@ -237,5 +237,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 1ea3e84daee191e239f53f74d5c9d995a9206baa Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Thu, 3 Nov 2016 12:29:11 +0200 Subject: [PATCH 008/135] Starter Site Installations 1. globals.js: a new object starterSites added - positioning each starter site by index (1 through 5) 2. Command: installWebsite extended with 'starterSite' parameter. Currently hard-coded to "Venus" until reset.js is updated to other starter sites 3. Tests: WIP - /sandbox/InstallOtherStarterSite.js - currently works only with "Venus" 4. Tests: /000_setup/installSite.js and /locales/InstallSiteWithOtherLanguage.js updated with the new parameter of installWebsite 5. Notepad++ Nightwatch API updated with the starterSite parameter on installWebsite --- .../test/e2e/ApiLang/Notepad++/nightwatch.xml | 1 + Website/test/e2e/commands/installWebsite.js | 24 +++++++-- Website/test/e2e/globals.js | 9 ++++ .../test/e2e/suite/000_setup/installSite.js | 3 +- .../locales/InstallSiteWithOtherLanguage.js | 4 +- .../suite/sandbox/InstallOtherStarterSite.js | 52 +++++++++++++++++++ 6 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js diff --git a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml index ef19b94b07..3f792e6a6c 100644 --- a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml +++ b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml @@ -267,6 +267,7 @@ + diff --git a/Website/test/e2e/commands/installWebsite.js b/Website/test/e2e/commands/installWebsite.js index 1cb5781ad7..57817893c6 100644 --- a/Website/test/e2e/commands/installWebsite.js +++ b/Website/test/e2e/commands/installWebsite.js @@ -4,8 +4,9 @@ function InstallWebsite() { events.EventEmitter.call(this); } -InstallWebsite.prototype.command = function (expectedLanguage, newLanguage, newLanguageCode) { +InstallWebsite.prototype.command = function (starterSite, expectedLanguage, newLanguage, newLanguageCode) { var browser = this.client.api; + starterSite = "Venus"; // other starter sites disallowed until reset.js is updated for other starter sites browser // The “Welcome” page of the setup wizard appears. @@ -33,19 +34,32 @@ InstallWebsite.prototype.command = function (expectedLanguage, newLanguage, newL // The “Starter Site” radio button is present and selected .waitForElementVisible('#setup', browser.globals.timeouts.little); browser.expect.element('#setup h1').text.to.contain('Setup'); - // The “Venus” radio button is present and selected. + // The “Venus” (or other site's) radio button is present and selected. browser.expect .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > radiobutton') .to.have.attribute('ischecked', 'true'); browser.expect .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') .text.to.equal('Starter sites'); + + // {{ + + // select a starter site + + var siteIndex = this.api.globals.starterSites[starterSite]; + + browser.clickLabel(starterSite); + browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(1) > radiobutton') + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(' + siteIndex + ') > radiobutton') .to.have.attribute('ischecked', 'true'); + browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') - .text.to.equal('Venus'); + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(' + siteIndex + ') > datalabeltext') + .text.to.equal(starterSite); + + // }} + // The “Next” button is available and enabled browser.expect.element('#navsetup clickbutton[label="Next"]').to.not.have.attribute('isdisabled'); // 5 Click “Next”. The “Language” page of the setup wizard appears. diff --git a/Website/test/e2e/globals.js b/Website/test/e2e/globals.js index d99ea6ab6f..2971a149c1 100644 --- a/Website/test/e2e/globals.js +++ b/Website/test/e2e/globals.js @@ -3,8 +3,17 @@ var timeouts = { save: 120000, little: 1000, }; + +var starterSites = { + Venus: 1, + Neptune: 2, + Mercury: 3, + "Open Cph - Razor": 4, + "Open Cph - Master Pages" : 5, + }; module.exports = { timeouts : timeouts, + starterSites : starterSites, beforeEach: function (browser, done) { browser.resizeWindow(1400, 1000, done); }, diff --git a/Website/test/e2e/suite/000_setup/installSite.js b/Website/test/e2e/suite/000_setup/installSite.js index 6a15a64b07..05c969e45d 100644 --- a/Website/test/e2e/suite/000_setup/installSite.js +++ b/Website/test/e2e/suite/000_setup/installSite.js @@ -1,5 +1,6 @@ var resetSite = require('../../reset.js'); +var starterSite = 'Venus'; var expectedLanguage = 'en-US'; module.exports = { @@ -21,6 +22,6 @@ module.exports = { .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); }, 'install Venus starter site': function (browser) { - browser.installWebsite(expectedLanguage) + browser.installWebsite(starterSite, expectedLanguage) } } diff --git a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js index 11e82611c4..cf587f5a97 100644 --- a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js +++ b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js @@ -19,7 +19,7 @@ module.exports = { 'install Venus starter site with French (CA)': function (browser) { browser - .installWebsite('en-US', 'French (CA)', 'fr-CA') + .installWebsite('Venus', 'en-US', 'French (CA)', 'fr-CA') // assert the GUI and the website language is French browser @@ -30,7 +30,7 @@ module.exports = { }, 'reinstall Venus starter site with English (US)': function (browser) { - browser.installWebsite('en-US') + browser.installWebsite('Venus', 'en-US') // assert the GUI and the website language is English browser diff --git a/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js b/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js new file mode 100644 index 0000000000..195c8400d4 --- /dev/null +++ b/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js @@ -0,0 +1,52 @@ +var resetSite = require('../../reset.js'); + +module.exports = { + '@tags': ['install'], + beforeEach: function (browser) { + // 0 Reset the website + resetSite(function (err) { + if (err) { + browser.end(); + console.error(err); + process.exit(1); + } + }); + + // 1 Launch an uninitialized website. + browser + .url(browser.launchUrl + '/Composite/top.aspx') + .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); + /* */ + }, + +/* + 'install Neptune starter site': function (browser) { + browser + .installWebsite('Neptune', 'en-US') + }, + + 'install Mercury starter site': function (browser) { + browser + .installWebsite('Mercury', 'en-US') + }, + + 'install Open Cph Razor starter site': function (browser) { + browser + .installWebsite('Open Cph - Razor', 'en-US') + }, + + 'install Open Cph Master Pages starter site': function (browser) { + browser + .installWebsite('Open Cph - Master Pages', 'en-US') + }, +*/ + 'install Venus starter site': function (browser) { + browser + .installWebsite('Venus', 'en-US') + + browser + .selectPerspective("Content") + .openTreeNode("Venus Starter Site") + } + +} From 9e75561746ca69d69ed99dc0077a4c8416c7684f Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Fri, 4 Nov 2016 10:52:38 +0200 Subject: [PATCH 009/135] Starter Site Installations (WIP) 1. globals.js: 2 new objects added: setupOptions and templatesOnly - to position setup options (1 through 3) and templates only sites (1 through 2) by index 2. Command: installWebsite extended with the 'setupOption' parameter. Currently hard-coded to "Starter sites' until reset.js is updated to other starter sites 3. Tests: updated accordingly those using installWebsite: installSite, InstallSiteWithOtherLanguage, InstallOtherStarterSite 4. Notepad++ Nightwatch API updated with the 'setupOption' parameter on 'installWebsite' --- .../test/e2e/ApiLang/Notepad++/nightwatch.xml | 1 + Website/test/e2e/commands/installWebsite.js | 54 ++++++++++++------- Website/test/e2e/globals.js | 19 +++++-- .../test/e2e/suite/000_setup/installSite.js | 3 +- .../locales/InstallSiteWithOtherLanguage.js | 4 +- .../suite/sandbox/InstallOtherStarterSite.js | 3 +- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml index 3f792e6a6c..4da146be0a 100644 --- a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml +++ b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml @@ -267,6 +267,7 @@ + diff --git a/Website/test/e2e/commands/installWebsite.js b/Website/test/e2e/commands/installWebsite.js index 57817893c6..70f5187c64 100644 --- a/Website/test/e2e/commands/installWebsite.js +++ b/Website/test/e2e/commands/installWebsite.js @@ -4,9 +4,13 @@ function InstallWebsite() { events.EventEmitter.call(this); } -InstallWebsite.prototype.command = function (starterSite, expectedLanguage, newLanguage, newLanguageCode) { +InstallWebsite.prototype.command = function (setupOption, starterSite, expectedLanguage, newLanguage, newLanguageCode) { var browser = this.client.api; - starterSite = "Venus"; // other starter sites disallowed until reset.js is updated for other starter sites + + // TEMP: other setup and starter site options disallowed + // until reset.js is updated for other setup options and starter sites + setupOption = "Starter sites"; + starterSite = "Venus"; browser // The “Welcome” page of the setup wizard appears. @@ -35,30 +39,40 @@ InstallWebsite.prototype.command = function (starterSite, expectedLanguage, newL .waitForElementVisible('#setup', browser.globals.timeouts.little); browser.expect.element('#setup h1').text.to.contain('Setup'); // The “Venus” (or other site's) radio button is present and selected. + + // {{ select s setup option, for example "Starter site" + + var setupGroupIndex = this.api.globals.setupOptions[setupOption]; + + browser.clickLabel(setupOption); + browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > radiobutton') + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(' + setupGroupIndex + ') > radiobutton') .to.have.attribute('ischecked', 'true'); browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) > datalabeltext') - .text.to.equal('Starter sites'); + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(' + setupGroupIndex + ') > datalabeltext') + .text.to.equal(setupOption); - // {{ - - // select a starter site + // }} + + // {{ select a starter site, for example, "Venus" (only if not "Bare bones" : 3) + + if(setupOption != 'Bare bones') + { + var siteIndex = this.api.globals.starterSites[starterSite]; + + browser.clickLabel(starterSite); + + browser.expect + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(' + setupGroupIndex + ') + p + div > radiodatagroup > radio:nth-of-type(' + siteIndex + ') > radiobutton') + .to.have.attribute('ischecked', 'true'); - var siteIndex = this.api.globals.starterSites[starterSite]; + browser.expect + .element('#setupfields > div > radiodatagroup > radio:nth-of-type(' + setupGroupIndex + ') + p + div > radiodatagroup > radio:nth-of-type(' + siteIndex + ') > datalabeltext') + .text.to.equal(starterSite); + } - browser.clickLabel(starterSite); - - browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(' + siteIndex + ') > radiobutton') - .to.have.attribute('ischecked', 'true'); - - browser.expect - .element('#setupfields > div > radiodatagroup > radio:nth-of-type(1) + p + div > radiodatagroup > radio:nth-of-type(' + siteIndex + ') > datalabeltext') - .text.to.equal(starterSite); - - // }} + // }} // The “Next” button is available and enabled browser.expect.element('#navsetup clickbutton[label="Next"]').to.not.have.attribute('isdisabled'); diff --git a/Website/test/e2e/globals.js b/Website/test/e2e/globals.js index 2971a149c1..a7e13104a9 100644 --- a/Website/test/e2e/globals.js +++ b/Website/test/e2e/globals.js @@ -3,17 +3,30 @@ var timeouts = { save: 120000, little: 1000, }; - + +var setupOptions = { + "Starter sites" : 1, + "Templates only" : 2, + "Bare bones" : 3, +} + var starterSites = { Venus: 1, Neptune: 2, Mercury: 3, "Open Cph - Razor": 4, "Open Cph - Master Pages" : 5, - }; + }; + +var templatesOnly = { + "Tiny Cph - Razor": 1, + "Tiny Cph - Master Pages" : 2, +} + module.exports = { timeouts : timeouts, - starterSites : starterSites, + setupOptions : setupOptions, + starterSites : starterSites, beforeEach: function (browser, done) { browser.resizeWindow(1400, 1000, done); }, diff --git a/Website/test/e2e/suite/000_setup/installSite.js b/Website/test/e2e/suite/000_setup/installSite.js index 05c969e45d..3afc9ba367 100644 --- a/Website/test/e2e/suite/000_setup/installSite.js +++ b/Website/test/e2e/suite/000_setup/installSite.js @@ -1,5 +1,6 @@ var resetSite = require('../../reset.js'); +var setupOption = 'Bare bones'; var starterSite = 'Venus'; var expectedLanguage = 'en-US'; @@ -22,6 +23,6 @@ module.exports = { .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); }, 'install Venus starter site': function (browser) { - browser.installWebsite(starterSite, expectedLanguage) + browser.installWebsite(setupOption, starterSite, expectedLanguage) } } diff --git a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js index cf587f5a97..8f582dd2de 100644 --- a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js +++ b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js @@ -19,7 +19,7 @@ module.exports = { 'install Venus starter site with French (CA)': function (browser) { browser - .installWebsite('Venus', 'en-US', 'French (CA)', 'fr-CA') + .installWebsite('Starter sites', 'Venus', 'en-US', 'French (CA)', 'fr-CA') // assert the GUI and the website language is French browser @@ -30,7 +30,7 @@ module.exports = { }, 'reinstall Venus starter site with English (US)': function (browser) { - browser.installWebsite('Venus', 'en-US') + browser.installWebsite('Starter sites', 'Venus', 'en-US') // assert the GUI and the website language is English browser diff --git a/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js b/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js index 195c8400d4..667ae52ec7 100644 --- a/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js +++ b/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js @@ -16,7 +16,6 @@ module.exports = { browser .url(browser.launchUrl + '/Composite/top.aspx') .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); - /* */ }, /* @@ -42,7 +41,7 @@ module.exports = { */ 'install Venus starter site': function (browser) { browser - .installWebsite('Venus', 'en-US') + .installWebsite('Starter sites', 'Venus', 'en-US') browser .selectPerspective("Content") From 34eb1e5bd7e457265acea6100fcf8688f2f4d7dc Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Fri, 4 Nov 2016 11:32:35 +0200 Subject: [PATCH 010/135] Website Installation: small fix in installSite.js --- Website/test/e2e/suite/000_setup/installSite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/test/e2e/suite/000_setup/installSite.js b/Website/test/e2e/suite/000_setup/installSite.js index 3afc9ba367..868d0415ef 100644 --- a/Website/test/e2e/suite/000_setup/installSite.js +++ b/Website/test/e2e/suite/000_setup/installSite.js @@ -1,6 +1,6 @@ var resetSite = require('../../reset.js'); -var setupOption = 'Bare bones'; +var setupOption = 'Starter sites'; var starterSite = 'Venus'; var expectedLanguage = 'en-US'; From 9c848b13630296919d68f19a0bddd8c4521ed57e Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Sat, 5 Nov 2016 03:17:31 +0200 Subject: [PATCH 011/135] Starter Site Installations 1. reset.js: new, uses robocopy to take an initial snapshot of essential folders of the uninitialized site, then restores from it on further calls. The old reset.js renamed as reset.old.js 2. Command: installWebsite now enabled to accept setup options ('Starter sites', or 'Bare bones') or 1 of 5 starter sites. 3. Test: /starterSites/InstallStarterSites.js improved and extended version of /sandbox/InstallOtherStarterSite.js 4. Test: 000_setup/installSite.js updated to work with the new reset.js and installWebsite.js. Defaults to 'Venus'. 5. Test: locales/InstallSiteWithOtherLanguage.js updated to work with the new reset.js and installWebsite.js --- Website/test/e2e/commands/installWebsite.js | 9 +- Website/test/e2e/reset.js | 194 +++++++++--------- Website/test/e2e/reset.old.js | 104 ++++++++++ .../test/e2e/suite/000_setup/installSite.js | 19 +- .../locales/InstallSiteWithOtherLanguage.js | 15 +- .../suite/starterSites/InstallStarterSites.js | 77 +++++++ 6 files changed, 292 insertions(+), 126 deletions(-) create mode 100644 Website/test/e2e/reset.old.js create mode 100644 Website/test/e2e/suite/starterSites/InstallStarterSites.js diff --git a/Website/test/e2e/commands/installWebsite.js b/Website/test/e2e/commands/installWebsite.js index 70f5187c64..1476a5752d 100644 --- a/Website/test/e2e/commands/installWebsite.js +++ b/Website/test/e2e/commands/installWebsite.js @@ -5,12 +5,13 @@ function InstallWebsite() { } InstallWebsite.prototype.command = function (setupOption, starterSite, expectedLanguage, newLanguage, newLanguageCode) { + var browser = this.client.api; - // TEMP: other setup and starter site options disallowed - // until reset.js is updated for other setup options and starter sites - setupOption = "Starter sites"; - starterSite = "Venus"; + // Launch an uninitialized website. + browser + .url(browser.launchUrl + '/Composite/top.aspx') + .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); browser // The “Welcome” page of the setup wizard appears. diff --git a/Website/test/e2e/reset.js b/Website/test/e2e/reset.js index df58e03fb5..012af978c6 100644 --- a/Website/test/e2e/reset.js +++ b/Website/test/e2e/reset.js @@ -1,104 +1,106 @@ -const removePaths = [ - 'Website/App_Data/Composite/Configuration/Composite.Forms.FormBuilder.xml', - 'Website/App_Data/Composite/Configuration/Composite.Media.ImageCrop.xml', - 'Website/App_Data/Composite/Configuration/DynamicXmlDataProvider.config', - 'Website/App_Data/Composite/Configuration/FirstTimeStart.xml', - 'Website/App_Data/Composite/Configuration/InstallationInformation.xml', - 'Website/App_Data/Composite/Configuration/SystemInitialized.xml', - 'Website/App_Data/Composite/DataMetaData/', - 'Website/App_Data/Composite/DataStores/', - 'Website/App_Data/Composite/DynamicTypeForms/*', - 'Website/App_Data/Composite/InlineCSharpFunctions/', - 'Website/App_Data/Composite/PackageLicenses/', - 'Website/App_Data/Composite/Packages/', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Entries.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xml', - 'Website/App_Data/Media/', - 'Website/App_Data/PageTemplateFeatures/', - 'Website/App_Data/PageTemplates/*.cshtml', - 'Website/App_Data/Razor/Composite/', - 'Website/App_Data/Razor/Orckestra/', - 'Website/App_Data/Razor/Layout/', - 'Website/App_Data/Razor/PageBlocks/', - 'Website/App_GlobalResources/', - 'Website/BlogMetaWeblog.ashx', - 'Website/BlogRssFeed.ashx', - 'Website/Composite/InstalledPackages/', - 'Website/Frontend/Composite/', - 'Website/Frontend/Orckestra/', - 'Website/Frontend/Images/*', - 'Website/Frontend/Scripts/*', - 'Website/Frontend/Styles/VisualEditor.less', - 'Website/Frontend/Styles/style.less', - 'Website/Frontend/Styles/style.min.css', - 'Website/Frontend/Styles/bootstrap', - 'Website/Frontend/Styles/font-awesome', - 'Website/Frontend/Styles/includes', - 'Website/Frontend/Styles/PageBlocks', - 'Website/Frontend/Styles/style.less', - 'Website/Frontend/Styles/style.min.css', - 'Website/Frontend/Styles/VisualEditor.common.less', - 'Website/Frontend/Styles/VisualEditor.less', - 'Website/Frontend/fonts/', - 'Website/bin/Antlr3.Runtime.dll', - 'Website/bin/Composite.Community.Blog.dll', - 'Website/bin/Composite.Forms.FormBuilder.dll', - 'Website/bin/Composite.Forms.Renderer.dll', - 'Website/bin/Composite.Generated.dll', - 'Website/bin/Composite.Media.ImageCrop.dll', - 'Website/bin/Composite.Search.SimplePageSearch.dll', - 'Website/bin/Composite.Tools.LinkChecker.dll', - 'Website/bin/Composite.Web.BundlingAndMinification.dll', - 'Website/bin/Composite.Web.Css.Less.dll', - 'Website/bin/CookComputing.XmlRpcV2.dll', - 'Website/bin/ICSharpCode.SharpZipLib.dll', - 'Website/bin/System.Web.Optimization.dll', - 'Website/bin/WebGrease.dll' + +const backupPaths = [ + 'App_Data', + 'bin', + 'Composite', + 'Frontend', + 'Renderers' +] + +const ignoredPaths = [ + + 'bower_components', + 'obj', + 'node_modules', + 'Properties', + 'test' + ] -const rimraf = require('rimraf'); + + const fs = require('fs'); +const robocopy = require('robocopy'); const basepath = process.cwd(); -function copyFile(source, target) { - return new Promise(function(resolve, reject) { - var reader = fs.createReadStream(source); - reader.on('error', reject); - var id = Math.ceil(10000 * Math.random()); - var writer = fs.createWriteStream('tmp' + id); - writer.on('error', reject); - writer.on('finish', function () { resolve(id); }); - reader.pipe(writer); - }).then(function (id) { - fs.renameSync('tmp' + id, target); - }); -} +module.exports = function reset() { + + // the backup exists + if(fs.existsSync(basepath + '\\_backups')) + { + /* + // copy ignoredPaths to /_ignored, mirroring + if(!fs.existsSync(basepath + '\\_ignored')) + { + fs.mkdir(basepath + '\\_ignored'); + } + */ + + var count = ignoredPaths.length; + + for(var i = 0; i < count; i++) + { + robocopy ({ + source: basepath + '\\Website\\' + ignoredPaths[i], + destination: basepath + '\\_backups\\' + ignoredPaths[i], + subdirs: true, + copy:{ + mirror: true + } + }); + } + -module.exports = function reset(callback) { - Promise.all(removePaths.map(function (path) { - var fullpath = basepath + '\\' + path; - return new Promise(function (resolve, reject) { - rimraf(fullpath, {}, function (err) { - if (err) { - reject(err); - } else { - resolve(); + // restore the /Website from /_backups, mirroring + + // except for the folder where the server is running + robocopy ({ + source: basepath + '\\_backups\\', + destination: basepath + '\\Website\\', + subdirs: true, + copy:{ + mirror: true + }, + file:{ + excludeDirs: [ + basepath + '\\Website\\test', + basepath + '\\_backups\\test', + basepath + '\\Website\\bower_components', + basepath + '\\_backups\\bower_components', + basepath + '\\Website\\node_modules', + basepath + '\\_backups\\node_modules' + ] + } + + }); + } + + // the backup doesn't exist + else + { + // 1 create the backup folder: + fs.mkdir(basepath + '\\_backups'); + + var count = backupPaths.length; + + // 2 - copy backupPaths to /_backups + for(var i = 0; i < count; i++) + { + robocopy ({ + source: basepath + '\\Website\\' + backupPaths[i], + destination: basepath + '\\_backups\\' + backupPaths[i], + subdirs: true, + copy:{ + mirror: true } - }); - }); - })) - .then(function () { - return Promise.all([ - copyFile(basepath + '/Website/DebugBuild.Web.config', - basepath + '/Website/Web.config'), - copyFile(basepath + '/Website/App_Data/Composite/DebugBuild.Composite.config', - basepath + '/Website/App_Data/Composite/Composite.config') - ]); - }) - .then(function () { - callback(); - }) - .catch(function (err) { - callback(err); - }); + }); + } + + // 3 - copy /Website/*.* to /_backups, no subdirs + robocopy ({ + source: basepath + '\\Website', + destination: basepath + '\\_backups', + subdirs: false + }); + } }; diff --git a/Website/test/e2e/reset.old.js b/Website/test/e2e/reset.old.js new file mode 100644 index 0000000000..df58e03fb5 --- /dev/null +++ b/Website/test/e2e/reset.old.js @@ -0,0 +1,104 @@ +const removePaths = [ + 'Website/App_Data/Composite/Configuration/Composite.Forms.FormBuilder.xml', + 'Website/App_Data/Composite/Configuration/Composite.Media.ImageCrop.xml', + 'Website/App_Data/Composite/Configuration/DynamicXmlDataProvider.config', + 'Website/App_Data/Composite/Configuration/FirstTimeStart.xml', + 'Website/App_Data/Composite/Configuration/InstallationInformation.xml', + 'Website/App_Data/Composite/Configuration/SystemInitialized.xml', + 'Website/App_Data/Composite/DataMetaData/', + 'Website/App_Data/Composite/DataStores/', + 'Website/App_Data/Composite/DynamicTypeForms/*', + 'Website/App_Data/Composite/InlineCSharpFunctions/', + 'Website/App_Data/Composite/PackageLicenses/', + 'Website/App_Data/Composite/Packages/', + 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Entries.xml', + 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xml', + 'Website/App_Data/Media/', + 'Website/App_Data/PageTemplateFeatures/', + 'Website/App_Data/PageTemplates/*.cshtml', + 'Website/App_Data/Razor/Composite/', + 'Website/App_Data/Razor/Orckestra/', + 'Website/App_Data/Razor/Layout/', + 'Website/App_Data/Razor/PageBlocks/', + 'Website/App_GlobalResources/', + 'Website/BlogMetaWeblog.ashx', + 'Website/BlogRssFeed.ashx', + 'Website/Composite/InstalledPackages/', + 'Website/Frontend/Composite/', + 'Website/Frontend/Orckestra/', + 'Website/Frontend/Images/*', + 'Website/Frontend/Scripts/*', + 'Website/Frontend/Styles/VisualEditor.less', + 'Website/Frontend/Styles/style.less', + 'Website/Frontend/Styles/style.min.css', + 'Website/Frontend/Styles/bootstrap', + 'Website/Frontend/Styles/font-awesome', + 'Website/Frontend/Styles/includes', + 'Website/Frontend/Styles/PageBlocks', + 'Website/Frontend/Styles/style.less', + 'Website/Frontend/Styles/style.min.css', + 'Website/Frontend/Styles/VisualEditor.common.less', + 'Website/Frontend/Styles/VisualEditor.less', + 'Website/Frontend/fonts/', + 'Website/bin/Antlr3.Runtime.dll', + 'Website/bin/Composite.Community.Blog.dll', + 'Website/bin/Composite.Forms.FormBuilder.dll', + 'Website/bin/Composite.Forms.Renderer.dll', + 'Website/bin/Composite.Generated.dll', + 'Website/bin/Composite.Media.ImageCrop.dll', + 'Website/bin/Composite.Search.SimplePageSearch.dll', + 'Website/bin/Composite.Tools.LinkChecker.dll', + 'Website/bin/Composite.Web.BundlingAndMinification.dll', + 'Website/bin/Composite.Web.Css.Less.dll', + 'Website/bin/CookComputing.XmlRpcV2.dll', + 'Website/bin/ICSharpCode.SharpZipLib.dll', + 'Website/bin/System.Web.Optimization.dll', + 'Website/bin/WebGrease.dll' +] +const rimraf = require('rimraf'); +const fs = require('fs'); + +const basepath = process.cwd(); + +function copyFile(source, target) { + return new Promise(function(resolve, reject) { + var reader = fs.createReadStream(source); + reader.on('error', reject); + var id = Math.ceil(10000 * Math.random()); + var writer = fs.createWriteStream('tmp' + id); + writer.on('error', reject); + writer.on('finish', function () { resolve(id); }); + reader.pipe(writer); + }).then(function (id) { + fs.renameSync('tmp' + id, target); + }); +} + +module.exports = function reset(callback) { + Promise.all(removePaths.map(function (path) { + var fullpath = basepath + '\\' + path; + return new Promise(function (resolve, reject) { + rimraf(fullpath, {}, function (err) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + })) + .then(function () { + return Promise.all([ + copyFile(basepath + '/Website/DebugBuild.Web.config', + basepath + '/Website/Web.config'), + copyFile(basepath + '/Website/App_Data/Composite/DebugBuild.Composite.config', + basepath + '/Website/App_Data/Composite/Composite.config') + ]); + }) + .then(function () { + callback(); + }) + .catch(function (err) { + callback(err); + }); +}; diff --git a/Website/test/e2e/suite/000_setup/installSite.js b/Website/test/e2e/suite/000_setup/installSite.js index 868d0415ef..0902660a59 100644 --- a/Website/test/e2e/suite/000_setup/installSite.js +++ b/Website/test/e2e/suite/000_setup/installSite.js @@ -6,22 +6,11 @@ var expectedLanguage = 'en-US'; module.exports = { '@tags': ['install'], - before: function (browser, done) { - resetSite(function (err) { - if (err) { - browser.end(); - console.error(err); - process.exit(1); - } - done(); - }); - }, - beforeEach: function (browser) { - // 1 Launch an uninitialized website. - browser - .url(browser.launchUrl + '/Composite/top.aspx') - .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); + + before: function () { + resetSite(); }, + 'install Venus starter site': function (browser) { browser.installWebsite(setupOption, starterSite, expectedLanguage) } diff --git a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js index 8f582dd2de..bdb4275f1a 100644 --- a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js +++ b/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js @@ -4,17 +4,7 @@ module.exports = { '@tags': ['install'], beforeEach: function (browser) { // 0 Reset the website - resetSite(function (err) { - if (err) { - browser.end(); - console.error(err); - process.exit(1); - } - }); - // 1 Launch an uninitialized website. - browser - .url(browser.launchUrl + '/Composite/top.aspx') - .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); + resetSite(); }, 'install Venus starter site with French (CA)': function (browser) { @@ -27,6 +17,7 @@ module.exports = { .openTreeNode("Langues") .assertTreeNodeHasChild("Langues", "Français, Canada") + .end() }, 'reinstall Venus starter site with English (US)': function (browser) { @@ -37,6 +28,8 @@ module.exports = { .selectPerspective("System") .openTreeNode("Languages") .assertTreeNodeHasChild("Languages", "English, US") + + .end() } diff --git a/Website/test/e2e/suite/starterSites/InstallStarterSites.js b/Website/test/e2e/suite/starterSites/InstallStarterSites.js new file mode 100644 index 0000000000..b4bdce1359 --- /dev/null +++ b/Website/test/e2e/suite/starterSites/InstallStarterSites.js @@ -0,0 +1,77 @@ +var resetSite = require('../../reset.js'); + +module.exports = { + '@tags': ['install'], + beforeEach: function (browser) { + // 0 Reset the website + resetSite(); + }, + + // 1 install starter sites other than "Venus" + 'install Neptune starter site': function (browser) { + browser + .installWebsite('Starter sites', 'Neptune', 'en-US') + + browser + .selectPerspective("Content") + .openTreeNode("Neptune Starter Site") + + .end() + }, + + 'install Mercury starter site': function (browser) { + browser + .installWebsite('Starter sites', 'Mercury', 'en-US') + + browser + .selectPerspective("Content") + .openTreeNode("Frontpage") + + .end() + }, + + 'install Open Cph Razor starter site': function (browser) { + browser + .installWebsite('Starter sites', 'Open Cph - Razor', 'en-US') + + browser + .selectPerspective("Content") + .openTreeNode("Open Cph Starter Site") + + .end() + }, + + 'install Open Cph Master Pages starter site': function (browser) { + browser + .installWebsite('Starter sites', 'Open Cph - Master Pages', 'en-US') + + browser + .selectPerspective("Content") + .openTreeNode("Open Cph Starter Site") + + .end() + }, + + 'install Bare Bones site': function (browser) { + browser + .installWebsite('Bare bones', '', 'en-US') + + browser + .selectPerspective("Content") + .assertTreeNodeHasNoChild('Websites') + + .end() + }, + + // 2 reset to "Venus" + 'install Venus starter site': function (browser) { + browser + .installWebsite('Starter sites', 'Venus', 'en-US') + + browser + .selectPerspective("Content") + .openTreeNode("Venus Starter Site") + + .end() + }, +} From 329efdee10226c4defc38a285af48f91f4aef28f Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Sat, 5 Nov 2016 03:50:59 +0200 Subject: [PATCH 012/135] Added 'robocopy' module and bumped up the version of 'chromedriver' --- Website/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Website/package.json b/Website/package.json index 02ae1f25b1..4569343698 100644 --- a/Website/package.json +++ b/Website/package.json @@ -4,7 +4,7 @@ "devDependencies": { "JSONPath": "^0.10.0", "autoprefixer-core": "^5.2.1", - "chromedriver": "2.21.2", + "chromedriver": "^2.25.1", "csswring": "^3.0.5", "grunt": "~0.4.5", "grunt-contrib-copy": "0.8.2", @@ -15,6 +15,7 @@ "iedriver": "2.53.1", "less": "^2.1.2", "nightwatch": "0.9.3", + "robocopy": "^0.1.15", "rimraf": "2.5.4", "selenium-server-standalone-jar": "2.53.1", "xml2js": "^0.4.10" From e888eae0ce85908db102af4563ff334158edc13e Mon Sep 17 00:00:00 2001 From: wwwysocki Date: Mon, 7 Nov 2016 20:19:08 +0200 Subject: [PATCH 013/135] Small fixes 1. The leftover test in /sandbox removed. Wrongly committed before. 2. The function in the test UninstallInstallYouTube renamed. Wrongy copied from InstallUninstallExtranet 3. The tests with reinstallation of starter websites moved to the end of the test suite in /zzz_starterSites --- .../suite/packages/UninstallInstallYouTube.js | 2 +- .../suite/sandbox/InstallOtherStarterSite.js | 51 ------------------- .../InstallSiteWithOtherLanguage.js | 0 .../InstallStarterSites.js | 0 4 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js rename Website/test/e2e/suite/{locales => zzz_starterSites}/InstallSiteWithOtherLanguage.js (100%) rename Website/test/e2e/suite/{starterSites => zzz_starterSites}/InstallStarterSites.js (100%) diff --git a/Website/test/e2e/suite/packages/UninstallInstallYouTube.js b/Website/test/e2e/suite/packages/UninstallInstallYouTube.js index 1420979035..b0a77f8494 100644 --- a/Website/test/e2e/suite/packages/UninstallInstallYouTube.js +++ b/Website/test/e2e/suite/packages/UninstallInstallYouTube.js @@ -6,7 +6,7 @@ module.exports = { content .prepare("Content"); }, - 'Install Extranet': function (browser) { + 'Uninstall and Install YouTube': function (browser) { browser .uninstallLocalPackage("Composite.Media.YouTube") diff --git a/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js b/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js deleted file mode 100644 index 667ae52ec7..0000000000 --- a/Website/test/e2e/suite/sandbox/InstallOtherStarterSite.js +++ /dev/null @@ -1,51 +0,0 @@ -var resetSite = require('../../reset.js'); - -module.exports = { - '@tags': ['install'], - beforeEach: function (browser) { - // 0 Reset the website - resetSite(function (err) { - if (err) { - browser.end(); - console.error(err); - process.exit(1); - } - }); - - // 1 Launch an uninitialized website. - browser - .url(browser.launchUrl + '/Composite/top.aspx') - .waitForElementVisible('.welcomepage', browser.globals.timeouts.basic); - }, - -/* - 'install Neptune starter site': function (browser) { - browser - .installWebsite('Neptune', 'en-US') - }, - - 'install Mercury starter site': function (browser) { - browser - .installWebsite('Mercury', 'en-US') - }, - - 'install Open Cph Razor starter site': function (browser) { - browser - .installWebsite('Open Cph - Razor', 'en-US') - }, - - 'install Open Cph Master Pages starter site': function (browser) { - browser - .installWebsite('Open Cph - Master Pages', 'en-US') - }, -*/ - 'install Venus starter site': function (browser) { - browser - .installWebsite('Starter sites', 'Venus', 'en-US') - - browser - .selectPerspective("Content") - .openTreeNode("Venus Starter Site") - } - -} diff --git a/Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js b/Website/test/e2e/suite/zzz_starterSites/InstallSiteWithOtherLanguage.js similarity index 100% rename from Website/test/e2e/suite/locales/InstallSiteWithOtherLanguage.js rename to Website/test/e2e/suite/zzz_starterSites/InstallSiteWithOtherLanguage.js diff --git a/Website/test/e2e/suite/starterSites/InstallStarterSites.js b/Website/test/e2e/suite/zzz_starterSites/InstallStarterSites.js similarity index 100% rename from Website/test/e2e/suite/starterSites/InstallStarterSites.js rename to Website/test/e2e/suite/zzz_starterSites/InstallStarterSites.js From 4f6800a77bb13d77920529745a7672a8dc160fa4 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Tue, 8 Nov 2016 10:19:56 +0200 Subject: [PATCH 014/135] Fixes for timeouts and test environments 1. global.js: timeouts: +loading: 25000 2. Commands: installWebsite.js: timeout.loading used in the final steps to handle timeout issues 3. nightwatch.json: sql env: + /packages + /zzz_starterSites --- Website/test/e2e/commands/installWebsite.js | 4 ++-- Website/test/e2e/globals.js | 1 + nightwatch.json | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Website/test/e2e/commands/installWebsite.js b/Website/test/e2e/commands/installWebsite.js index 1476a5752d..662ea20fc8 100644 --- a/Website/test/e2e/commands/installWebsite.js +++ b/Website/test/e2e/commands/installWebsite.js @@ -164,9 +164,9 @@ InstallWebsite.prototype.command = function (setupOption, starterSite, expectedL .waitForElementVisible('#loading', browser.globals.timeouts.little) // Eventually, the user logs in successfully and the CMS Console appears. .waitForElementNotPresent('#loading', browser.globals.timeouts.save) - .waitForElementVisible('body', browser.globals.timeouts.basic) + .waitForElementVisible('body', browser.globals.timeouts.loading) .page.appWindow() - .waitForFrameLoad('@appFrame', browser.globals.timeouts.basic); + .waitForFrameLoad('@appFrame', browser.globals.timeouts.loading); }; module.exports = InstallWebsite; \ No newline at end of file diff --git a/Website/test/e2e/globals.js b/Website/test/e2e/globals.js index a7e13104a9..f40f67ee0c 100644 --- a/Website/test/e2e/globals.js +++ b/Website/test/e2e/globals.js @@ -2,6 +2,7 @@ var timeouts = { basic: 10000, save: 120000, little: 1000, + loading: 25000, }; var setupOptions = { diff --git a/nightwatch.json b/nightwatch.json index cdfe958b35..256722e46e 100644 --- a/nightwatch.json +++ b/nightwatch.json @@ -52,7 +52,9 @@ "sql": { "exclude" : ["Website/test/e2e/suite/000_setup/installSite.js", - "Website/test/e2e/suite/010_setupPackages/installVerboseLoggingPackage.js"] + "Website/test/e2e/suite/010_setupPackages/installVerboseLoggingPackage.js", + "Website/test/e2e/suite/packages", + "Website/test/e2e/suite/zzz_starterSites"] }, "firefox" : { From 94ad8ab66873892027a8fc3335043e9ca45ad600 Mon Sep 17 00:00:00 2001 From: Vitalii Vysotskyi Date: Tue, 8 Nov 2016 13:24:24 +0200 Subject: [PATCH 015/135] Creating global data types (WIP) 1. Command: + /logOut.js 2. Test: + /data/CreateGlobalDataTypes.js 3. Notepad++ API: +logOut --- .../e2e/ApiLang/Notepad++/Nightwatch.UDL.xml | 2 +- .../test/e2e/ApiLang/Notepad++/nightwatch.xml | 5 + Website/test/e2e/commands/logOut.js | 17 +++ .../e2e/suite/data/CreateGlobalDataTypes.js | 129 ++++++++++++++++++ 4 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 Website/test/e2e/commands/logOut.js create mode 100644 Website/test/e2e/suite/data/CreateGlobalDataTypes.js diff --git a/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml b/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml index df03ad54bb..d7e3b48d21 100644 --- a/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml +++ b/Website/test/e2e/ApiLang/Notepad++/Nightwatch.UDL.xml @@ -24,7 +24,7 @@ - assertBrowserContainsAttribute assertBrowserContains assertFieldValue assertTreeNodeHasChild assertTreeNodeIsEmpty assertTreeNodeIsNotEmpty clickDataBySibilings clickDialogButton clickInFrame clickLabel clickSave replaceTextInCodeMirror selectEditOnContent clickText closeDocumentTab changeElementContent doubleClickSelector enterFrame leaveFrame openTreeNode replaceContent rightClickSelector selectActionFromToolbar selectContentTab selectDialog selectDocumentTab selectFrame selectFrameWithXpath selectPerspective selectTreeNodeAction setFieldValueInFieldGroup setFieldValue setFileFieldValue switchContentTab topFrame waitForFrameLoad acceptChanges acceptFunctionEdit assertTreeNodeHasNoChild submitFormData installPackage uninstallPackage installCommercialPackage installLocalPackage uninstallLocalPackage installLocale uninstallLocale installWebsite + assertBrowserContainsAttribute assertBrowserContains assertFieldValue assertTreeNodeHasChild assertTreeNodeIsEmpty assertTreeNodeIsNotEmpty clickDataBySibilings clickDialogButton clickInFrame clickLabel clickSave replaceTextInCodeMirror selectEditOnContent clickText closeDocumentTab changeElementContent doubleClickSelector enterFrame leaveFrame openTreeNode replaceContent rightClickSelector selectActionFromToolbar selectContentTab selectDialog selectDocumentTab selectFrame selectFrameWithXpath selectPerspective selectTreeNodeAction setFieldValueInFieldGroup setFieldValue setFileFieldValue switchContentTab topFrame waitForFrameLoad acceptChanges acceptFunctionEdit assertTreeNodeHasNoChild submitFormData installPackage uninstallPackage installCommercialPackage installLocalPackage uninstallLocalPackage installLocale uninstallLocale installWebsite logOut browser editor2 editor beforeEach afterEach done diff --git a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml index 4da146be0a..3524891948 100644 --- a/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml +++ b/Website/test/e2e/ApiLang/Notepad++/nightwatch.xml @@ -273,6 +273,11 @@ + + + + + \ No newline at end of file diff --git a/Website/test/e2e/commands/logOut.js b/Website/test/e2e/commands/logOut.js new file mode 100644 index 0000000000..f82be18b13 --- /dev/null +++ b/Website/test/e2e/commands/logOut.js @@ -0,0 +1,17 @@ +var events = require('events'); + +function LogOut() { + events.EventEmitter.call(this); +} + +LogOut.prototype.command = function (userName) { + + this.client.api + .clickLabel(userName) + .clickLabel("Sign out") + .waitForElementVisible('#id_username', this.client.api.globals.timeouts.basic); + + return this.client.api; +}; + +module.exports = LogOut; diff --git a/Website/test/e2e/suite/data/CreateGlobalDataTypes.js b/Website/test/e2e/suite/data/CreateGlobalDataTypes.js new file mode 100644 index 0000000000..bf6018e386 --- /dev/null +++ b/Website/test/e2e/suite/data/CreateGlobalDataTypes.js @@ -0,0 +1,129 @@ +module.exports = { + '@tags': ['create-data-types'], + beforeEach: function (browser) { + browser.url(browser.launchUrl + '/Composite/top.aspx'); + var content = browser.page.content(); + content + .prepare("Content"); + }, + + 'Create Parent Global Data Type': function (browser) { + + // create a parent global data type + browser + .selectPerspective("Data") + .selectTreeNodeAction("Global Datatypes", "Add Datatype") + .selectDocumentTab("New Datatype") + .setFieldValue("Title", "Parents") + .setFieldValue("Type namespace", "Auto.Tests") + .setFieldValue("Type name", "Parent") + .selectContentTab("Fields") + .clickLabel("Add New") + .clickSave() + .closeDocumentTab("Parents") + .assertTreeNodeHasChild("Global Datatypes","Auto.Tests.Parent") + + browser + .logOut("admin") + }, + + 'Add data items': function (browser) { + + browser + .selectPerspective("Data") + .selectTreeNodeAction("Auto.Tests.Parent", "Add Data") + .selectDocumentTab("Parent") + .setFieldValue("MyStringField", "Parent A") + .setFieldValue("MyIntField", "100") + .setFieldValue("MyDateTimeField", "12/31/2016") + .setFieldValue("NewField", "Some text 1") + .clickSave() + .closeDocumentTab("Parent") + .openTreeNode("Auto.Tests.Parent") + .assertTreeNodeHasChild("Auto.Tests.Parent","Parent A") + + .selectTreeNodeAction("Auto.Tests.Parent", "Add Data") + .selectDocumentTab("Parent") + .setFieldValue("MyStringField", "Parent B") + .setFieldValue("MyIntField", "1000") + .setFieldValue("MyDateTimeField", "12/31/2018") + .setFieldValue("NewField", "Some text 2") + .clickSave() + .closeDocumentTab("Parent") + .openTreeNode("Auto.Tests.Parent") + .assertTreeNodeHasChild("Auto.Tests.Parent","Parent B") + + .selectTreeNodeAction("Auto.Tests.Parent", "Add Data") + .selectDocumentTab("Parent") + .setFieldValue("MyStringField", "Parent C") + .setFieldValue("MyIntField", "10000") + .setFieldValue("MyDateTimeField", "12/31/2020") + .setFieldValue("NewField", "Some text 3") + .clickSave() + .closeDocumentTab("Parent") + .openTreeNode("Auto.Tests.Parent") + .assertTreeNodeHasChild("Auto.Tests.Parent","Parent C") + + browser + .logOut("admin") + }, + + 'Duplicate data items': function (browser) { + + browser + .selectPerspective("Data") + .openTreeNode("Auto.Tests.Parent") + .selectTreeNodeAction("Parent B", "Duplicate Data") + .assertTreeNodeHasChild("Auto.Tests.Parent", "Copy of Parent B") + + browser + .logOut("admin") + }, + + 'Delete data items': function (browser) { + + browser + .selectPerspective("Data") + .openTreeNode("Auto.Tests.Parent") + .selectTreeNodeAction("Parent B", "Delete Data") + .clickDialogButton("OK") + .assertTreeNodeHasNoChild("Auto.Tests.Parent", "Parent B") + + browser + .logOut("admin") + }, + + 'Edit data items': function (browser) { + + browser + .selectPerspective("Data") + .openTreeNode("Auto.Tests.Parent") + .selectTreeNodeAction("Copy of Parent B", "Edit Data") + .selectDocumentTab("Copy of Parent B") + .setFieldValue("MyStringField", "Parent B new") + .setFieldValue("MyIntField", "99") + .setFieldValue("MyDateTimeField", "01/01/2017") + .setFieldValue("NewField", "New text 1 edited") + .clickSave() + .closeDocumentTab("Copy of Parent B") + .openTreeNode("Auto.Tests.Parent") + .assertTreeNodeHasChild("Auto.Tests.Parent","Parent B new") + + browser + .logOut("admin") + }, + + 'Delete Parent Global Data Type': function (browser) { + + browser + .selectPerspective("Data") + .selectTreeNodeAction("Auto.Tests.Parent","Delete Datatype") + .clickDialogButton("OK") + .assertTreeNodeHasNoChild("Auto.Tests.Parent") + }, + + afterEach: function (browser, done) { + done(); + } +} + From 5d80fa7744a4ffcd630ac3fce8522be2d84a352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pauli=20=C3=98ster=C3=B8?= Date: Thu, 10 Nov 2016 16:09:42 -0300 Subject: [PATCH 016/135] Created a IMailer service which acts a abstraction for sending emails. Added a default implementation which sends emails using the SmtpClient. --- Composite/Composite.csproj | 2 ++ Composite/Core/IMailer.cs | 24 +++++++++++++++++++ Composite/Core/SmtpMailer.cs | 24 +++++++++++++++++++ .../ApplicationLevelEventHandlers.cs | 8 +++++-- .../Mail/SendMailFunction.cs | 9 +++++-- 5 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 Composite/Core/IMailer.cs create mode 100644 Composite/Core/SmtpMailer.cs diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 193ea68102..acd8a89818 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -174,6 +174,8 @@ + + diff --git a/Composite/Core/IMailer.cs b/Composite/Core/IMailer.cs new file mode 100644 index 0000000000..39fe24bfa6 --- /dev/null +++ b/Composite/Core/IMailer.cs @@ -0,0 +1,24 @@ +ï»żusing System.Net.Mail; +using System.Threading.Tasks; + +namespace Composite.Core +{ + /// + /// A contract for sending email messages. + /// + public interface IMailer + { + /// + /// Sends the specified + /// + /// The message to send + void Send(MailMessage message); + + /// + /// Sends the specified an asynchronous operation. + /// + /// The message to send + /// The task object representing the asynchronous operation. + Task SendAsync(MailMessage message); + } +} diff --git a/Composite/Core/SmtpMailer.cs b/Composite/Core/SmtpMailer.cs new file mode 100644 index 0000000000..67784e6fb9 --- /dev/null +++ b/Composite/Core/SmtpMailer.cs @@ -0,0 +1,24 @@ +ï»żusing System.Net.Mail; +using System.Threading.Tasks; + +namespace Composite.Core +{ + internal class SmtpMailer : IMailer + { + public void Send(MailMessage message) + { + using (var client = new SmtpClient()) + { + client.Send(message); + } + } + + public async Task SendAsync(MailMessage message) + { + using (var client = new SmtpClient()) + { + await client.SendMailAsync(message); + } + } + } +} diff --git a/Composite/Core/WebClient/ApplicationLevelEventHandlers.cs b/Composite/Core/WebClient/ApplicationLevelEventHandlers.cs index f2afaf8f1c..e2d2142adf 100644 --- a/Composite/Core/WebClient/ApplicationLevelEventHandlers.cs +++ b/Composite/Core/WebClient/ApplicationLevelEventHandlers.cs @@ -19,6 +19,7 @@ using Composite.Functions; using Composite.Plugins.Elements.UrlToEntityToken; using Composite.Plugins.Routing.InternalUrlConverters; +using Microsoft.Extensions.DependencyInjection; namespace Composite.Core.WebClient @@ -91,17 +92,20 @@ private static void InitializeServices() UrlToEntityTokenFacade.Register(new DataUrlToEntityTokenMapper()); UrlToEntityTokenFacade.Register(new ServerLogUrlToEntityTokenMapper()); - RoutedData.ConfigureServices(ServiceLocator.ServiceCollection); + var services = ServiceLocator.ServiceCollection; + RoutedData.ConfigureServices(services); using (new LogExecutionTime(_verboseLogEntryTitle, "Initializing dynamic data action tokens")) { - DataActionTokenResolverRegistry.Register(ServiceLocator.ServiceCollection); + DataActionTokenResolverRegistry.Register(services); } InternalUrls.Register(new MediaInternalUrlConverter()); InternalUrls.Register(new PageInternalUrlConverter()); + services.AddSingleton(new SmtpMailer()); + VersionedDataHelper.Initialize(); } diff --git a/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs b/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs index 62cd576c76..dabd13c454 100644 --- a/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs +++ b/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Net.Mail; using System.Web; +using Composite.Core; +using Composite.Core.Application; using Composite.Core.Extensions; using Composite.Core.IO; using Composite.Core.Logging; @@ -11,6 +13,7 @@ using Composite.Data.Types; using Composite.Functions; using Composite.Plugins.Functions.FunctionProviders.StandardFunctionProvider.Foundation; +using Microsoft.Extensions.DependencyInjection; namespace Composite.Plugins.Functions.FunctionProviders.StandardFunctionProvider.Mail { @@ -112,8 +115,10 @@ public static bool SendMail(string subject, string body, bool isHtml, string fro } - SmtpClient client = new SmtpClient(); - client.Send(mailMessage); + + var mailer = ServiceLocator.ApplicationServices.GetService(); + + mailer.Send(mailMessage); return true; } From b856f1e94e27791823aced66bea2d48228af64ca Mon Sep 17 00:00:00 2001 From: wwwysocki Date: Fri, 3 Feb 2017 12:21:45 +0200 Subject: [PATCH 017/135] Added info on installing chromedriver and robocopy --- Website/test/e2e/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Website/test/e2e/README.md b/Website/test/e2e/README.md index ed2da419f0..53367be644 100644 --- a/Website/test/e2e/README.md +++ b/Website/test/e2e/README.md @@ -14,6 +14,16 @@ The next step is installing nightwatch itself. This is done by issuing the comma Nightwatch expects to find the CMS running on localhost, port 8080. You can either change your Visual Studio or WebMatrix/IIS setup to use this port, or edit the `nightwatch.json` configuration file found in the project root. You can edit the line that says `"launch_url" : "http://localhost:8080"` to reflect the URL used. +You may need to consider installing the latest: + +* chromedriver (if running tests in Chrome) +* robocopy (used for reseting the website and installing various Starter Site options) + +Go to /Website and run these commands there: + +* `npm install --save-dev chromedriver@latest` +* `npm install --save-dev robocopy@latest` + Finally, navigate to the root directory of your CMS working copy. This will usually be named `CMS`, but you may have named it otherwise when cloning it. In this directory, you can then start the tests by running `nightwatch` from your command line. This will run the whole test suite, starting with installing the Venus starter site. Due to certain technical limitations, nightwatch must always be run from the working directory, and cannot be run from any subdirectory. From fcf5695e5e89af53ae1220574898aeb84a1a2386 Mon Sep 17 00:00:00 2001 From: wwwysocki Date: Fri, 3 Feb 2017 12:43:41 +0200 Subject: [PATCH 018/135] Updated "Tests" to "Components" --- Website/test/e2e/suite/content/browseTree.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Website/test/e2e/suite/content/browseTree.js b/Website/test/e2e/suite/content/browseTree.js index fac12604c3..db25ccf0ce 100644 --- a/Website/test/e2e/suite/content/browseTree.js +++ b/Website/test/e2e/suite/content/browseTree.js @@ -25,14 +25,14 @@ module.exports = { systemView.openTreeNode('Getting Started'); // Child pages appear below the page. systemView.assertTreeNodeHasChild('Getting Started'); - // 6 Locate the “Tests” page. The page is present below “Getting Started”. - systemView.assertTreeNodeHasChild('Getting Started', 'Tests'); - // 7 Select the “Tests” page The “Test” page gets selected in the tree. - systemView.openTreeNode('Tests') - // The “Test” page’s content loads in the browser view. + // 6 Locate the “Components” page. The page is present below “Getting Started”. + systemView.assertTreeNodeHasChild('Getting Started', 'Components'); + // 7 Select the “Components” page The “Test” page gets selected in the tree. + systemView.openTreeNode('Components') + // The “Components” page’s content loads in the browser view. content - .assertBrowserContains('div.content-column > h1', 'Test the design') - // The URL in the address bar reads “http:///Getting-Started/Tests/c1mode(unpublished) - .assertBrowserUrl('/Getting-Started/Tests/c1mode(unpublished)') + .assertBrowserContains('div.content-column > h1', 'Test components') + // The URL in the address bar reads “http:///Getting-Started/components/c1mode(unpublished) + .assertBrowserUrl('/Getting-Started/components/c1mode(unpublished)') } }; From 3beb43edce871ce32ee44f307e6c0bcb71ec3ba1 Mon Sep 17 00:00:00 2001 From: wwwysocki Date: Fri, 3 Feb 2017 15:22:28 +0200 Subject: [PATCH 019/135] Update multiEditor.js --- Website/test/e2e/suite/content/multiEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/test/e2e/suite/content/multiEditor.js b/Website/test/e2e/suite/content/multiEditor.js index 9776d2e79d..fa6d82ce35 100644 --- a/Website/test/e2e/suite/content/multiEditor.js +++ b/Website/test/e2e/suite/content/multiEditor.js @@ -12,7 +12,7 @@ module.exports = { .selectTreeNodeAction("Venus Starter Site", "Edit Page") .page.editor() .selectEditOnContent(1) - .clickDataBySibilings("Statement content") + .clickDataBySibilings("Content") .changeElementContent('h1 > em', 'Jupiter') .acceptChanges() .clickDataBySibilings("Background Image") From 49abeffa5b142b474817009ae568b441fffacf0c Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Wed, 8 Feb 2017 17:21:48 +0100 Subject: [PATCH 020/135] Aligning colors on login/loading splash --- README.md | 2 +- Website/Composite/images/Orckestra-Black.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 14bcbaa17b..04d777e4c8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Visit http://docs.cms.orckestra.com/Getting-started/Guide Download binaries from https://github.com/Orckestra/CMS-Foundation/releases/latest ## Forums ## -Head over to https://orckestracms.codeplex.com/discussions to ask questions +Head over to https://gitter.im/Orckestra/C1-CMS or https://orckestracms.codeplex.com/discussions to ask questions ## Who are we? ## Orckestra is the company driving the development of C1 CMS Foundation. We have a team working full time on this CMS and on other cool stuff you can add to it. We are situated in Austin, Montreal, Copenhagen and Kiev. We specialize in enterprise commerce software. diff --git a/Website/Composite/images/Orckestra-Black.svg b/Website/Composite/images/Orckestra-Black.svg index 7689c6cfd6..346c88d089 100644 --- a/Website/Composite/images/Orckestra-Black.svg +++ b/Website/Composite/images/Orckestra-Black.svg @@ -1,7 +1,7 @@ - - - - - - - - - - + + + + + + + + + + + From a53c37cfea35d9618826ab230c4a5d5871e397c2 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 10 Feb 2017 16:05:40 +0100 Subject: [PATCH 022/135] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14bcbaa17b..f079136613 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,4 @@ Head over to https://orckestracms.codeplex.com/discussions to ask questions ## Who are we? ## Orckestra is the company driving the development of C1 CMS Foundation. We have a team working full time on this CMS and on other cool stuff you can add to it. We are situated in Austin, Montreal, Copenhagen and Kiev. We specialize in enterprise commerce software. -You can visit us at http://cms.orckestra.com and http://www.orckestra.com/ +You can visit us at http://c1.orckestra.com and http://www.orckestra.com/ From d8b73366a634e3d8f8f68ba966ac5d6abd49cb96 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 14 Feb 2017 11:55:20 +0100 Subject: [PATCH 023/135] DataEntityToken - refactoring + performance optimization --- Composite/C1Console/Security/EntityToken.cs | 41 +++++++++--------- Composite/Data/DataEntityToken.cs | 47 ++++++++------------- 2 files changed, 37 insertions(+), 51 deletions(-) diff --git a/Composite/C1Console/Security/EntityToken.cs b/Composite/C1Console/Security/EntityToken.cs index 274715c57a..e1a1a14a29 100644 --- a/Composite/C1Console/Security/EntityToken.cs +++ b/Composite/C1Console/Security/EntityToken.cs @@ -18,7 +18,6 @@ public object Deserialize(string serializedObject) { return EntityTokenSerializer.Deserialize(serializedObject); } - } @@ -29,7 +28,7 @@ public object Deserialize(string serializedObject) /// EntityToken is used through out C1 CMS to describe artifacts that can have security settings. Also see . /// /// - /// When subclassing this class and adding properties that have an impack when identity (equiallity) + /// When subclassing this class and adding properties that have an impact when identity (equality) /// of the subclass, remember to overload Equal and GetHashCode! /// [DebuggerDisplay("Type = {Type}, Source = {Source}, Id = {Id}")] @@ -62,7 +61,7 @@ public abstract class EntityToken /// The state of the EntityToken. Invalid entity tokens will be automatically removed from the system. /// /// The state of the EntityToken. - public virtual bool IsValid() { return true; } + public virtual bool IsValid() => true; /// @@ -110,11 +109,11 @@ protected static void DoDeserialize(string serializedEntityToken, out string typ { dic = StringConversionServices.ParseKeyValueCollection(serializedEntityToken); - if ((dic.ContainsKey("_EntityToken_Type_") == false) || - (dic.ContainsKey("_EntityToken_Source_") == false) || - (dic.ContainsKey("_EntityToken_Id_") == false)) + if (!dic.ContainsKey("_EntityToken_Type_") || + !dic.ContainsKey("_EntityToken_Source_") || + !dic.ContainsKey("_EntityToken_Id_")) { - throw new ArgumentException("The serializedEntityToken is not a serialized entity token", "serializedEntityToken"); + throw new ArgumentException("Is not a serialized entity token", nameof(serializedEntityToken)); } type = StringConversionServices.DeserializeValueString(dic["_EntityToken_Type_"]); @@ -142,16 +141,16 @@ public virtual string GetPrettyHtml(Dictionary piggybag) /// - public virtual string OnGetTypePrettyHtml() { return this.Type; } + public virtual string OnGetTypePrettyHtml() => this.Type; /// - public virtual string OnGetSourcePrettyHtml() { return this.Source; } + public virtual string OnGetSourcePrettyHtml() => this.Source; /// - public virtual string OnGetIdPrettyHtml() { return this.Id; } + public virtual string OnGetIdPrettyHtml() => this.Id; /// - public virtual string OnGetExtraPrettyHtml() { return null; } + public virtual string OnGetExtraPrettyHtml() => null; /// @@ -174,23 +173,21 @@ public override bool Equals(object obj) /// public bool EqualsWithVersionIgnore(object obj) { - EntityToken entityToken = obj as EntityToken; + var entityToken = obj as EntityToken; if (entityToken == null) return false; - ValidateEntityToken(); - if (entityToken.GetHashCode() != GetHashCode()) return false; - - return entityToken.Id == this.Id && + return entityToken.GetHashCode() == GetHashCode() && + entityToken.Id == this.Id && entityToken.Type == this.Type && entityToken.Source == this.Source && entityToken.GetType() == this.GetType(); } /// - public virtual string VersionId { get; } = ""; + public virtual string VersionId { get; } = ""; /// @@ -229,7 +226,7 @@ public int GetVersionHashCode() /// public override string ToString() { - return string.Format("Source = {0}, Type = {1}, Id = {2}", this.Source, this.Type, this.Id); + return $"Source = {this.Source}, Type = {this.Type}, Id = {this.Id}"; } @@ -240,9 +237,9 @@ private void ValidateEntityToken() _entityTokenUniquenessValidated = true; - if ((string.IsNullOrEmpty(this.Type)) && - (string.IsNullOrEmpty(this.Source)) && - (string.IsNullOrEmpty(this.Id))) + if (string.IsNullOrEmpty(this.Type) && + string.IsNullOrEmpty(this.Source) && + string.IsNullOrEmpty(this.Id)) { ThrowNotUniqueException(); } @@ -250,7 +247,7 @@ private void ValidateEntityToken() private void ThrowNotUniqueException() { - throw new InvalidOperationException(string.Format("EntityTokens should be unique for the given element. The properties Type, Source and Id may not all be empty string. This is not the case for this type {0}", GetType())); + throw new InvalidOperationException($"EntityTokens should be unique for the given element. The properties Type, Source and Id may not all be empty string. This is not the case for this type {GetType()}"); } } } diff --git a/Composite/Data/DataEntityToken.cs b/Composite/Data/DataEntityToken.cs index e719210840..6ce50d1e24 100644 --- a/Composite/Data/DataEntityToken.cs +++ b/Composite/Data/DataEntityToken.cs @@ -78,11 +78,7 @@ public override string Type public override string VersionId => this.SerializedVersionId; /// - public override bool IsValid() - { - return this.Data != null; - } - + public override bool IsValid() => this.Data != null; /// @@ -92,14 +88,9 @@ public Type InterfaceType { if (_interfaceType == null) { - if (_dataSourceId != null) - { - _interfaceType = _dataSourceId.InterfaceType; - } - else - { - _interfaceType = TypeManager.TryGetType(this.Type); - } + _interfaceType = _dataSourceId != null + ? _dataSourceId.InterfaceType + : TypeManager.TryGetType(this.Type); } return _interfaceType; @@ -180,9 +171,10 @@ public override void OnGetPrettyHtml(EntityTokenHtmlPrettyfier prettifier) { IDataId dataId = DataIdSerializer.Deserialize(this.Id, this.VersionId); - var sb = new StringBuilder(); - sb.Append("DataId
"); - sb.Append("Type: " + dataId.GetType() + "
"); + var sb = new StringBuilder() + .Append("DataId
") + .Append($"Type: {dataId.GetType()}
"); + foreach (PropertyInfo propertyInfo in dataId.GetType().GetPropertiesRecursively()) { sb.Append("" + propertyInfo.Name + ": " + propertyInfo.GetValue(dataId, null).ToString() + "
"); @@ -215,14 +207,7 @@ private string SerializedId { if (_serializedId == null) { - if (!GetVersionKeyPropertyNames().Any()) - { - return this.DataSourceId.DataId.Serialize(null); - } - - var keyPropertyNames = this.InterfaceType - .GetCustomAttributesRecursively() - .Select(f=>f.KeyPropertyName); + var keyPropertyNames = GetVersionKeyPropertyNames().Any() ? GetKeyPropertyNames() : null; _serializedId = this.DataSourceId.DataId.Serialize(keyPropertyNames); } @@ -238,18 +223,22 @@ private string SerializedVersionId if (_serializedVersionId == null) { var versionKeyPropertyNames = GetVersionKeyPropertyNames(); - if (!versionKeyPropertyNames.Any()) - { - return ""; - } - _serializedVersionId = this.DataSourceId.DataId.Serialize(versionKeyPropertyNames); + _serializedVersionId = versionKeyPropertyNames.Any() + ? this.DataSourceId.DataId.Serialize(versionKeyPropertyNames) + : string.Empty; } return _serializedVersionId; } } + private IEnumerable GetKeyPropertyNames() + { + return this.InterfaceType.GetCustomAttributesRecursively() + .Select(f => f.KeyPropertyName); + } + private IEnumerable GetVersionKeyPropertyNames() { From 72b143f4f0e6b67ba05567cc10da1493ce07ab40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pauli=20=C3=98ster=C3=B8?= Date: Wed, 15 Feb 2017 14:38:55 -0300 Subject: [PATCH 024/135] NuGet packages - Removed redundant packages from Composite\packages.config - Consolidated library versions across projects --- Composite/packages.config | 3 --- Website/WebSite.csproj | 2 +- Website/packages.config | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Composite/packages.config b/Composite/packages.config index de85ac9352..cece090fd4 100644 --- a/Composite/packages.config +++ b/Composite/packages.config @@ -3,11 +3,8 @@ - - - diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index 2cd7ef6c15..d79b364e75 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -52,7 +52,7 @@ - ..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll + ..\packages\Castle.Core.3.3.1\lib\net45\Castle.Core.dll True diff --git a/Website/packages.config b/Website/packages.config index d5e3665524..5051521ec4 100644 --- a/Website/packages.config +++ b/Website/packages.config @@ -1,6 +1,6 @@ ï»ż - + @@ -14,7 +14,7 @@ - + From 2edd1a06ff7c9c6f6adb9cccaf958def4a0d14f4 Mon Sep 17 00:00:00 2001 From: Taras Nakonechnyi Date: Thu, 16 Feb 2017 12:59:29 +0200 Subject: [PATCH 025/135] add query icons --- .../Composite/images/icons/svg/query-group.svg | 13 +++++++++++++ .../images/icons/svg/query-perspective.svg | 10 ++++++++++ Website/Composite/images/icons/svg/query.svg | 16 ++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 Website/Composite/images/icons/svg/query-group.svg create mode 100644 Website/Composite/images/icons/svg/query-perspective.svg create mode 100644 Website/Composite/images/icons/svg/query.svg diff --git a/Website/Composite/images/icons/svg/query-group.svg b/Website/Composite/images/icons/svg/query-group.svg new file mode 100644 index 0000000000..4ce011b33c --- /dev/null +++ b/Website/Composite/images/icons/svg/query-group.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Website/Composite/images/icons/svg/query-perspective.svg b/Website/Composite/images/icons/svg/query-perspective.svg new file mode 100644 index 0000000000..c4177936b6 --- /dev/null +++ b/Website/Composite/images/icons/svg/query-perspective.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Website/Composite/images/icons/svg/query.svg b/Website/Composite/images/icons/svg/query.svg new file mode 100644 index 0000000000..f845ebd262 --- /dev/null +++ b/Website/Composite/images/icons/svg/query.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From a9966b9c1f210711e8b9c0db6aaa5a43fd7cc3de Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 16 Feb 2017 12:05:55 +0100 Subject: [PATCH 026/135] Fixing a deadlock between TreeFacade and TreeSharedRootsFacade, refactoring --- Composite/C1Console/Trees/TreeFacadeImpl.cs | 39 +++++---- .../C1Console/Trees/TreeSharedRootsFacade.cs | 79 ++++++++----------- 2 files changed, 54 insertions(+), 64 deletions(-) diff --git a/Composite/C1Console/Trees/TreeFacadeImpl.cs b/Composite/C1Console/Trees/TreeFacadeImpl.cs index 71c3b775b9..9d94b7e9e3 100644 --- a/Composite/C1Console/Trees/TreeFacadeImpl.cs +++ b/Composite/C1Console/Trees/TreeFacadeImpl.cs @@ -51,22 +51,30 @@ public void Initialize() { using (_resourceLocker.Locker) { + var resources = _resourceLocker.Resources; + if (!GlobalInitializerFacade.IsReinitializingTheSystem) { - DataEventSystemFacade.SubscribeToDataAfterAdd(OnUpdateTreeAttachmentPoints, true); - DataEventSystemFacade.SubscribeToDataDeleted(OnUpdateTreeAttachmentPoints, true); - DataEventSystemFacade.SubscribeToStoreChanged(OnTreeAttachmentPointsStoreChange, true); + DataEvents.OnAfterAdd += OnUpdateTreeAttachmentPoints; + DataEvents.OnDeleted += OnUpdateTreeAttachmentPoints; + DataEvents.OnStoreChanged += OnTreeAttachmentPointsStoreChange; GeneratedTypesFacade.SubscribeToUpdateTypeEvent(OnDataTypeChanged); - var treeAuxiliaryAncestorProvider = new C1Console.Trees.TreeAuxiliaryAncestorProvider(); - AuxiliarySecurityAncestorFacade.AddAuxiliaryAncestorProvider(treeAuxiliaryAncestorProvider, true); - AuxiliarySecurityAncestorFacade.AddAuxiliaryAncestorProvider(treeAuxiliaryAncestorProvider, true); - AuxiliarySecurityAncestorFacade.AddAuxiliaryAncestorProvider(treeAuxiliaryAncestorProvider, true); - AuxiliarySecurityAncestorFacade.AddAuxiliaryAncestorProvider(treeAuxiliaryAncestorProvider, true); - AuxiliarySecurityAncestorFacade.AddAuxiliaryAncestorProvider(treeAuxiliaryAncestorProvider, true); + var treeAuxiliaryAncestorProvider = new TreeAuxiliaryAncestorProvider(); + var entityTokenTypes = new[] + { + typeof (TreeSimpleElementEntityToken), + typeof (TreeFunctionElementGeneratorEntityToken), + typeof (TreeDataFieldGroupingElementEntityToken), + typeof (DataEntityToken), + typeof (TreePerspectiveEntityToken) + }; - _resourceLocker.Resources.PersistentAttachmentPoints = new Dictionary>(); + entityTokenTypes.ForEach(type => AuxiliarySecurityAncestorFacade + .AddAuxiliaryAncestorProvider(type, treeAuxiliaryAncestorProvider, true)); + + resources.PersistentAttachmentPoints = new Dictionary>(); LoadAllTrees(); InitializeTreeAttachmentPoints(); @@ -79,10 +87,9 @@ public void Initialize() fileWatcher.Renamed += OnReloadTrees; fileWatcher.EnableRaisingEvents = true; - _resourceLocker.Resources.FileSystemWatcher = fileWatcher; - + resources.FileSystemWatcher = fileWatcher; - _resourceLocker.Resources.RootEntityToken = ElementFacade.GetRootsWithNoSecurity().First().ElementHandle.EntityToken; + resources.RootEntityToken = ElementFacade.GetRootsWithNoSecurity().First().ElementHandle.EntityToken; } } } @@ -267,8 +274,8 @@ private void LoadAllTrees() var sb = new StringBuilder(); foreach (ValidationError validationError in tree.BuildResult.ValidationErrors) { - sb.AppendLine(string.Format("{0} at {1}", validationError.Message, validationError.XPath)); - Log.LogError("TreeFacade", string.Format("{0} at {1} in {2}", validationError.Message, validationError.XPath, filename)); + sb.AppendLine($"{validationError.Message} at {validationError.XPath}"); + Log.LogError("TreeFacade", $"{validationError.Message} at {validationError.XPath} in {filename}"); } //Tree errorTree = CreateErrorTree(treeId, sb.ToString()); @@ -494,7 +501,7 @@ public bool RemovePersistedAttachmentPoint(string treeId, Type interfaceType, ob /// /// This will add a attachment point until the system flushes. - /// This can be used by element provider implementors to attach trees to their exising trees. + /// This can be used by element provider implementors to attach trees to their existing trees. /// /// /// diff --git a/Composite/C1Console/Trees/TreeSharedRootsFacade.cs b/Composite/C1Console/Trees/TreeSharedRootsFacade.cs index 65eb96ec1a..707c4441bb 100644 --- a/Composite/C1Console/Trees/TreeSharedRootsFacade.cs +++ b/Composite/C1Console/Trees/TreeSharedRootsFacade.cs @@ -1,10 +1,8 @@ -ï»żusing System; -using System.Collections.Generic; +ï»żusing System.Collections.Generic; using System.Linq; using Composite.C1Console.Elements; using Composite.C1Console.Elements.Foundation; using Composite.C1Console.Elements.Foundation.PluginFacades; -using Composite.C1Console.Elements.Plugins.ElementAttachingProvider; using Composite.C1Console.Security; using Composite.C1Console.Trees.Foundation; using Composite.C1Console.Trees.Foundation.AttachmentPoints; @@ -24,81 +22,66 @@ internal class CustomTreePerspectiveInfo internal static class TreeSharedRootsFacade { - private volatile static Dictionary _sharedRootFolders; + private static volatile IReadOnlyDictionary _sharedRootFolders; private static string _elementAttachingProviderName; private static readonly object _lock = new object(); - public static Dictionary SharedRootFolders + public static IReadOnlyDictionary SharedRootFolders => GetSharedRootsInt(null); + + + public static void Initialize(string elementAttachingProviderName = null) + { + GetSharedRootsInt(elementAttachingProviderName); + } + + private static IReadOnlyDictionary GetSharedRootsInt(string elementAttachingProviderName) { - get + var result = _sharedRootFolders; + if (result != null) return result; + + lock (_lock) { - var result = _sharedRootFolders; + result = _sharedRootFolders; + if (result != null) return result; - if (result != null) + if (_elementAttachingProviderName == null) { - return result; + _elementAttachingProviderName = elementAttachingProviderName ?? GetElementAttachingProviderName(); } - lock (_lock) - { - Initialize(); + result = GetSharedRoots(_elementAttachingProviderName); + _sharedRootFolders = result; - return _sharedRootFolders; - } + return result; } } - public static void Initialize(string elementAttachingProviderName = null) + private static string GetElementAttachingProviderName() { - if (_sharedRootFolders != null) return; - - lock (_lock) + foreach (string providerName in ElementAttachingProviderRegistry.ElementAttachingProviderNames) { - if (_sharedRootFolders != null) return; - - if (_elementAttachingProviderName == null) + var provider = ElementAttachingProviderPluginFacade.GetElementAttachingProvider(providerName); + if (provider is TreeElementAttachingProvider) { - if (elementAttachingProviderName == null) - { - foreach (string providerName in ElementAttachingProviderRegistry.ElementAttachingProviderNames) - { - IElementAttachingProvider elementAttachingProvider = ElementAttachingProviderPluginFacade.GetElementAttachingProvider(providerName); - if (elementAttachingProvider is TreeElementAttachingProvider) - { - _elementAttachingProviderName = providerName; - break; - } - } - } - else - { - _elementAttachingProviderName = elementAttachingProviderName; - } + return providerName; } - - DoInitialize(_elementAttachingProviderName); } + return null; } public static void Clear() { - lock (_lock) - { - _sharedRootFolders = null; - } + _sharedRootFolders = null; } - private static void DoInitialize(string elementAttachingProviderName) + private static IReadOnlyDictionary GetSharedRoots(string elementAttachingProviderName) { var sharedRootFolders = new Dictionary(); - var treeNodeDynamicContext = new TreeNodeDynamicContext(TreeNodeDynamicContextDirection.Down); - treeNodeDynamicContext.Piggybag = new Dictionary(); - foreach (var tree in TreeFacade.AllTrees) { if (!tree.ShareRootElementById) continue; @@ -161,7 +144,7 @@ private static void DoInitialize(string elementAttachingProviderName) tree.RootTreeNode = childTreeNode; } - _sharedRootFolders = sharedRootFolders; + return sharedRootFolders; } } } From 080a73b6d246bbff3cad9c166dd64aded938f9d5 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Thu, 16 Feb 2017 15:07:37 +0100 Subject: [PATCH 027/135] remove unused references from packages.config --- Composite/packages.config | 3 --- 1 file changed, 3 deletions(-) diff --git a/Composite/packages.config b/Composite/packages.config index de85ac9352..cece090fd4 100644 --- a/Composite/packages.config +++ b/Composite/packages.config @@ -3,11 +3,8 @@ - - - From 8877ccd84ef63dbd09aa00f0898e595cd420b921 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 17 Feb 2017 17:17:55 +0100 Subject: [PATCH 028/135] Performance optimizations in relation to search index building time, refactoring --- Composite/Core/Types/TypeExtensionMethods.cs | 2 +- .../GeneratedTypesFacadeImpl.cs | 6 +- Composite/Data/PageMetaDataFacade.cs | 76 ++++++++----------- .../Types/MediaFileDataAncesorProvider.cs | 36 ++++----- .../Search/Crawling/XhtmlCrawlingHelper.cs | 6 +- .../DocumentSources/CmsPageDocumentSource.cs | 68 +++++++++++++++-- 6 files changed, 118 insertions(+), 76 deletions(-) diff --git a/Composite/Core/Types/TypeExtensionMethods.cs b/Composite/Core/Types/TypeExtensionMethods.cs index c01be4c36c..9b1eb1003a 100644 --- a/Composite/Core/Types/TypeExtensionMethods.cs +++ b/Composite/Core/Types/TypeExtensionMethods.cs @@ -86,7 +86,7 @@ public static List GetPropertiesRecursively(this Type type, Func

p.Name == "PageId" && p.DeclaringType == typeof (IPageData)); + properties.RemoveAll(p => p.Name == nameof (IPageData.PageId) && p.DeclaringType == typeof (IPageData)); } return properties; diff --git a/Composite/Data/GeneratedTypes/GeneratedTypesFacadeImpl.cs b/Composite/Data/GeneratedTypes/GeneratedTypesFacadeImpl.cs index c7ecb436ae..3fcc9e0b3c 100644 --- a/Composite/Data/GeneratedTypes/GeneratedTypesFacadeImpl.cs +++ b/Composite/Data/GeneratedTypes/GeneratedTypesFacadeImpl.cs @@ -134,7 +134,7 @@ private void UpdateWithNewPageFolderForeignKeySystem(DataTypeDescriptor dataType var dataTypeChangeDescriptor = new DataTypeChangeDescriptor(oldDataTypeDescriptor, dataTypeDescriptor); - UpdateDataTypeDescriptor updateDataTypeDescriptor = new UpdateDataTypeDescriptor(oldDataTypeDescriptor, dataTypeDescriptor); + var updateDataTypeDescriptor = new UpdateDataTypeDescriptor(oldDataTypeDescriptor, dataTypeDescriptor); DynamicTypeManager.AlterStore(updateDataTypeDescriptor, false); } @@ -150,8 +150,8 @@ private void UpdateWithNewMetaDataForeignKeySystem(DataTypeDescriptor dataTypeDe { if (dataTypeDescriptor.IsPageMetaDataType) { - DataFieldDescriptor dataFieldDescriptor = dataTypeDescriptor.Fields[PageMetaDataFacade.MetaDataType_MetaDataDefinitionFieldName]; - if ((dataFieldDescriptor != null) && (dataFieldDescriptor.ForeignKeyReferenceTypeName != null)) // This should never fail, but want to be sure + var dataFieldDescriptor = dataTypeDescriptor.Fields[nameof(IPageMetaData.FieldName)]; + if (dataFieldDescriptor?.ForeignKeyReferenceTypeName != null) // This should never fail, but want to be sure { dataFieldDescriptor.ForeignKeyReferenceTypeName = null; diff --git a/Composite/Data/PageMetaDataFacade.cs b/Composite/Data/PageMetaDataFacade.cs index f7d33f4f3b..a63dc6e733 100644 --- a/Composite/Data/PageMetaDataFacade.cs +++ b/Composite/Data/PageMetaDataFacade.cs @@ -28,11 +28,6 @@ public static class PageMetaDataFacade { private static readonly Guid DefaultCompositionContainerId = new Guid("eb210a75-be25-401f-b0d4-b3787bce36fa"); - internal static readonly string MetaDataType_IdFieldName = nameof(IPageMetaData.Id); - internal static readonly string MetaDataType_PageReferenceFieldName = nameof(IPageMetaData.PageId); - internal static readonly string MetaDataType_PageReferenceFieldVersionName = nameof(IPageMetaData.VersionId); - internal static readonly string MetaDataType_MetaDataDefinitionFieldName = nameof(IPageMetaData.FieldName); - ///

/// Returns all possible meta data types. This is NOT types that only have been defined on any pages or page type /// @@ -358,43 +353,33 @@ public static IData GetMetaData(Guid pageId, Guid pageVersionId, string definiti var lambdaExpression = Expression.Lambda( Expression.And( - Expression.And( - Expression.Equal( - Expression.Property( - parameterExpression, - PageMetaDataFacade.GetDefinitionNamePropertyInfo(metaDataType) + Expression.And( + Expression.Equal( + Expression.Property( + parameterExpression, + GetDefinitionPageReferencePropertyInfo(metaDataType) + ), + Expression.Constant(pageId, typeof(Guid)) ), - Expression.Constant( - definitionName, - typeof(string) + Expression.Equal( + Expression.Property( + parameterExpression, + GetDefinitionPageReferencePropertyVersionInfo(metaDataType) + ), + Expression.Constant(pageVersionId, typeof(Guid)) ) ), Expression.Equal( Expression.Property( parameterExpression, - GetDefinitionPageReferencePropertyInfo(metaDataType) + GetDefinitionNamePropertyInfo(metaDataType) ), - Expression.Constant( - pageId, - typeof(Guid) - ) - ) - ), - Expression.Equal( - Expression.Property( - parameterExpression, - GetDefinitionPageReferencePropertyVersionInfo(metaDataType) - ), - Expression.Constant( - pageVersionId, - typeof(Guid) - ) - ) - ), + Expression.Constant(definitionName, typeof(string)) + )), parameterExpression ); - Expression whereExpression = ExpressionCreator.Where(DataFacade.GetData(metaDataType).Expression, lambdaExpression); + var whereExpression = ExpressionCreator.Where(DataFacade.GetData(metaDataType).Expression, lambdaExpression); IEnumerable dataset = ExpressionHelper.GetCastedObjects(metaDataType, whereExpression); @@ -503,21 +488,24 @@ public static IEnumerable GetMetaDataAffectedPagesByPageTypeId(Guid defin /// public static bool IsDefinitionAllowed(Guid definingItemId, string name, string label, Guid metaDataTypeId) { - IEnumerable pageMetaDataDefinitions = DataFacade.GetData().Where(f => f.Name == name).Evaluate(); + var pageMetaDataDefinitions = DataFacade.GetData().Where(f => f.Name == name).Evaluate(); foreach (IPageMetaDataDefinition pageMetaDataDefinition in pageMetaDataDefinitions) { - if ((pageMetaDataDefinition.DefiningItemId == definingItemId) && - (pageMetaDataDefinition.MetaDataTypeId == metaDataTypeId) && - (pageMetaDataDefinition.Label != label) && - (pageMetaDataDefinitions.Count() == 1)) + if (pageMetaDataDefinition.DefiningItemId == definingItemId && + pageMetaDataDefinition.MetaDataTypeId == metaDataTypeId && + pageMetaDataDefinition.Label != label && + pageMetaDataDefinitions.Count() == 1) { return true; // Allow renaming of label } - if (pageMetaDataDefinition.Label != label) return false; - if (pageMetaDataDefinition.MetaDataTypeId != metaDataTypeId) return false; - if (pageMetaDataDefinition.DefiningItemId == definingItemId) return false; + if (pageMetaDataDefinition.Label != label + || pageMetaDataDefinition.MetaDataTypeId != metaDataTypeId + || pageMetaDataDefinition.DefiningItemId == definingItemId) + { + return false; + } } return true; @@ -903,7 +891,7 @@ public static void AssignMetaDataSpecificValues(IData metaData, string metaDataD { Type interfaceType = metaData.DataSourceId.InterfaceType; - PropertyInfo idPropertyInfo = interfaceType.GetPropertiesRecursively().SingleOrDefault(f => f.Name == MetaDataType_IdFieldName); + PropertyInfo idPropertyInfo = interfaceType.GetPropertiesRecursively().SingleOrDefault(f => f.Name == nameof(IPageMetaData.Id)); idPropertyInfo.SetValue(metaData, Guid.NewGuid(), null); PropertyInfo namePropertyInfo = GetDefinitionNamePropertyInfo(interfaceType); @@ -921,7 +909,7 @@ public static void AssignMetaDataSpecificValues(IData metaData, string metaDataD /// public static PropertyInfo GetDefinitionNamePropertyInfo(Type metaDataType) { - return metaDataType.GetPropertiesRecursively().Single(f => f.Name == MetaDataType_MetaDataDefinitionFieldName); + return typeof (IPageMetaData).GetProperty(nameof(IPageMetaData.FieldName)); } @@ -929,13 +917,13 @@ public static PropertyInfo GetDefinitionNamePropertyInfo(Type metaDataType) /// public static PropertyInfo GetDefinitionPageReferencePropertyInfo(Type metaDataType) { - return metaDataType.GetPropertiesRecursively().Last(f => f.Name == MetaDataType_PageReferenceFieldName); + return typeof(IPageRelatedData).GetProperty(nameof(IPageRelatedData.PageId)); } /// public static PropertyInfo GetDefinitionPageReferencePropertyVersionInfo(Type metaDataType) { - return metaDataType.GetPropertiesRecursively().Last(f => f.Name == MetaDataType_PageReferenceFieldVersionName); + return typeof(IVersioned).GetProperty(nameof(IVersioned.VersionId)); } diff --git a/Composite/Data/Types/MediaFileDataAncesorProvider.cs b/Composite/Data/Types/MediaFileDataAncesorProvider.cs index 891096647e..625d4493e1 100644 --- a/Composite/Data/Types/MediaFileDataAncesorProvider.cs +++ b/Composite/Data/Types/MediaFileDataAncesorProvider.cs @@ -1,52 +1,48 @@ ï»żusing System; -using System.Collections.Generic; using System.Linq; -using System.Text; using Composite.Data.Hierarchy; -using Composite.Data; -using Composite.Data.Types; using Composite.Core.Extensions; namespace Composite.Data.Types { internal sealed class MediaFileDataAncesorProvider : IDataAncestorProvider { - public IData GetParent(IData data) { - IData parent = null; + string parentFolderPath; + string storeId; + if (data is IMediaFile) { - IMediaFile file = (IMediaFile)data; + var file = (IMediaFile)data; - parent = (from item in DataFacade.GetData() - where item.Path == file.FolderPath && item.StoreId == file.StoreId - select item).FirstOrDefault(); - + parentFolderPath = file.FolderPath; + storeId = file.StoreId; } else if (data is IMediaFileFolder) { - IMediaFileFolder folder = (IMediaFileFolder)data; + var folder = (IMediaFileFolder) data; int lastIndex = folder.Path.LastIndexOf('/'); - if(lastIndex == 0) + if (lastIndex == 0) { return null; } - string parentPath = folder.Path.Substring(0, lastIndex); - parent = (from item in DataFacade.GetData() - where item.Path == parentPath && item.StoreId == folder.StoreId - select item).FirstOrDefault(); + parentFolderPath = folder.Path.Substring(0, lastIndex); + storeId = folder.StoreId; } else { - throw new ArgumentException("Must be either of type IMediaFile or IMediaFileFolder", "data"); + throw new ArgumentException("Must be either of type IMediaFile or IMediaFileFolder", nameof(data)); } + var queryable = DataFacade.GetData(); - return parent; + return queryable.IsEnumerableQuery() + ? queryable.AsEnumerable() + .FirstOrDefault(item => item.Path == parentFolderPath && item.StoreId == storeId) + : queryable.FirstOrDefault(item => item.Path == parentFolderPath && item.StoreId == storeId); } - } } diff --git a/Composite/Search/Crawling/XhtmlCrawlingHelper.cs b/Composite/Search/Crawling/XhtmlCrawlingHelper.cs index bd46ff3071..9f28afe146 100644 --- a/Composite/Search/Crawling/XhtmlCrawlingHelper.cs +++ b/Composite/Search/Crawling/XhtmlCrawlingHelper.cs @@ -76,8 +76,10 @@ private void ProcessFunctionCall(XElement functionNode) IFunction function; try { - function = FunctionFacade.GetFunction(functionName); - if (function == null) return; + if (!FunctionFacade.TryGetFunction(out function, functionName)) + { + return; + } } catch { diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index ba8e0c7d99..278b91d6bc 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -43,7 +43,7 @@ public CmsPageDocumentSource() { var page = (IPage) data; var entityToken = GetAdministratedEntityToken(page); - return entityToken != null ? FromPage(page, entityToken) : null; + return entityToken != null ? FromPage(page, entityToken, null) : null; }, data => GetDocumentId((IPage) data)); @@ -72,6 +72,10 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) publishedPages = conn.Get().ToDictionary(page => new Tuple(page.Id, page.VersionId)); } + var unpublishedMetaData = GetAllMetaData(PublicationScope.Unpublished, culture); + var publishedMetaData = GetAllMetaData(PublicationScope.Published, culture); + + foreach (var unpublishedPage in unpublishedPages) { var entityToken = unpublishedPage.GetDataEntityToken(); @@ -80,7 +84,7 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) if (publishedPages.TryGetValue(new Tuple(unpublishedPage.Id, unpublishedPage.VersionId), out publishedPage)) { - yield return FromPage(publishedPage, entityToken); + yield return FromPage(publishedPage, entityToken, publishedMetaData); if (unpublishedPage.PublicationStatus == GenericPublishProcessController.Published) { @@ -89,13 +93,13 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) } } - yield return FromPage(unpublishedPage, entityToken); + yield return FromPage(unpublishedPage, entityToken, unpublishedMetaData); } } public ICollection CustomFields => _customFields.Value; - private SearchDocument FromPage(IPage page, EntityToken entityToken) + private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary, List> allMetaData) { string label = page.MenuTitle; if (string.IsNullOrWhiteSpace(label)) @@ -118,10 +122,20 @@ private SearchDocument FromPage(IPage page, EntityToken entityToken) var placeholders = PageManager.GetPlaceholderContent(page.Id, page.VersionId); placeholders.ForEach(pl => documentBuilder.CrawlData(pl, true)); + List metaData; + + if (allMetaData != null) + { + allMetaData.TryGetValue(new Tuple(page.Id, page.VersionId), out metaData); + } + else + { + metaData = GetMetaData(page.Id, page.VersionId, page.DataSourceId.PublicationScope, page.DataSourceId.LocaleScope); + } + try { - page.GetMetaData() - .ForEach(pageMetaData => documentBuilder.CrawlData(pageMetaData)); + metaData?.ForEach(pageMetaData => documentBuilder.CrawlData(pageMetaData)); } catch (Exception ex) { @@ -159,5 +173,47 @@ private string GetDocumentId(IPage page) } return $"{UrlUtils.CompressGuid(page.Id)}{versionId}" + (isUnpublished ? "u" : ""); } + + private Dictionary, List> GetAllMetaData(PublicationScope publicationScope, CultureInfo culture) + { + var result = new Dictionary, List>(); + + using (var conn = new DataConnection(publicationScope, culture)) + { + conn.DisableServices(); + + foreach (var metaDataType in PageMetaDataFacade.GetAllMetaDataTypes() + .Where(type => typeof(IPageMetaData).IsAssignableFrom(type))) + { + foreach (var dataItem in DataFacade.GetData(metaDataType).OfType()) + { + var key = new Tuple(dataItem.PageId, dataItem.VersionId); + var list = result.GetOrAdd(key, () => new List()); + list.Add(dataItem); + } + } + } + + return result; + } + + private List GetMetaData(Guid pageId, Guid versionId, PublicationScope publicationScope, CultureInfo culture) + { + var result = new List(); + + using (var conn = new DataConnection(publicationScope, culture)) + { + conn.DisableServices(); + + foreach (var metaDataType in PageMetaDataFacade.GetAllMetaDataTypes() + .Where(type => typeof(IPageMetaData).IsAssignableFrom(type))) + { + result.AddRange(DataFacade.GetData(metaDataType).OfType() + .Where(md => md.PageId == pageId && md.VersionId == versionId)); + } + } + + return result; + } } } From b3933745495a6928ccc1bf9dd79df62bd0f54901 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Mon, 20 Feb 2017 11:04:10 +0100 Subject: [PATCH 029/135] Updating URLs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e6fb8cc6f8..2934e67b4e 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,13 @@ C1 CMS Foundation - a .NET based Web Content Management System, open source and [![Join the chat at https://gitter.im/Orckestra/C1-CMS](https://badges.gitter.im/Orckestra/C1-CMS.svg)](https://gitter.im/Orckestra/C1-CMS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Getting started ## -Visit http://docs.cms.orckestra.com/Getting-started/Guide +Visit http://docs.c1.orckestra.com/Getting-started/Guide ## Download ## Download binaries from https://github.com/Orckestra/CMS-Foundation/releases/latest ## Forums ## -Head over to https://gitter.im/Orckestra/C1-CMS or https://orckestracms.codeplex.com/discussions to ask questions +Head over to https://gitter.im/Orckestra/C1-CMS or https://c1cms.codeplex.com/discussions to ask questions ## Who are we? ## Orckestra is the company driving the development of C1 CMS Foundation. We have a team working full time on this CMS and on other cool stuff you can add to it. We are situated in Austin, Montreal, Copenhagen and Kiev. We specialize in enterprise commerce software. From 2dd1b65cd55a4b775aa61b589a3166f3542dbfa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pauli=20=C3=98ster=C3=B8?= Date: Mon, 20 Feb 2017 11:37:39 -0300 Subject: [PATCH 030/135] Removing WebApi from the Website Project as well --- Website/WebSite.csproj | 8 -------- Website/packages.config | 3 --- 2 files changed, 11 deletions(-) diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index d79b364e75..3bd78eb445 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -126,14 +126,6 @@ ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll True
- - ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - True - - - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - True - ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll True diff --git a/Website/packages.config b/Website/packages.config index 5051521ec4..379dcbe898 100644 --- a/Website/packages.config +++ b/Website/packages.config @@ -2,9 +2,6 @@ - - - From bca01f5cefa9604ea6f25642f5f9cc19edf0ef05 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Tue, 21 Feb 2017 16:41:42 +0100 Subject: [PATCH 031/135] log exception when adding failed --- Composite/Data/DataProviderCopier.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Composite/Data/DataProviderCopier.cs b/Composite/Data/DataProviderCopier.cs index c58e1b7aed..5fb737d427 100644 --- a/Composite/Data/DataProviderCopier.cs +++ b/Composite/Data/DataProviderCopier.cs @@ -254,9 +254,10 @@ private void CopyData(Type interfaceType) { AddData(interfaceType, dataset, targetDataProvider); } - catch (Exception) + catch (Exception e) { - Log.LogWarning(LogTitle, "Adding failed."); + Log.LogError(LogTitle, $"Adding failed while adding {interfaceType.Namespace}.{interfaceType.Name} because {e.Message}"); + Log.LogError(LogTitle,e.InnerException); throw; } } From 5559b37ad671ec28848334d3973999e491e01700 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Tue, 21 Feb 2017 16:43:37 +0100 Subject: [PATCH 032/135] use case sensitive compare for key fields when it is string --- .../SqlDataProviderStoreManipulator.cs | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs b/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs index c68d265a0f..cbe836735f 100644 --- a/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs +++ b/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs @@ -97,12 +97,12 @@ internal void CreateStore(DataTypeDescriptor typeDescriptor, DataScopeIdentifier return; } - throw new InvalidOperationException("Database already contains a table named {0}".FormatWith(tableName)); + throw new InvalidOperationException($"Database already contains a table named {tableName}"); } var sql = new StringBuilder(); var sqlColumns = typeDescriptor.Fields.Select(fieldDescriptor - => GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, true, false) + => GetColumnInfo(tableName, fieldDescriptor.Name, typeDescriptor, fieldDescriptor, true, false) ).ToList(); sql.AppendFormat("CREATE TABLE dbo.[{0}]({1});", tableName, string.Join(",", sqlColumns)); @@ -429,8 +429,7 @@ private void AlterStore(UpdateDataTypeDescriptor updateDataTypeDescriptor, DataT { if (tables.Contains(alteredTableName)) throw new InvalidOperationException( - string.Format("Can not rename table to {0}. A table with that name already exists", - alteredTableName)); + $"Can not rename table to {alteredTableName}. A table with that name already exists"); RenameTable(originalTableName, alteredTableName); } @@ -444,7 +443,7 @@ private void AlterStore(UpdateDataTypeDescriptor updateDataTypeDescriptor, DataT } DropFields(alteredTableName, changeDescriptor.DeletedFields, changeDescriptor.OriginalType.Fields); - ImplementFieldChanges(alteredTableName, changeDescriptor.ExistingFields); + ImplementFieldChanges(alteredTableName, changeDescriptor.AlteredType, changeDescriptor.ExistingFields); Dictionary defaultValues = null; @@ -542,7 +541,7 @@ private void DropStore(DataTypeDescriptor dataTypeDescriptor, DataScopeIdentifie if (tables.Contains(tableName)) { - ExecuteNonQuery(string.Format("DROP TABLE [{0}];", tableName)); + ExecuteNonQuery($"DROP TABLE [{tableName}];"); SqlTableInformationStore.ClearCache(_connectionString, tableName); } @@ -555,6 +554,7 @@ private void DropStore(DataTypeDescriptor dataTypeDescriptor, DataScopeIdentifie private void ImplementFieldChanges( string tableName, + DataTypeDescriptor typeDescriptor, IEnumerable existingFieldDescription) { foreach (var changedFieldDescriptor in existingFieldDescription) @@ -564,6 +564,7 @@ private void ImplementFieldChanges( var columnName = changedFieldDescriptor.OriginalField.Name; ConfigureColumn(tableName, columnName, + typeDescriptor, changedFieldDescriptor.AlteredField, changedFieldDescriptor.OriginalField, changes); } } @@ -605,13 +606,16 @@ private void AppendFields(string tableName, { foreach (var addedFieldDescriptor in addedFieldDescriptions) { + string fieldName = addedFieldDescriptor.Name; object defaultValue = null; - if (defaultValues != null && defaultValues.ContainsKey(addedFieldDescriptor.Name)) + if (defaultValues != null && defaultValues.ContainsKey(fieldName)) { defaultValue = defaultValues[addedFieldDescriptor.Name]; } - CreateColumn(tableName, addedFieldDescriptor, defaultValue); + + + CreateColumn(tableName, changeDescriptor.AlteredType, addedFieldDescriptor, defaultValue); // Updating VersionId field if (addedFieldDescriptor.Name == nameof(IVersioned.VersionId) @@ -720,18 +724,18 @@ private Exception MakeVerboseException(Exception ex) - private void CreateColumn(string tableName, DataFieldDescriptor fieldDescriptor, object defaultValue = null) + private void CreateColumn(string tableName, DataTypeDescriptor typeDescriptor, DataFieldDescriptor fieldDescriptor, object defaultValue = null) { if (defaultValue == null && !fieldDescriptor.IsNullable && fieldDescriptor.DefaultValue != null) { ExecuteNonQuery("ALTER TABLE [{0}] ADD {1};" - .FormatWith(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, true, false))); + .FormatWith(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, typeDescriptor, fieldDescriptor, true, false))); return; } // Creating a column, making it nullable ExecuteNonQuery("ALTER TABLE [{0}] ADD {1};" - .FormatWith(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, true, true))); + .FormatWith(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, typeDescriptor, fieldDescriptor, true, true))); // Setting default value with "UPDATE" statement if (defaultValue != null || (!fieldDescriptor.IsNullable && fieldDescriptor.DefaultValue == null)) @@ -757,17 +761,21 @@ private void CreateColumn(string tableName, DataFieldDescriptor fieldDescriptor, // Making column not nullable if necessary if(!fieldDescriptor.IsNullable) { - AlterColumn(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, false, false)); + AlterColumn(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, typeDescriptor, fieldDescriptor, false, false)); } } - private void ConfigureColumn(string tableName, string columnName, DataFieldDescriptor fieldDescriptor, DataFieldDescriptor originalFieldDescriptor, bool changes) + private void ConfigureColumn(string tableName, string columnName, + DataTypeDescriptor typeDescriptor, + DataFieldDescriptor fieldDescriptor, DataFieldDescriptor originalFieldDescriptor, bool changes) { - if (columnName != fieldDescriptor.Name) + string fieldName = fieldDescriptor.Name; + + if (columnName != fieldName) { - RenameColumn(tableName, columnName, fieldDescriptor.Name); + RenameColumn(tableName, columnName, fieldName); } if(changes) @@ -778,7 +786,7 @@ private void ConfigureColumn(string tableName, string columnName, DataFieldDescr { if (fieldDescriptor.StoreType.ToString() != originalFieldDescriptor.StoreType.ToString()) { - AlterColumn(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, false, true)); + AlterColumn(tableName, GetColumnInfo(tableName, fieldName, typeDescriptor, fieldDescriptor, false, true)); } string defaultValue = TranslatesIntoDefaultConstraint(fieldDescriptor.DefaultValue) @@ -789,7 +797,7 @@ private void ConfigureColumn(string tableName, string columnName, DataFieldDescr .FormatWith(tableName, fieldDescriptor.Name, defaultValue)); } - AlterColumn(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, fieldDescriptor, false, false)); + AlterColumn(tableName, GetColumnInfo(tableName, fieldDescriptor.Name, typeDescriptor, fieldDescriptor, false, false)); } ExecuteNonQuery(SetDefaultValue(tableName, fieldDescriptor.Name, fieldDescriptor.DefaultValue)); @@ -800,9 +808,13 @@ private void AlterColumn(string tableName, string columnInfo) ExecuteNonQuery(string.Format("ALTER TABLE [{0}] ALTER COLUMN {1};", tableName, columnInfo)); } - internal string GetColumnInfo(string tableName, string columnName, DataFieldDescriptor fieldDescriptor, bool includeDefault, bool forceNullable) + internal string GetColumnInfo(string tableName, string columnName, + DataTypeDescriptor dataTypeDescriptor, + DataFieldDescriptor fieldDescriptor, bool includeDefault, bool forceNullable) { string defaultInfo = string.Empty; + string fieldName = fieldDescriptor.Name; + bool isKeyField = dataTypeDescriptor.KeyPropertyNames.Contains(fieldName); if (TranslatesIntoDefaultConstraint(fieldDescriptor.DefaultValue)) { @@ -817,7 +829,8 @@ internal string GetColumnInfo(string tableName, string columnName, DataFieldDesc var defaultValue = fieldDescriptor.DefaultValue; string collation = string.Empty; - if (defaultValue != null && defaultValue.ValueType == DefaultValueType.RandomString) + if (defaultValue?.ValueType == DefaultValueType.RandomString + || (isKeyField && fieldDescriptor.StoreType.IsString)) { collation = "COLLATE Latin1_General_CS_AS"; } From 87830764dca29913403e983461f5c00921065e90 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 27 Feb 2017 15:17:19 +0100 Subject: [PATCH 033/135] Performance optimization in relation to startup time --- .../Core/WebClient/BuildManagerHelper.cs | 111 +++++++++++------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/Composite/Core/WebClient/BuildManagerHelper.cs b/Composite/Core/WebClient/BuildManagerHelper.cs index 87e7a58f79..a41377d8e5 100644 --- a/Composite/Core/WebClient/BuildManagerHelper.cs +++ b/Composite/Core/WebClient/BuildManagerHelper.cs @@ -1,17 +1,25 @@ ï»żusing Composite.Core.IO; using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; +using System.Web.Compilation; +using System.Web.Hosting; using System.Xml.Linq; +using Composite.Core.Extensions; namespace Composite.Core.WebClient { internal static class BuildManagerHelper { + private static DateTime? _delayPreloadTo = null; + private static TimeSpan _preloadDelay = TimeSpan.FromSeconds(2); + private static readonly string LogTitle = typeof (BuildManagerHelper).Name; private static int _preloadingInitiated; @@ -33,15 +41,12 @@ private static void LoadAllControls() const string configFileFilePath = "~/App_Data/Composite/Composite.config"; var config = XDocument.Load(PathUtil.Resolve(configFileFilePath)); - var controlPathes = (from element in config.Descendants() + var controlPathes = from element in config.Descendants() let userControlVirtualPath = (string) element.Attribute("userControlVirtualPath") where userControlVirtualPath != null - select userControlVirtualPath).ToList(); - - var stopWatch = new Stopwatch(); - stopWatch.Start(); + select userControlVirtualPath; - Log.LogVerbose(LogTitle, "Preloading all the controls, starting"); + var controlsToCompile = new List(); foreach (var controlPath in controlPathes) { @@ -51,52 +56,72 @@ private static void LoadAllControls() continue; } - try - { - BuildManagerHelper.GetCompiledType(controlPath); - } - catch (ThreadAbortException) - { - // this exception is automatically rethrown after this catch - } - catch (Exception ex) - { - Log.LogWarning(LogTitle, ex); - } + controlsToCompile.Add(controlPath); } - stopWatch.Stop(); - - Log.LogVerbose(LogTitle, "Preloading all the controls: " + stopWatch.ElapsedMilliseconds + "ms"); Func isAshxAsmxPath = f => f == ".ashx" || f == ".asmx"; Func isAspNetPath = f => f == ".aspx" || isAshxAsmxPath(f); var aspnetPaths = DirectoryUtils.GetFilesRecursively(PathUtil.Resolve("~/Composite")).Where(f => isAshxAsmxPath(Path.GetExtension(f))) .Concat(DirectoryUtils.GetFilesRecursively(PathUtil.Resolve("~/Renderers")).Where(f => isAspNetPath(Path.GetExtension(f)))) + .Select(PathUtil.GetWebsitePath) .ToList(); - stopWatch.Reset(); - stopWatch.Start(); + var compileGroups = new List>>() + { + new Tuple>("ASP.NET controls", controlsToCompile), + new Tuple>("ASP.NET pages and handlers", aspnetPaths), + }; + - foreach (var aspnetPath in aspnetPaths) + foreach (var compileGroup in compileGroups) { - try - { - BuildManagerHelper.GetCompiledType(PathUtil.GetWebsitePath(aspnetPath)); - } - catch (ThreadAbortException) - { - // this exception is automatically rethrown after this catch - } - catch (Exception ex) + if (HostingEnvironment.ApplicationHost.ShutdownInitiated()) return; + + Log.LogVerbose(LogTitle, "Preloading " + compileGroup.Item1); + + var stopWatch = new Stopwatch(); + stopWatch.Start(); + + foreach (var virtualPath in compileGroup.Item2) { - Log.LogWarning("BuildManagerHelper", ex); + while (true) + { + if (HostingEnvironment.ApplicationHost.ShutdownInitiated()) return; + + Thread.MemoryBarrier(); + var waitUntil = _delayPreloadTo; + var now = DateTime.Now; + + if (waitUntil == null || waitUntil <= now) + { + break; + } + + Thread.Sleep(waitUntil.Value - now); + } + + try + { + using (new DisableUrlMedataScope()) + { + BuildManager.GetCompiledType(virtualPath); + } + } + catch (ThreadAbortException) + { + // this exception is automatically rethrown after this catch + } + catch (Exception ex) + { + Log.LogWarning(LogTitle, ex); + } } - } - stopWatch.Stop(); + stopWatch.Stop(); - Log.LogVerbose(LogTitle, "Preloading all asp.net files: " + stopWatch.ElapsedMilliseconds + "ms"); + Log.LogVerbose(LogTitle, $"Preloading {compileGroup.Item1} completed in {stopWatch.ElapsedMilliseconds} ms"); + } } catch (ThreadAbortException) { @@ -131,14 +156,12 @@ public static void DisableUrlMetadataCaching(bool disableCaching) return; } - var systemWeb = typeof (System.Web.TraceMode).Assembly; + var systemWeb = typeof(System.Web.TraceMode).Assembly; Type cachedPathData = systemWeb.GetType("System.Web.CachedPathData", false); - if (cachedPathData == null) return; - FieldInfo field = cachedPathData.GetField("s_doNotCacheUrlMetadata", BindingFlags.Static | BindingFlags.NonPublic); - if (field == null) return; + var field = cachedPathData?.GetField("s_doNotCacheUrlMetadata", BindingFlags.Static | BindingFlags.NonPublic); - field.SetValue(null, disableCaching); + field?.SetValue(null, disableCaching); } /// @@ -146,10 +169,12 @@ public static void DisableUrlMetadataCaching(bool disableCaching) /// public static IDisposable DisableUrlMetadataCachingScope() { + _delayPreloadTo = DateTime.Now.Add(_preloadDelay); + return new DisableUrlMedataScope(); } - public class DisableUrlMedataScope : IDisposable + internal class DisableUrlMedataScope : IDisposable { public DisableUrlMedataScope() { From 7e6f7ae563379d87e7d01975db155e7d497b94b9 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Mon, 27 Feb 2017 16:09:00 +0100 Subject: [PATCH 034/135] getting rid of unusable warnings --- Composite/C1Console/RichContent/Components/ComponentManager.cs | 1 - Composite/Core/WebClient/Services/WampRouter/WampRouter.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Composite/C1Console/RichContent/Components/ComponentManager.cs b/Composite/C1Console/RichContent/Components/ComponentManager.cs index 1b1f8e5864..3f1c79aab1 100644 --- a/Composite/C1Console/RichContent/Components/ComponentManager.cs +++ b/Composite/C1Console/RichContent/Components/ComponentManager.cs @@ -76,7 +76,6 @@ void IObserver.OnError(Exception error) void IObserver.OnNext(ComponentChange value) { _componentCache = null; - _log.LogInformation(nameof(ComponentManager), "We should flush some cache here.." + value.ProviderId); } #endregion } diff --git a/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs b/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs index 96cf344aef..da422ed36e 100644 --- a/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs +++ b/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs @@ -56,7 +56,7 @@ public void RegisterPublisher { if (realm.TopicContainer.TopicUris.FirstOrDefault(f => f.Equals(eventObservable.Topic)) == null) { - Log.LogWarning(nameof(WampRouter), + Log.LogVerbose(nameof(WampRouter), $"Trying to publish on topic: {eventObservable.Topic}, but there is no subscriber to this topic"); } else From 8ceddbe8d5ed3b4b209cab9fe2b07709c45165a0 Mon Sep 17 00:00:00 2001 From: "david.abitbol@orckestra.com" Date: Mon, 27 Feb 2017 14:06:55 -0500 Subject: [PATCH 035/135] Added 2 new fields for media: Tags and a read-only field to display the mediaURL --- .../AddNewMediaFileWorkflow.cs | 3 ++ .../EditMediaFileWorkflow.cs | 3 ++ Composite/Data/Types/IMediaFile.cs | 10 ++++ Composite/Data/Types/IMediaFileData.cs | 5 ++ Composite/Data/Types/IMediaFileStore.cs | 1 - .../FileSystemMediaFile.cs | 19 +++++++ .../FileSystemMediaFileProvider.cs | 10 +++- .../MediaFileProvider/MediaFile.cs | 10 +++- .../MediaFileProvider/MediaFileProvider.cs | 2 +- .../VirtualImageFile.cs | 20 +++++++ .../WorkflowMediaFile.cs | 13 +++++ .../Administrative/AddMediaFileStep2.xml | 8 +++ .../forms/Administrative/EditMediaFile.xml | 22 ++++++++ .../Composite.Management.en-us.xml | 4 ++ Website/jspm.config.js | 52 +++++++++---------- Website/package.json | 23 ++++---- 16 files changed, 165 insertions(+), 40 deletions(-) diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/AddNewMediaFileWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/AddNewMediaFileWorkflow.cs index 27ba6c0ca5..81f4852a3a 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/AddNewMediaFileWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/AddNewMediaFileWorkflow.cs @@ -100,6 +100,7 @@ private void initializeCodeActivity_InitializeBindings_ExecuteCode(object sender this.Bindings.Add("AllowOverwrite", false); this.Bindings.Add("Title", ""); this.Bindings.Add("Description", ""); + this.Bindings.Add("Tags", ""); } @@ -219,6 +220,7 @@ private void finalizeCodeActivity_Finalize_ExecuteCode(object sender, EventArgs mediaFile.FolderPath = this.FolderPath; mediaFile.Title = this.GetBinding("Title"); mediaFile.Description = this.GetBinding("Description"); + mediaFile.Tags = this.GetBinding("Tags"); mediaFile.Culture = C1Console.Users.UserSettings.ActiveLocaleCultureInfo.Name; mediaFile.Length = uploadedFile.ContentLength; mediaFile.MimeType = MimeTypeInfo.GetMimeType(uploadedFile); @@ -244,6 +246,7 @@ private void finalizeCodeActivity_Finalize_ExecuteCode(object sender, EventArgs fileData.Title = this.GetBinding("Title"); fileData.Description = this.GetBinding("Description"); + fileData.Tags = this.GetBinding("Tags"); fileData.MimeType = MimeTypeInfo.GetMimeType(uploadedFile); fileData.Length = uploadedFile.ContentLength; diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs index d6c5451f55..036226aa9e 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs @@ -31,7 +31,9 @@ private void initializeCodeActivity_ExecuteCode(object sender, EventArgs e) this.Bindings.Add("FileDataFileName", file.FileName); this.Bindings.Add("FileDataTitle", file.Title); + this.Bindings.Add("FileDataURL", file.MediaURL); this.Bindings.Add("FileDataDescription", file.Description); + this.Bindings.Add("FileDataTags", file.Tags); this.Bindings.Add("ProvidesMetaData", store.ProvidesMetadata); this.BindingsValidationRules.Add("FileDataTitle", new List { new StringLengthClientValidationRule(0, 256) }); @@ -50,6 +52,7 @@ private void finalizeCodeActivity_ExecuteCode(object sender, EventArgs e) file.FileName = this.GetBinding("FileDataFileName"); file.Title = this.GetBinding("FileDataTitle"); file.Description = this.GetBinding("FileDataDescription"); + file.Tags = this.GetBinding("FileDataTags"); DataFacade.Update(file); diff --git a/Composite/Data/Types/IMediaFile.cs b/Composite/Data/Types/IMediaFile.cs index d4121e2d0d..7061835745 100644 --- a/Composite/Data/Types/IMediaFile.cs +++ b/Composite/Data/Types/IMediaFile.cs @@ -55,6 +55,12 @@ public interface IMediaFile : IFile [SearchableField(true, true, false)] string Description { get; set; } + /// + [ImmutableFieldId("{016372B5-9692-4C2D-B64D-8FC6594BBCFF}")] + [StoreFieldType(PhysicalStoreFieldType.LargeString)] + [SearchableField(true, true, false)] + string Tags { get; set; } + /// [ImmutableFieldId("{D4B7D47E-49CF-43c9-AC36-4134B136860A}")] @@ -68,6 +74,10 @@ public interface IMediaFile : IFile [SearchableField(false, true, true)] string MimeType { get; } + /// + [ImmutableFieldId("{ae5be3d2-c239-48a0-a833-3d23a263a40f}")] + string MediaURL { get; } + /// [ImmutableFieldId("{BCD0C1A2-9769-4209-8D43-DB7DDBABBB8B}")] diff --git a/Composite/Data/Types/IMediaFileData.cs b/Composite/Data/Types/IMediaFileData.cs index 413db2151d..ad85fa5ed1 100644 --- a/Composite/Data/Types/IMediaFileData.cs +++ b/Composite/Data/Types/IMediaFileData.cs @@ -47,6 +47,11 @@ public interface IMediaFileData : IData [ImmutableFieldId("{6993c337-88c6-4e90-a1c2-64aeb73f0650}")] string Description { get; set; } + /// + [StoreFieldType(PhysicalStoreFieldType.LargeString, IsNullable = true)] + [ImmutableFieldId("{ef096303-74b9-4b90-9626-2cefecd0a3ce}")] + string Tags { get; set; } + /// [StoreFieldType(PhysicalStoreFieldType.String, 128, IsNullable = true)] diff --git a/Composite/Data/Types/IMediaFileStore.cs b/Composite/Data/Types/IMediaFileStore.cs index 47a9cae94f..692bed12d2 100644 --- a/Composite/Data/Types/IMediaFileStore.cs +++ b/Composite/Data/Types/IMediaFileStore.cs @@ -19,7 +19,6 @@ public interface IMediaFileStore : IData /// string Description { get; } - /// bool IsReadOnly { get; } diff --git a/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs b/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs index add13f98f1..a8b512da62 100644 --- a/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs +++ b/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs @@ -65,6 +65,14 @@ public string StoreId set; } + public string MediaURL + { + get + { + return Composite.Core.Routing.MediaUrls.BuildUrl(this); + } + } + public string Title @@ -92,6 +100,17 @@ public string Description } } + public string Tags + { + get + { + return ""; + } + set + { + } + } + public string Culture diff --git a/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFileProvider.cs b/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFileProvider.cs index ba190c3612..ec695c9a14 100644 --- a/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFileProvider.cs +++ b/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFileProvider.cs @@ -45,7 +45,7 @@ private IMediaFileStore Store { if (_store == null) { - _store = new MediaArchiveStore(_storeId, _storeTitle, _storeDescription, _context.CreateDataSourceId(new MediaDataId() { MediaType = _storeType }, typeof(IMediaFileStore))); + _store = new MediaArchiveStore(_storeId, _storeTitle, _storeDescription, _context.CreateDataSourceId(new MediaDataId() { MediaType = _storeType }, typeof(IMediaFileStore))); } return _store; } @@ -404,7 +404,7 @@ private sealed class MediaArchiveStore : IMediaFileStore - public MediaArchiveStore(string id, string title, string description, DataSourceId dataSourceId) + public MediaArchiveStore(string id, string title, string description,DataSourceId dataSourceId) { Id = id; Title = title; @@ -436,6 +436,12 @@ public string Description set; } + public string Tags + { + get; + set; + } + public bool IsReadOnly diff --git a/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs b/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs index 57a8ef89b0..e4ce9cc421 100644 --- a/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs +++ b/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs @@ -23,6 +23,7 @@ public MediaFile(IMediaFileData file, string storeId, DataSourceId dataSourceId, this.FolderPath = file.FolderPath; this.Title = file.Title; this.Description = file.Description; + this.Tags = file.Tags; this.MimeType = file.MimeType; this.Length = file.Length; this.IsReadOnly = false; @@ -50,7 +51,12 @@ public string CompositePath set { /* Do nothing. Used for deserialization purpouses */ } } - + public string MediaURL { + get + { + return Composite.Core.Routing.MediaUrls.BuildUrl(this); + } + } public string StoreId { @@ -82,6 +88,8 @@ public string Description set; } + public string Tags { get; set; } + public string Culture { get; diff --git a/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFileProvider.cs b/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFileProvider.cs index 5fee6b8c29..45d3fc1a8d 100644 --- a/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFileProvider.cs +++ b/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFileProvider.cs @@ -528,6 +528,7 @@ private void CopyFileData(IMediaFile from, IMediaFileData to) to.CultureInfo = from.Culture; to.Description = from.Description; to.FileName = from.FileName; + to.Tags = from.Tags; to.FolderPath = from.FolderPath; to.Length = from.Length; to.MimeType = MimeTypeInfo.GetCanonical(from.MimeType); @@ -618,7 +619,6 @@ public MediaFileStore(string id, string title, string description, DataSourceId public string Description { get; set; } - public bool IsReadOnly { get { return false; } diff --git a/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs b/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs index cadaa6317b..9301c16603 100644 --- a/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs +++ b/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs @@ -88,6 +88,26 @@ public string Description } } + public string Tags + { + get + { + return _sourceFile.Tags; + } + set + { + _sourceFile.Tags = value; ; + } + } + + public string MediaURL + { + get + { + return Composite.Core.Routing.MediaUrls.BuildUrl(this); + } + } + public string Culture { get diff --git a/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs b/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs index 75b23c0931..3f3c5151fc 100644 --- a/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs +++ b/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs @@ -20,6 +20,7 @@ public WorkflowMediaFile() Title = string.Empty; Description = string.Empty; MimeType = string.Empty; + Tags = string.Empty; DataSourceId = new DataSourceId(typeof(IMediaFile)); } @@ -35,6 +36,7 @@ public WorkflowMediaFile(IMediaFile file) CreationTime = file.CreationTime; DataSourceId = file.DataSourceId; Description = file.Description; + Tags = file.Tags; FileName = file.FileName; FolderPath = file.FolderPath; IsReadOnly = file.IsReadOnly; @@ -95,6 +97,9 @@ public string Description set; } + /// + public string Tags { get; set; } + /// @@ -122,6 +127,14 @@ public int? Length set; } + public string MediaURL + { + get + { + return Composite.Core.Routing.MediaUrls.BuildUrl(this); + } + } + /// diff --git a/Website/Composite/content/forms/Administrative/AddMediaFileStep2.xml b/Website/Composite/content/forms/Administrative/AddMediaFileStep2.xml index e81f23d20b..8f2bc34c72 100644 --- a/Website/Composite/content/forms/Administrative/AddMediaFileStep2.xml +++ b/Website/Composite/content/forms/Administrative/AddMediaFileStep2.xml @@ -4,6 +4,7 @@ + @@ -30,6 +31,13 @@ + + diff --git a/Website/Composite/content/forms/Administrative/EditMediaFile.xml b/Website/Composite/content/forms/Administrative/EditMediaFile.xml index 2e6b63eaab..765ecbb63a 100644 --- a/Website/Composite/content/forms/Administrative/EditMediaFile.xml +++ b/Website/Composite/content/forms/Administrative/EditMediaFile.xml @@ -4,6 +4,8 @@ + + @@ -35,6 +37,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Website/Composite/localization/Composite.Management.en-us.xml b/Website/Composite/localization/Composite.Management.en-us.xml index 9b47d08f2e..f1ef58a5ef 100644 --- a/Website/Composite/localization/Composite.Management.en-us.xml +++ b/Website/Composite/localization/Composite.Management.en-us.xml @@ -623,6 +623,10 @@ + + + + diff --git a/Website/jspm.config.js b/Website/jspm.config.js index b4b8603e6c..af60c39915 100644 --- a/Website/jspm.config.js +++ b/Website/jspm.config.js @@ -294,7 +294,7 @@ SystemJS.config({ "magicpen-media": "npm:magicpen-media@1.5.1", "messy": "npm:messy@6.12.2", "net": "npm:jspm-nodelibs-net@0.2.0", - "os": "npm:jspm-nodelibs-os@0.2.0", + "os": "github:jspm/nodelibs-os@0.2.0-alpha", "punycode": "npm:jspm-nodelibs-punycode@0.2.0", "querystring": "npm:jspm-nodelibs-querystring@0.2.0", "rc-table": "npm:rc-table@5.0.3", @@ -315,17 +315,17 @@ SystemJS.config({ "constants": "npm:jspm-nodelibs-constants@0.2.0", "assert": "npm:jspm-nodelibs-assert@0.2.0", "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha", - "child_process": "npm:jspm-nodelibs-child_process@0.2.0", - "crypto": "npm:jspm-nodelibs-crypto@0.2.0", - "domain": "npm:jspm-nodelibs-domain@0.2.0", + "child_process": "github:jspm/nodelibs-child_process@0.2.0-alpha", + "crypto": "github:jspm/nodelibs-crypto@0.2.0-alpha", + "domain": "github:jspm/nodelibs-domain@0.2.0-alpha", "events": "github:jspm/nodelibs-events@0.2.0-alpha", "fs": "github:jspm/nodelibs-fs@0.2.0-alpha", "http": "github:jspm/nodelibs-http@0.2.0-alpha", - "https": "npm:jspm-nodelibs-https@0.2.0", + "https": "github:jspm/nodelibs-https@0.2.0-alpha", "path": "github:jspm/nodelibs-path@0.2.0-alpha", "process": "github:jspm/nodelibs-process@0.2.0-alpha", "stream": "github:jspm/nodelibs-stream@0.2.0-alpha", - "string_decoder": "npm:jspm-nodelibs-string_decoder@0.2.0", + "string_decoder": "github:jspm/nodelibs-string_decoder@0.2.0-alpha", "normalizr": "npm:normalizr@2.2.1", "react-redux": "npm:react-redux@4.4.5", "redux": "npm:redux@3.6.0", @@ -334,10 +334,10 @@ SystemJS.config({ "url": "github:jspm/nodelibs-url@0.2.0-alpha", "url-polyfill": "github:github/url-polyfill@0.5.6", "util": "github:jspm/nodelibs-util@0.2.0-alpha", - "vm": "npm:jspm-nodelibs-vm@0.2.0", + "vm": "github:jspm/nodelibs-vm@0.2.0-alpha", "wampy": "npm:wampy@4.0.0", "whatwg-fetch": "npm:whatwg-fetch@1.1.1", - "zlib": "npm:jspm-nodelibs-zlib@0.2.0" + "zlib": "github:jspm/nodelibs-zlib@0.2.0-alpha" }, packages: { "npm:bn.js@4.11.6": { @@ -829,49 +829,49 @@ SystemJS.config({ "punycode-browserify": "npm:punycode@1.4.1" } }, - "npm:jspm-nodelibs-domain@0.2.0": { + "github:jspm/nodelibs-http@0.2.0-alpha": { "map": { - "domain-browserify": "npm:domain-browser@1.1.7" + "http-browserify": "npm:stream-http@2.5.0" } }, - "npm:jspm-nodelibs-crypto@0.2.0": { + "github:jspm/nodelibs-buffer@0.2.0-alpha": { "map": { - "crypto-browserify": "npm:crypto-browserify@3.11.0" + "buffer-browserify": "npm:buffer@4.9.1" } }, - "npm:jspm-nodelibs-zlib@0.2.0": { + "github:jspm/nodelibs-stream@0.2.0-alpha": { "map": { - "zlib-browserify": "npm:browserify-zlib@0.1.4" + "stream-browserify": "npm:stream-browserify@2.0.1" } }, - "npm:jspm-nodelibs-string_decoder@0.2.0": { + "github:jspm/nodelibs-url@0.2.0-alpha": { "map": { - "string_decoder-browserify": "npm:string_decoder@0.10.31" + "url-browserify": "npm:url@0.11.0" } }, - "npm:jspm-nodelibs-os@0.2.0": { + "github:jspm/nodelibs-domain@0.2.0-alpha": { "map": { - "os-browserify": "npm:os-browserify@0.2.1" + "domain-browserify": "npm:domain-browser@1.1.7" } }, - "github:jspm/nodelibs-http@0.2.0-alpha": { + "github:jspm/nodelibs-os@0.2.0-alpha": { "map": { - "http-browserify": "npm:stream-http@2.5.0" + "os-browserify": "npm:os-browserify@0.2.1" } }, - "github:jspm/nodelibs-buffer@0.2.0-alpha": { + "github:jspm/nodelibs-zlib@0.2.0-alpha": { "map": { - "buffer-browserify": "npm:buffer@4.9.1" + "zlib-browserify": "npm:browserify-zlib@0.1.4" } }, - "github:jspm/nodelibs-stream@0.2.0-alpha": { + "github:jspm/nodelibs-string_decoder@0.2.0-alpha": { "map": { - "stream-browserify": "npm:stream-browserify@2.0.1" + "string_decoder-browserify": "npm:string_decoder@0.10.31" } }, - "github:jspm/nodelibs-url@0.2.0-alpha": { + "github:jspm/nodelibs-crypto@0.2.0-alpha": { "map": { - "url-browserify": "npm:url@0.11.0" + "crypto-browserify": "npm:crypto-browserify@3.11.0" } } } diff --git a/Website/package.json b/Website/package.json index e8a976bf69..3df4409518 100644 --- a/Website/package.json +++ b/Website/package.json @@ -79,7 +79,7 @@ "react-immutable-proptypes": "npm:react-immutable-proptypes@^2.1.0", "sinon": "npm:sinon@^1.17.5", "source-map": "npm:source-map@0.2", - "systemjs-hot-reloader": "github:capaj/systemjs-hot-reloader@^0.6.0", + "systemjs-hot-reloader": "github:alexisvincent/systemjs-hot-reloader@^0.6.0", "systemjs-hot-reloader-store": "github:peteruithoven/systemjs-hot-reloader-store@^1.0.0", "tweetnacl": "npm:tweetnacl@0.13", "unexpected-dom": "npm:unexpected-dom@^3.1.0", @@ -93,20 +93,20 @@ "assert": "npm:jspm-nodelibs-assert@^0.2.0", "bluebird": "npm:bluebird@^3.0.0", "buffer": "github:jspm/nodelibs-buffer@^0.2.0-alpha", - "child_process": "npm:jspm-nodelibs-child_process@^0.2.0", + "child_process": "github:jspm/nodelibs-child_process@^0.2.0-alpha", "constants": "npm:jspm-nodelibs-constants@^0.2.0", - "crypto": "npm:jspm-nodelibs-crypto@^0.2.0", - "domain": "npm:jspm-nodelibs-domain@^0.2.0", + "crypto": "github:jspm/nodelibs-crypto@^0.2.0-alpha", + "domain": "github:jspm/nodelibs-domain@^0.2.0-alpha", "events": "github:jspm/nodelibs-events@^0.2.0-alpha", "fs": "github:jspm/nodelibs-fs@^0.2.0-alpha", "http": "github:jspm/nodelibs-http@^0.2.0-alpha", - "https": "npm:jspm-nodelibs-https@^0.2.0", + "https": "github:jspm/nodelibs-https@^0.2.0-alpha", "immutable": "npm:immutable@^3.8.1", "magicpen-media": "npm:magicpen-media@^1.5.0", "messy": "npm:messy@^6.12.0", "module": "npm:jspm-nodelibs-module@^0.2.0", "net": "npm:jspm-nodelibs-net@^0.2.0", - "os": "npm:jspm-nodelibs-os@^0.2.0", + "os": "github:jspm/nodelibs-os@^0.2.0-alpha", "path": "github:jspm/nodelibs-path@^0.2.0-alpha", "process": "github:jspm/nodelibs-process@^0.2.0-alpha", "punycode": "npm:jspm-nodelibs-punycode@^0.2.0", @@ -116,15 +116,15 @@ "redux": "npm:redux@^3.5.2", "repl": "npm:jspm-nodelibs-repl@^0.2.0", "stream": "github:jspm/nodelibs-stream@^0.2.0-alpha", - "string_decoder": "npm:jspm-nodelibs-string_decoder@^0.2.0", + "string_decoder": "github:jspm/nodelibs-string_decoder@^0.2.0-alpha", "tls": "npm:jspm-nodelibs-tls@^0.2.0", "tty": "npm:jspm-nodelibs-tty@^0.2.0", "unexpected": "npm:unexpected@^10.10.0", "unexpected-messy": "npm:unexpected-messy@^6.0.0", "url": "github:jspm/nodelibs-url@^0.2.0-alpha", "util": "github:jspm/nodelibs-util@^0.2.0-alpha", - "vm": "npm:jspm-nodelibs-vm@^0.2.0", - "zlib": "npm:jspm-nodelibs-zlib@^0.2.0" + "vm": "github:jspm/nodelibs-vm@^0.2.0-alpha", + "zlib": "github:jspm/nodelibs-zlib@^0.2.0-alpha" }, "overrides": { "github:github/url-polyfill@0.5.6": { @@ -226,6 +226,11 @@ "lodash": "^4.15.0", "supports-color": "^3.1.2" } + }, + "npm:unexpected@10.18.1": { + "main": "unexpected.js", + "dependencies": {}, + "jspmPackage": true } } } From 4b19b541aeab38974ae7d079b48b0fa111bc697e Mon Sep 17 00:00:00 2001 From: "david.abitbol@orckestra.com" Date: Mon, 27 Feb 2017 14:52:13 -0500 Subject: [PATCH 036/135] Fixed Localization and labels --- .../Composite/content/forms/Administrative/EditMediaFile.xml | 2 +- Website/Composite/localization/Composite.Management.en-us.xml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Website/Composite/content/forms/Administrative/EditMediaFile.xml b/Website/Composite/content/forms/Administrative/EditMediaFile.xml index 765ecbb63a..2edb6f460b 100644 --- a/Website/Composite/content/forms/Administrative/EditMediaFile.xml +++ b/Website/Composite/content/forms/Administrative/EditMediaFile.xml @@ -52,7 +52,7 @@ - + diff --git a/Website/Composite/localization/Composite.Management.en-us.xml b/Website/Composite/localization/Composite.Management.en-us.xml index f1ef58a5ef..00ec20790f 100644 --- a/Website/Composite/localization/Composite.Management.en-us.xml +++ b/Website/Composite/localization/Composite.Management.en-us.xml @@ -581,6 +581,8 @@ + + From d15e064a9840333526b3035fde264f8a032c59c6 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 28 Feb 2017 11:38:57 +0100 Subject: [PATCH 037/135] Fix searching media files by file names does not work --- Composite/Composite.csproj | 1 + .../DataTypeSearchReflectionHelper.cs | 7 ++++++ .../Crawling/FileNameDataFieldProcessor.cs | 25 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 Composite/Search/Crawling/FileNameDataFieldProcessor.cs diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index f930b25484..7649a51e2e 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -254,6 +254,7 @@ + diff --git a/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs b/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs index 622bfc6205..6e06f20d01 100644 --- a/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs +++ b/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs @@ -7,6 +7,7 @@ using Composite.Core.Types; using Composite.Data; using Composite.Data.ProcessControlled; +using Composite.Data.Types; using SearchableFieldInfo = System.Collections.Generic.KeyValuePair; namespace Composite.Search.Crawling @@ -67,6 +68,12 @@ internal static IDataFieldProcessor GetDataFieldProcessor(PropertyInfo propertyI return new PublicationStatusDataFieldProcessor(); } + if (propertyInfo.DeclaringType == typeof(IFile) + && propertyInfo.Name == nameof(IFile.FileName)) + { + return new FileNameDataFieldProcessor(); + } + return new DefaultDataFieldProcessor(); }); } diff --git a/Composite/Search/Crawling/FileNameDataFieldProcessor.cs b/Composite/Search/Crawling/FileNameDataFieldProcessor.cs new file mode 100644 index 0000000000..d56da991b6 --- /dev/null +++ b/Composite/Search/Crawling/FileNameDataFieldProcessor.cs @@ -0,0 +1,25 @@ +ï»żusing System; +using System.Collections.Generic; + +namespace Composite.Search.Crawling +{ + internal class FileNameDataFieldProcessor: DefaultDataFieldProcessor + { + public override IEnumerable GetTextParts(object value) + { + string fileName = (string) value; + yield return fileName; + + int extensionSeparator = fileName.LastIndexOf(".", StringComparison.Ordinal); + if (extensionSeparator > 0) + { + yield return fileName.Substring(0, extensionSeparator); + } + + if (extensionSeparator + 1 < fileName.Length) + { + yield return fileName.Substring(extensionSeparator + 1); + } + } + } +} From 0f76766b3444ad0025d2a94eb4a3b4be49e5b8b9 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 28 Feb 2017 14:17:48 +0100 Subject: [PATCH 038/135] Fixing sorting by descending not working in tree definitions when translation from foreign locales is enabled; refactoring --- .../Trees/DataFolderElementsTreeNode.cs | 148 +++++------------- Composite/Core/Linq/ExpressionHelper.cs | 33 ++-- 2 files changed, 52 insertions(+), 129 deletions(-) diff --git a/Composite/C1Console/Trees/DataFolderElementsTreeNode.cs b/Composite/C1Console/Trees/DataFolderElementsTreeNode.cs index 399b68d85f..0c89f65147 100644 --- a/Composite/C1Console/Trees/DataFolderElementsTreeNode.cs +++ b/Composite/C1Console/Trees/DataFolderElementsTreeNode.cs @@ -25,9 +25,9 @@ namespace Composite.C1Console.Trees [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public class DataFolderElementsTreeNode : DataFilteringTreeNode { - private readonly MethodInfo StringStartsWithMethodInfo = typeof(string).GetMethods().First(f => f.Name == "StartsWith"); - private readonly MethodInfo StringSubstringMethodInfo = typeof(string).GetMethods().Where(f => f.Name == "Substring").Skip(1).First(); - private readonly MethodInfo ToUpperCompareMethodInfo = typeof(string).GetMethods().First(f => f.Name == "ToUpper"); + private readonly MethodInfo StringStartsWithMethodInfo = typeof(string).GetMethods().First(f => f.Name == nameof(string.StartsWith)); + private readonly MethodInfo StringSubstringMethodInfo = typeof(string).GetMethods().Where(f => f.Name == nameof(string.Substring)).Skip(1).First(); + private readonly MethodInfo ToUpperCompareMethodInfo = typeof(string).GetMethods().First(f => f.Name == nameof(string.ToUpper)); /// public Type InterfaceType { get; internal set; } // Required @@ -85,17 +85,7 @@ public class DataFolderElementsTreeNode : DataFilteringTreeNode /// public override IEnumerable GetEntityTokens(EntityToken childEntityToken, TreeNodeDynamicContext dynamicContext) { - IEnumerable labels = GetObjects(dynamicContext, true); - - if (this.LocalizationEnabled) - { - using (new DataScope(UserSettings.ForeignLocaleCultureInfo)) - { - List foreignLabels = GetObjects(dynamicContext, true); - labels = labels.Concat(foreignLabels).Distinct(); - } - } - + IEnumerable labels = GetCurrentAndLocalizableObjects(dynamicContext, true); Type childGeneratingDataElementsReferenceType = null; object childGeneratingDataElementsReferenceValue = null; @@ -195,9 +185,10 @@ protected override IEnumerable OnGetElements(EntityToken parentEntityTo { if (this.IsTopFolderParent) { - DataEntityToken dataEntityToken = (DataEntityToken)dynamicContext.Piggybag + var dataEntityToken = dynamicContext.Piggybag .GetParentEntityTokens(parentEntityToken) - .FirstOrDefault(f => f is DataEntityToken && ((DataEntityToken)f).InterfaceType == ChildGeneratingParentIdFilterNode.ParentFilterType); + .OfType() + .FirstOrDefault(f => f.InterfaceType == ChildGeneratingParentIdFilterNode.ParentFilterType); if (dataEntityToken != null) { @@ -206,7 +197,7 @@ protected override IEnumerable OnGetElements(EntityToken parentEntityTo referenceType = this.ChildGeneratingParentIdFilterNode.KeyPropertyInfo.DeclaringType; referenceValue = this.ChildGeneratingParentIdFilterNode.KeyPropertyInfo.GetValue(data, null); - } + } } else { @@ -223,23 +214,7 @@ protected override IEnumerable OnGetElements(EntityToken parentEntityTo return CreateFolderRangeElements(parentEntityToken, referenceType, referenceValue, dynamicContext); } - IEnumerable objects; - - if (!this.LocalizationEnabled) - { - objects = GetObjects(dynamicContext); - } - else - { - List orgObjects = GetObjects(dynamicContext); - using (new DataScope(UserSettings.ForeignLocaleCultureInfo)) - { - List foreignObjects = GetObjects(dynamicContext); - orgObjects.AddRange(foreignObjects); - orgObjects.Sort(); // TODO: Check if sorting here is necessary - objects = orgObjects.Distinct(); - } - } + IEnumerable objects = GetCurrentAndLocalizableObjects(dynamicContext); if (this.FirstLetterOnly) { @@ -272,7 +247,7 @@ private IEnumerable CreateSimpleElements(EntityToken parentEntityToken, foreach (var pair in objectsAndLabels) { - Element element = CreateElement( + yield return CreateElement( parentEntityToken, referenceType, referenceValue, @@ -280,8 +255,6 @@ private IEnumerable CreateSimpleElements(EntityToken parentEntityToken, pair.Label, f => f.GroupingValues.Add(this.GroupingValuesFieldName, ConvertGroupingValue(pair.Object)) ); - - yield return element; } } @@ -322,35 +295,18 @@ private Func GetLabelFunction(out bool shouldBeSortedByLabel) private IEnumerable CreateFolderRangeElements(EntityToken parentEntityToken, Type referenceType, object referenceValue, TreeNodeDynamicContext dynamicContext) { - IEnumerable indexes; - if (this.Display == LeafDisplayMode.Lazy) + var indexes = Enumerable.Empty(); + + if (this.Display != LeafDisplayMode.Lazy) { - indexes = new List(); - } - else - { - if (!this.LocalizationEnabled) - { - indexes = GetObjects(dynamicContext); - } - else - { - List orgObjects = GetObjects(dynamicContext); - using (new DataScope(UserSettings.ForeignLocaleCultureInfo)) - { - List foreignObjects = GetObjects(dynamicContext); - orgObjects.AddRange(foreignObjects); - orgObjects.Sort(); - indexes = orgObjects.Distinct(); - } - } + indexes = GetCurrentAndLocalizableObjects(dynamicContext); } foreach (IFolderRange folderRange in this.FolderRanges.Ranges) { bool contained = indexes.Contains(folderRange.Index); - if ((this.Display == LeafDisplayMode.Compact) && (contained == false)) continue; + if (this.Display == LeafDisplayMode.Compact && !contained) continue; Element element = CreateElement( parentEntityToken, @@ -377,15 +333,9 @@ private IEnumerable CreateFolderRangeElements(EntityToken parentEntityT private IEnumerable CreateFirstLetterOnlyElements(EntityToken parentEntityToken, Type referenceType, object referenceValue, TreeNodeDynamicContext dynamicContext, IEnumerable objects) { - foreach (object obj in objects) + foreach (string label in objects.OfType()) { - if (obj == null) continue; - - string stringObject = (string)obj; - - string label = stringObject; - - Element element = CreateElement( + yield return CreateElement( parentEntityToken, referenceType, referenceValue, @@ -393,8 +343,6 @@ private IEnumerable CreateFirstLetterOnlyElements(EntityToken parentEnt label, f => f.GroupingValues.Add(this.GroupingValuesFieldName, label) ); - - yield return element; } } @@ -591,33 +539,30 @@ private Expression ApplyOrder(Expression expression, List fiel return expression; } - private List GetObjects(TreeNodeDynamicContext dynamicContext, bool includeAllGroupingFields = false) + private List GetObjects(TreeNodeDynamicContext dynamicContext, bool includeAllGroupingFields = false) { - Expression expression = GetObjectsExpression(dynamicContext, includeAllGroupingFields); + var expression = GetObjectsExpression(dynamicContext, includeAllGroupingFields); - return ExpressionHelper.GetObjects(this.InterfaceType, expression); + return ExpressionHelper.GetCastedObjects(this.InterfaceType, expression); } - - private List GetObjects(TreeNodeDynamicContext dynamicContext) + private IEnumerable GetCurrentAndLocalizableObjects(TreeNodeDynamicContext dynamicContext, bool includeAllGroupingFields = false) { - Expression expression = GetObjectsExpression(dynamicContext); + IEnumerable objects = GetObjects(dynamicContext, includeAllGroupingFields); - return ExpressionHelper.GetCastedObjects(this.InterfaceType, expression); - } - - + if (!this.LocalizationEnabled) return objects; - private bool UseChildGeneratingFilterExpression - { - get + using (new DataScope(UserSettings.ForeignLocaleCultureInfo)) { - return this.IsTopFolderParent && this.Display != LeafDisplayMode.Lazy; + var foreignObjects = GetObjects(dynamicContext, includeAllGroupingFields); + return objects.Concat(foreignObjects).Distinct(); } } + private bool UseChildGeneratingFilterExpression => IsTopFolderParent && Display != LeafDisplayMode.Lazy; + internal override Expression CreateFilterExpression(ParameterExpression parameterExpression, TreeNodeDynamicContext dynamicContext, IList filtersToSkip = null) { @@ -675,7 +620,7 @@ internal override Expression CreateFilterExpression(ParameterExpression paramete { // This will only happen if we are searching up and are given another entity token that // TreeDataFieldGroupingElementEntityToken and DataEntityToken or TreeSimpleElementEntityToken - throw new NotImplementedException(string.Format("Unsupported child entity token type '{0}'", dynamicContext.CurrentEntityToken.GetType())); + throw new NotImplementedException($"Unsupported child entity token type '{dynamicContext.CurrentEntityToken.GetType()}'"); } } else @@ -718,7 +663,7 @@ internal override Expression CreateFilterExpression(ParameterExpression paramete { // This will only happen if we are searching up and are given another entity token that // TreeDataFieldGroupingElementEntityToken and DataEntityToken or TreeSimpleElementEntityToken - throw new NotImplementedException(string.Format("Unsupported child entity token type '{0}'", dynamicContext.CurrentEntityToken.GetType())); + throw new NotImplementedException($"Unsupported child entity token type '{dynamicContext.CurrentEntityToken.GetType()}'"); } } @@ -855,36 +800,26 @@ private Expression CreateFirstLetterOnlyFilterExpression(object value, Expressio { string castedValue = (string)value; - if (castedValue != "") + if (castedValue == "") { - Expression expression = Expression.Condition( + return Expression.Equal(fieldExpression, Expression.Constant("")); + } + + return Expression.Condition( Expression.NotEqual( fieldExpression, Expression.Constant(null) - ), + ), Expression.Call( Expression.Call( fieldExpression, this.ToUpperCompareMethodInfo - ), + ), this.StringStartsWithMethodInfo, Expression.Constant(castedValue) - ), + ), Expression.Constant(false) ); - - return expression; - } - else - { - Expression expression = - Expression.Equal( - fieldExpression, - Expression.Constant("") - ); - - return expression; - } } @@ -1088,7 +1023,7 @@ protected override void OnInitialize() this.KeyPropertyInfo = this.InterfaceType.GetKeyProperties()[0]; - if (typeof(ILocalizedControlled).IsAssignableFrom(this.InterfaceType) == false) + if (!typeof(ILocalizedControlled).IsAssignableFrom(this.InterfaceType)) { this.ShowForeignItems = false; } @@ -1096,8 +1031,9 @@ protected override void OnInitialize() private bool LocalizationEnabled => - this.ShowForeignItems + ShowForeignItems && UserValidationFacade.IsLoggedIn() + && UserSettings.ForeignLocaleCultureInfo != null && !UserSettings.ActiveLocaleCultureInfo.Equals(UserSettings.ForeignLocaleCultureInfo); @@ -1139,7 +1075,7 @@ private static Type GetTupleType(int filedCount) /// public override string ToString() { - return string.Format("DataFolderElementsTreeNode, Id = {0}, DataType = {1}, FieldName = {2}, {3}", this.Id, this.InterfaceType, this.FieldName, this.ParentString()); + return $"DataFolderElementsTreeNode, Id = {this.Id}, DataType = {this.InterfaceType}, FieldName = {this.FieldName}, {this.ParentString()}"; } } } diff --git a/Composite/Core/Linq/ExpressionHelper.cs b/Composite/Core/Linq/ExpressionHelper.cs index 521e367b24..edf92441d3 100644 --- a/Composite/Core/Linq/ExpressionHelper.cs +++ b/Composite/Core/Linq/ExpressionHelper.cs @@ -8,26 +8,13 @@ namespace Composite.Core.Linq { - internal static class ExpressionHelper - { - public static List GetObjects(Type interfaceType, Expression sourceExpression) - { - List result = DataFacade.GetData(interfaceType).Provider.CreateQuery(sourceExpression).ToListOfObjects(); - - return result; - } - - - + internal static class ExpressionHelper + { public static List GetCastedObjects(Type interfaceType, Expression sourceExpression) { - List result = - DataFacade.GetData(interfaceType).Provider.CreateQuery(sourceExpression). - ToEnumerableOfObjects(). - Cast(). - ToList(); - - return result; + return DataFacade.GetData(interfaceType).Provider + .CreateQuery(sourceExpression) + .Cast().ToList(); } @@ -50,7 +37,7 @@ public static Expression CreatePropertyExpression(string fieldName, Expression p } } - throw new InvalidOperationException(string.Format("The interface '{0}' or any of its superinterfaces does not contain a field named '{1}'", parameterExpression.Type, fieldName)); + throw new InvalidOperationException($"The interface '{parameterExpression.Type}' or any of its superinterfaces does not contain a field named '{fieldName}'"); } @@ -59,7 +46,7 @@ public static Expression CreatePropertyExpression(Type currentInterfaceType, Typ { Expression fieldParameterExpression = GetPropertyParameterExpression(currentInterfaceType, actualPropertyDeclaringType, parameterExpression); - Expression expression = ExpressionHelper.CreatePropertyExpression(fieldName, fieldParameterExpression); + Expression expression = CreatePropertyExpression(fieldName, fieldParameterExpression); return expression; } @@ -148,10 +135,10 @@ public static Expression CreatePropertyPredicate(ParameterExpression parameterEx PropertyInfo propertyInfo = kvp.Item1; object value = kvp.Item2; - Expression left = LambdaExpression.Property(parameterExpression, propertyInfo); - Expression right = Expression.Constant(value); + var left = Expression.Property(parameterExpression, propertyInfo); + var right = Expression.Constant(value); - Expression filter = Expression.Equal(left, right); + var filter = Expression.Equal(left, right); currentExpression = currentExpression == null ? filter : Expression.And(currentExpression, filter); } From 7004a747d873995d10855b4d73448d8b7c707ebb Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 28 Feb 2017 17:24:16 +0100 Subject: [PATCH 039/135] Fixing a save button not working second time when editing page folder data and search package being installed --- .../DocumentSources/CmsPageDocumentSource.cs | 2 +- .../DataChangesIndexNotifier.cs | 75 ++++++++++++------- .../DocumentSources/DataTypeDocumentSource.cs | 55 +++++++------- .../MediaLibraryDocumentSource.cs | 2 +- 4 files changed, 81 insertions(+), 53 deletions(-) diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index 278b91d6bc..6a2023d28b 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -39,7 +39,7 @@ public CmsPageDocumentSource() _changesIndexNotifier = new DataChangesIndexNotifier( _listeners, typeof(IPage), - data => + (data, culture) => { var page = (IPage) data; var entityToken = GetAdministratedEntityToken(page); diff --git a/Composite/Search/DocumentSources/DataChangesIndexNotifier.cs b/Composite/Search/DocumentSources/DataChangesIndexNotifier.cs index a3b2920c7a..ad8ed622cf 100644 --- a/Composite/Search/DocumentSources/DataChangesIndexNotifier.cs +++ b/Composite/Search/DocumentSources/DataChangesIndexNotifier.cs @@ -12,16 +12,18 @@ namespace Composite.Search.DocumentSources { internal class DataChangesIndexNotifier { + const string LogTitle = nameof(DataChangesIndexNotifier); + private readonly IEnumerable _listeners; private readonly Type _interfaceType; - private Func GetDocument { get; } + private Func GetDocument { get; } private Func GetDocumentId { get; } public DataChangesIndexNotifier( IEnumerable listeners, Type interfaceType, - Func getDocumentFunc, + Func getDocumentFunc, Func getDocumentIdFunc) { _listeners = listeners; @@ -69,19 +71,26 @@ private void Data_OnAfterAdd(object sender, DataEventArgs dataEventArgs) { if (IgnoreNotification(dataEventArgs)) return; - var data = dataEventArgs.Data; - - if (IsPublishedDataFromUnpublishedScope(data)) + try { - return; - } + var data = dataEventArgs.Data; + + if (IsPublishedDataFromUnpublishedScope(data)) + { + return; + } - var document = GetDocument(data); - if(document == null) return; + foreach (var culture in GetCultures(data)) + { + var document = GetDocument(data, culture); + if (document == null) continue; - foreach (var culture in GetCultures(data)) + _listeners.ForEach(l => l.Create(culture, document)); + } + } + catch (Exception ex) { - _listeners.ForEach(l => l.Create(culture, document)); + Log.LogError(LogTitle, ex); } } @@ -89,21 +98,28 @@ private void Data_OnAfterUpdate(object sender, DataEventArgs dataEventArgs) { if (IgnoreNotification(dataEventArgs)) return; - var data = dataEventArgs.Data; - bool toBeDeleted = IsPublishedDataFromUnpublishedScope(data); - - if (toBeDeleted) + try { - DeleteDocuments(data); - return; + var data = dataEventArgs.Data; + bool toBeDeleted = IsPublishedDataFromUnpublishedScope(data); + + if (toBeDeleted) + { + DeleteDocuments(data); + return; + } + + foreach (var culture in GetCultures(data)) + { + var document = GetDocument(data, culture); + if (document == null) continue; + + _listeners.ForEach(l => l.Update(culture, document)); + } } - - var document = GetDocument(data); - if(document == null) return; - - foreach (var culture in GetCultures(data)) + catch (Exception ex) { - _listeners.ForEach(l => l.Update(culture, document)); + Log.LogError(LogTitle, ex); } } @@ -117,11 +133,18 @@ private void Data_OnDeleted(object sender, DataEventArgs dataEventArgs) private void DeleteDocuments(IData data) { - var documentId = GetDocumentId(data); + try + { + var documentId = GetDocumentId(data); - foreach (var culture in GetCultures(data)) + foreach (var culture in GetCultures(data)) + { + _listeners.ForEach(l => l.Delete(culture, documentId)); + } + } + catch (Exception ex) { - _listeners.ForEach(l => l.Delete(culture, documentId)); + Log.LogError(LogTitle, ex); } } diff --git a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs index a2ba6cce60..b6594917c4 100644 --- a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs +++ b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs @@ -60,7 +60,8 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) using (new DataConnection(PublicationScope.Published, culture)) { var dataSet = DataFacade.GetData(_interfaceType).Cast().Evaluate(); - foreach (var document in dataSet.Select(FromData).Where(doc => doc != null)) + + foreach (var document in dataSet.Select(d => FromData(d, culture)).Where(doc => doc != null)) { yield return document; } @@ -75,7 +76,8 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) .Where(data => data.PublicationStatus != GenericPublishProcessController.Published) .Evaluate(); - foreach (var document in dataSet.Select(FromData).Where(doc => doc != null)) + foreach (var document in dataSet.Select(data => FromData(data, culture)) + .Where(doc => doc != null)) { yield return document; } @@ -85,35 +87,38 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) public ICollection CustomFields => _customFields.Value; - private SearchDocument FromData(IData data) + private SearchDocument FromData(IData data, CultureInfo culture) { - string label = data.GetLabel(); - if (string.IsNullOrEmpty(label)) + using (new DataScope(culture)) { - // Having a label is a requirement for a data item to be searchable - return null; - } + string label = data.GetLabel(); + if (string.IsNullOrEmpty(label)) + { + // Having a label is a requirement for a data item to be searchable + return null; + } - var docBuilder = new SearchDocumentBuilder(); - docBuilder.CrawlData(data); - docBuilder.SetDataType(_interfaceType); + var docBuilder = new SearchDocumentBuilder(); + docBuilder.CrawlData(data); + docBuilder.SetDataType(_interfaceType); - string documentId = GetDocumentId(data); - string url = null; - if (InternalUrls.DataTypeSupported(data.DataSourceId.InterfaceType) - && (!_isPublishable || (data.DataSourceId.PublicationScope == PublicationScope.Published))) - { - url = InternalUrls.TryBuildInternalUrl(data.ToDataReference()); - } + string documentId = GetDocumentId(data); + string url = null; + if (InternalUrls.DataTypeSupported(data.DataSourceId.InterfaceType) + && (!_isPublishable || (data.DataSourceId.PublicationScope == PublicationScope.Published))) + { + url = InternalUrls.TryBuildInternalUrl(data.ToDataReference()); + } - var entityToken = GetConsoleEntityToken(data); - if (entityToken == null) - { - Log.LogWarning(LogTitle, $"Failed to obtain an entity token for a data item of type '{data.DataSourceId.InterfaceType}'"); - return null; - } + var entityToken = GetConsoleEntityToken(data); + if (entityToken == null) + { + Log.LogWarning(LogTitle, $"Failed to obtain an entity token for a data item of type '{data.DataSourceId.InterfaceType}'"); + return null; + } - return docBuilder.BuildDocument(Name, documentId, label, null, entityToken, url); + return docBuilder.BuildDocument(Name, documentId, label, null, entityToken, url); + } } private EntityToken GetConsoleEntityToken(IData data) diff --git a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs index 4fbc0d03d7..a37f67a33e 100644 --- a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs +++ b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs @@ -23,7 +23,7 @@ public MediaLibraryDocumentSource() _changesIndexNotifier = new DataChangesIndexNotifier( _listeners, typeof(IMediaFile), - data => FromMediaFile((IMediaFile)data), + (data, culture) => FromMediaFile((IMediaFile)data), data => ((IMediaFile)data).Id.ToString()); _changesIndexNotifier.Start(); } From c56d576cbdd326286d68d5942d7462ffe4c4c39e Mon Sep 17 00:00:00 2001 From: "david.abitbol@orckestra.com" Date: Wed, 1 Mar 2017 09:43:39 -0500 Subject: [PATCH 040/135] Optimized the code for the MediaURL to be calculated only at the workflow level leaving the interfaces as-is --- .../EditMediaFileWorkflow.cs | 3 ++- Composite/Data/Types/IMediaFile.cs | 5 ----- .../FileSystemMediaFile.cs | 11 +---------- .../Data/DataProviders/MediaFileProvider/MediaFile.cs | 7 ------- .../VirtualImageFileProvider/VirtualImageFile.cs | 9 +-------- .../WorkflowMediaFile.cs | 11 +---------- 6 files changed, 5 insertions(+), 41 deletions(-) diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs index 036226aa9e..a14eae3e6a 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/EditMediaFileWorkflow.cs @@ -28,10 +28,11 @@ private void initializeCodeActivity_ExecuteCode(object sender, EventArgs e) DataEntityToken token = (DataEntityToken)this.EntityToken; IMediaFile file = (IMediaFile)token.Data; IMediaFileStore store = DataFacade.GetData(x => x.Id == file.StoreId).First(); + var mediaURL = Composite.Core.Routing.MediaUrls.BuildUrl(file); this.Bindings.Add("FileDataFileName", file.FileName); this.Bindings.Add("FileDataTitle", file.Title); - this.Bindings.Add("FileDataURL", file.MediaURL); + this.Bindings.Add("FileDataURL", mediaURL); this.Bindings.Add("FileDataDescription", file.Description); this.Bindings.Add("FileDataTags", file.Tags); this.Bindings.Add("ProvidesMetaData", store.ProvidesMetadata); diff --git a/Composite/Data/Types/IMediaFile.cs b/Composite/Data/Types/IMediaFile.cs index 7061835745..7615e9185f 100644 --- a/Composite/Data/Types/IMediaFile.cs +++ b/Composite/Data/Types/IMediaFile.cs @@ -74,11 +74,6 @@ public interface IMediaFile : IFile [SearchableField(false, true, true)] string MimeType { get; } - /// - [ImmutableFieldId("{ae5be3d2-c239-48a0-a833-3d23a263a40f}")] - string MediaURL { get; } - - /// [ImmutableFieldId("{BCD0C1A2-9769-4209-8D43-DB7DDBABBB8B}")] [StoreFieldType(PhysicalStoreFieldType.Integer, IsNullable=true)] diff --git a/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs b/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs index a8b512da62..c96208687a 100644 --- a/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs +++ b/Composite/Plugins/Data/DataProviders/FileSystemMediaFileProvider/FileSystemMediaFile.cs @@ -65,16 +65,7 @@ public string StoreId set; } - public string MediaURL - { - get - { - return Composite.Core.Routing.MediaUrls.BuildUrl(this); - } - } - - - + public string Title { get diff --git a/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs b/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs index e4ce9cc421..afbb3ef48d 100644 --- a/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs +++ b/Composite/Plugins/Data/DataProviders/MediaFileProvider/MediaFile.cs @@ -51,13 +51,6 @@ public string CompositePath set { /* Do nothing. Used for deserialization purpouses */ } } - public string MediaURL { - get - { - return Composite.Core.Routing.MediaUrls.BuildUrl(this); - } - } - public string StoreId { get; diff --git a/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs b/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs index 9301c16603..0bac73312c 100644 --- a/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs +++ b/Composite/Plugins/Data/DataProviders/VirtualImageFileProvider/VirtualImageFile.cs @@ -100,14 +100,7 @@ public string Tags } } - public string MediaURL - { - get - { - return Composite.Core.Routing.MediaUrls.BuildUrl(this); - } - } - + public string Culture { get diff --git a/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs b/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs index 3f3c5151fc..1f182135c4 100644 --- a/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs +++ b/Composite/Plugins/Elements/ElementProviders/MediaFileProviderElementProvider/WorkflowMediaFile.cs @@ -127,16 +127,7 @@ public int? Length set; } - public string MediaURL - { - get - { - return Composite.Core.Routing.MediaUrls.BuildUrl(this); - } - } - - - + /// public DateTime? CreationTime { From 3c8e19048b4484a13cea7adf4faac2cea3e96857 Mon Sep 17 00:00:00 2001 From: "david.abitbol@orckestra.com" Date: Wed, 1 Mar 2017 15:29:08 -0500 Subject: [PATCH 041/135] Undid changes to jspm and package --- Website/jspm.config.js | 1734 ++++++++++++++++++++-------------------- Website/package.json | 23 +- 2 files changed, 876 insertions(+), 881 deletions(-) diff --git a/Website/jspm.config.js b/Website/jspm.config.js index af60c39915..6979f19882 100644 --- a/Website/jspm.config.js +++ b/Website/jspm.config.js @@ -1,878 +1,878 @@ SystemJS.config({ - paths: { - "console/": "Composite/console/", - "github:": "jspm_packages/github/", - "npm:": "jspm_packages/npm/", - "local:": "jspm_packages/local/", - "CMSConsole/": "Composite/" - }, - meta: { - "console/*": { - "format": "esm" - } - }, - browserConfig: { - "baseURL": "/" - }, - sassPluginOptions: { - "autoprefixer": true - }, - devConfig: { - "paths": { - "unittest/": "test/unit/" - }, - "meta": { - "unittest/*": { - "format": "esm" - } - }, - "map": { - "babel-runtime": "npm:babel-runtime@5.8.38", - "core-js": "npm:core-js@1.2.7", - "glob": "npm:glob@7.1.1", - "react-addons-test-utils": "npm:react-addons-test-utils@15.3.2", - "sinon": "npm:sinon@1.17.6", - "systemjs-hot-reloader": "github:capaj/systemjs-hot-reloader@0.6.0", - "systemjs-hot-reloader-store": "github:peteruithoven/systemjs-hot-reloader-store@1.0.0", - "unexpected-dom": "npm:unexpected-dom@3.1.0", - "unexpected-react": "npm:unexpected-react@3.2.4", - "unexpected-sinon": "npm:unexpected-sinon@10.5.1", - "source-map": "npm:source-map@0.2.0", - "jsbn": "npm:jsbn@0.1.0", - "tweetnacl": "npm:tweetnacl@0.13.3", - "jodid25519": "npm:jodid25519@1.0.2", - "ecc-jsbn": "npm:ecc-jsbn@0.1.1", - "dns": "npm:jspm-nodelibs-dns@0.2.0", - "dgram": "npm:jspm-nodelibs-dgram@0.2.0", - "babel-plugin-transform-react-jsx": "npm:babel-plugin-transform-react-jsx@6.8.0", - "unexpected-mitm": "npm:unexpected-mitm@9.3.4", - "zurvan": "npm:zurvan@0.3.2", - "unexpected-zurvan": "npm:unexpected-zurvan@0.1.0", - "react-immutable-proptypes": "npm:react-immutable-proptypes@2.1.0" - }, - "packages": { - "github:capaj/systemjs-hot-reloader@0.6.0": { - "map": { - "debug": "npm:debug@2.2.0", - "socket.io-client": "github:socketio/socket.io-client@1.5.0", - "weakee": "npm:weakee@1.0.0" - } - }, - "npm:amdefine@1.0.0": { - "map": {} - }, - "npm:babel-runtime@5.8.38": { - "map": {} - }, - "npm:brace-expansion@1.1.6": { - "map": { - "balanced-match": "npm:balanced-match@0.4.2", - "concat-map": "npm:concat-map@0.0.1" - } - }, - "npm:debug@2.2.0": { - "map": { - "ms": "npm:ms@0.7.1" - } - }, - "npm:ecc-jsbn@0.1.1": { - "map": { - "jsbn": "npm:jsbn@0.1.0" - } - }, - "npm:formatio@1.1.1": { - "map": { - "samsam": "npm:samsam@1.1.3" - } - }, - "npm:fs.realpath@1.0.0": { - "map": {} - }, - "npm:jodid25519@1.0.2": { - "map": { - "jsbn": "npm:jsbn@0.1.0" - } - }, - "npm:magicpen-prism@2.2.1": { - "map": {} - }, - "npm:source-map@0.2.0": { - "map": { - "amdefine": "npm:amdefine@1.0.0" - } - }, - "npm:unexpected-dom@3.1.0": { - "map": { - "extend": "npm:extend@3.0.0", - "magicpen-prism": "npm:magicpen-prism@2.2.1" - } - }, - "npm:unexpected-htmllike-jsx-adapter@1.0.0": { - "map": { - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:unexpected-htmllike-reactrendered-adapter@2.0.1": { - "map": { - "object-assign": "npm:object-assign@4.1.0", - "react-render-hook": "npm:react-render-hook@0.1.4" - } - }, - "npm:unexpected-htmllike@2.1.1": { - "map": { - "array-changes": "npm:array-changes@1.3.1", - "array-changes-async": "npm:array-changes-async@2.2.1", - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:util@0.10.3": { - "map": { - "inherits": "npm:inherits@2.0.1" - } - }, - "npm:babel-plugin-transform-react-jsx@6.8.0": { - "map": { - "babel-runtime": "npm:babel-runtime@6.11.6", - "babel-plugin-syntax-jsx": "npm:babel-plugin-syntax-jsx@6.13.0", - "babel-helper-builder-react-jsx": "npm:babel-helper-builder-react-jsx@6.9.0" - } - }, - "npm:babel-helper-builder-react-jsx@6.9.0": { - "map": { - "babel-runtime": "npm:babel-runtime@6.11.6", - "esutils": "npm:esutils@2.0.2", - "babel-types": "npm:babel-types@6.16.0", - "lodash": "npm:lodash@4.16.4" - } - }, - "npm:detect-indent@3.0.0": { - "map": { - "repeating": "npm:repeating@1.1.3", - "get-stdin": "npm:get-stdin@3.0.2", - "minimist": "npm:minimist@1.2.0" - } - }, - "npm:repeating@1.1.3": { - "map": { - "is-finite": "npm:is-finite@1.0.2" + paths: { + "console/": "Composite/console/", + "github:": "jspm_packages/github/", + "npm:": "jspm_packages/npm/", + "local:": "jspm_packages/local/", + "CMSConsole/": "Composite/" + }, + meta: { + "console/*": { + "format": "esm" } - }, - "npm:memoizesync@0.5.0": { - "map": { - "lru-cache": "npm:lru-cache@2.3.1" - } - }, - "npm:inherits@2.0.1": { - "map": {} - }, - "npm:unexpected-mitm@9.3.4": { - "map": { - "messy": "npm:messy@6.12.2", - "callsite": "npm:callsite@1.0.0", - "underscore": "npm:underscore@1.7.0", - "detect-indent": "npm:detect-indent@3.0.0", - "memoizesync": "npm:memoizesync@0.5.0", - "mitm-papandreou": "npm:mitm-papandreou@1.3.1-patch1" - } - }, - "npm:sinon@1.17.6": { - "map": { - "lolex": "npm:lolex@1.3.2", - "samsam": "npm:samsam@1.1.2", - "formatio": "npm:formatio@1.1.1", - "util": "npm:util@0.10.3" - } - }, - "npm:unexpected-react@3.2.4": { - "map": { - "react-render-hook": "npm:react-render-hook@0.1.4", - "unexpected-htmllike-reactrendered-adapter": "npm:unexpected-htmllike-reactrendered-adapter@2.0.1", - "unexpected-htmllike-jsx-adapter": "npm:unexpected-htmllike-jsx-adapter@1.0.0", - "unexpected-htmllike": "npm:unexpected-htmllike@2.1.1", - "magicpen-prism": "npm:magicpen-prism@2.2.1" - } - }, - "npm:glob@7.1.1": { - "map": { - "inflight": "npm:inflight@1.0.6", - "once": "npm:once@1.4.0", - "minimatch": "npm:minimatch@3.0.3", - "path-is-absolute": "npm:path-is-absolute@1.0.1", - "inherits": "npm:inherits@2.0.3", - "fs.realpath": "npm:fs.realpath@1.0.0" - } - }, - "npm:inflight@1.0.6": { - "map": { - "once": "npm:once@1.4.0", - "wrappy": "npm:wrappy@1.0.2" - } - }, - "npm:mitm-papandreou@1.3.1-patch1": { - "map": { - "underscore": "npm:underscore@1.5.2" - } - }, - "npm:minimatch@3.0.3": { - "map": { - "brace-expansion": "npm:brace-expansion@1.1.6" - } - }, - "npm:once@1.4.0": { - "map": { - "wrappy": "npm:wrappy@1.0.2" - } - }, - "npm:babel-types@6.16.0": { - "map": { - "babel-runtime": "npm:babel-runtime@6.11.6", - "esutils": "npm:esutils@2.0.2", - "lodash": "npm:lodash@4.16.4", - "to-fast-properties": "npm:to-fast-properties@1.0.2" - } - }, - "npm:array-changes@1.3.1": { - "map": { - "arraydiff-papandreou": "npm:arraydiff-papandreou@0.1.1-patch1" - } - }, - "npm:array-changes-async@2.2.1": { - "map": { - "arraydiff-async": "npm:arraydiff-async@0.2.0" - } - }, - "npm:is-finite@1.0.2": { + }, + browserConfig: { + "baseURL": "/" + }, + sassPluginOptions: { + "autoprefixer": true + }, + devConfig: { + "paths": { + "unittest/": "test/unit/" + }, + "meta": { + "unittest/*": { + "format": "esm" + } + }, "map": { - "number-is-nan": "npm:number-is-nan@1.0.1" + "babel-runtime": "npm:babel-runtime@5.8.38", + "core-js": "npm:core-js@1.2.7", + "glob": "npm:glob@7.1.1", + "react-addons-test-utils": "npm:react-addons-test-utils@15.3.2", + "sinon": "npm:sinon@1.17.6", + "systemjs-hot-reloader": "github:capaj/systemjs-hot-reloader@0.6.0", + "systemjs-hot-reloader-store": "github:peteruithoven/systemjs-hot-reloader-store@1.0.0", + "unexpected-dom": "npm:unexpected-dom@3.1.0", + "unexpected-react": "npm:unexpected-react@3.2.4", + "unexpected-sinon": "npm:unexpected-sinon@10.5.1", + "source-map": "npm:source-map@0.2.0", + "jsbn": "npm:jsbn@0.1.0", + "tweetnacl": "npm:tweetnacl@0.13.3", + "jodid25519": "npm:jodid25519@1.0.2", + "ecc-jsbn": "npm:ecc-jsbn@0.1.1", + "dns": "npm:jspm-nodelibs-dns@0.2.0", + "dgram": "npm:jspm-nodelibs-dgram@0.2.0", + "babel-plugin-transform-react-jsx": "npm:babel-plugin-transform-react-jsx@6.8.0", + "unexpected-mitm": "npm:unexpected-mitm@9.3.4", + "zurvan": "npm:zurvan@0.3.2", + "unexpected-zurvan": "npm:unexpected-zurvan@0.1.0", + "react-immutable-proptypes": "npm:react-immutable-proptypes@2.1.0" + }, + "packages": { + "github:capaj/systemjs-hot-reloader@0.6.0": { + "map": { + "debug": "npm:debug@2.2.0", + "socket.io-client": "github:socketio/socket.io-client@1.5.0", + "weakee": "npm:weakee@1.0.0" + } + }, + "npm:amdefine@1.0.0": { + "map": {} + }, + "npm:babel-runtime@5.8.38": { + "map": {} + }, + "npm:brace-expansion@1.1.6": { + "map": { + "balanced-match": "npm:balanced-match@0.4.2", + "concat-map": "npm:concat-map@0.0.1" + } + }, + "npm:debug@2.2.0": { + "map": { + "ms": "npm:ms@0.7.1" + } + }, + "npm:ecc-jsbn@0.1.1": { + "map": { + "jsbn": "npm:jsbn@0.1.0" + } + }, + "npm:formatio@1.1.1": { + "map": { + "samsam": "npm:samsam@1.1.3" + } + }, + "npm:fs.realpath@1.0.0": { + "map": {} + }, + "npm:jodid25519@1.0.2": { + "map": { + "jsbn": "npm:jsbn@0.1.0" + } + }, + "npm:magicpen-prism@2.2.1": { + "map": {} + }, + "npm:source-map@0.2.0": { + "map": { + "amdefine": "npm:amdefine@1.0.0" + } + }, + "npm:unexpected-dom@3.1.0": { + "map": { + "extend": "npm:extend@3.0.0", + "magicpen-prism": "npm:magicpen-prism@2.2.1" + } + }, + "npm:unexpected-htmllike-jsx-adapter@1.0.0": { + "map": { + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:unexpected-htmllike-reactrendered-adapter@2.0.1": { + "map": { + "object-assign": "npm:object-assign@4.1.0", + "react-render-hook": "npm:react-render-hook@0.1.4" + } + }, + "npm:unexpected-htmllike@2.1.1": { + "map": { + "array-changes": "npm:array-changes@1.3.1", + "array-changes-async": "npm:array-changes-async@2.2.1", + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:util@0.10.3": { + "map": { + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:babel-plugin-transform-react-jsx@6.8.0": { + "map": { + "babel-runtime": "npm:babel-runtime@6.11.6", + "babel-plugin-syntax-jsx": "npm:babel-plugin-syntax-jsx@6.13.0", + "babel-helper-builder-react-jsx": "npm:babel-helper-builder-react-jsx@6.9.0" + } + }, + "npm:babel-helper-builder-react-jsx@6.9.0": { + "map": { + "babel-runtime": "npm:babel-runtime@6.11.6", + "esutils": "npm:esutils@2.0.2", + "babel-types": "npm:babel-types@6.16.0", + "lodash": "npm:lodash@4.16.4" + } + }, + "npm:detect-indent@3.0.0": { + "map": { + "repeating": "npm:repeating@1.1.3", + "get-stdin": "npm:get-stdin@3.0.2", + "minimist": "npm:minimist@1.2.0" + } + }, + "npm:repeating@1.1.3": { + "map": { + "is-finite": "npm:is-finite@1.0.2" + } + }, + "npm:memoizesync@0.5.0": { + "map": { + "lru-cache": "npm:lru-cache@2.3.1" + } + }, + "npm:inherits@2.0.1": { + "map": {} + }, + "npm:unexpected-mitm@9.3.4": { + "map": { + "messy": "npm:messy@6.12.2", + "callsite": "npm:callsite@1.0.0", + "underscore": "npm:underscore@1.7.0", + "detect-indent": "npm:detect-indent@3.0.0", + "memoizesync": "npm:memoizesync@0.5.0", + "mitm-papandreou": "npm:mitm-papandreou@1.3.1-patch1" + } + }, + "npm:sinon@1.17.6": { + "map": { + "lolex": "npm:lolex@1.3.2", + "samsam": "npm:samsam@1.1.2", + "formatio": "npm:formatio@1.1.1", + "util": "npm:util@0.10.3" + } + }, + "npm:unexpected-react@3.2.4": { + "map": { + "react-render-hook": "npm:react-render-hook@0.1.4", + "unexpected-htmllike-reactrendered-adapter": "npm:unexpected-htmllike-reactrendered-adapter@2.0.1", + "unexpected-htmllike-jsx-adapter": "npm:unexpected-htmllike-jsx-adapter@1.0.0", + "unexpected-htmllike": "npm:unexpected-htmllike@2.1.1", + "magicpen-prism": "npm:magicpen-prism@2.2.1" + } + }, + "npm:glob@7.1.1": { + "map": { + "inflight": "npm:inflight@1.0.6", + "once": "npm:once@1.4.0", + "minimatch": "npm:minimatch@3.0.3", + "path-is-absolute": "npm:path-is-absolute@1.0.1", + "inherits": "npm:inherits@2.0.3", + "fs.realpath": "npm:fs.realpath@1.0.0" + } + }, + "npm:inflight@1.0.6": { + "map": { + "once": "npm:once@1.4.0", + "wrappy": "npm:wrappy@1.0.2" + } + }, + "npm:mitm-papandreou@1.3.1-patch1": { + "map": { + "underscore": "npm:underscore@1.5.2" + } + }, + "npm:minimatch@3.0.3": { + "map": { + "brace-expansion": "npm:brace-expansion@1.1.6" + } + }, + "npm:once@1.4.0": { + "map": { + "wrappy": "npm:wrappy@1.0.2" + } + }, + "npm:babel-types@6.16.0": { + "map": { + "babel-runtime": "npm:babel-runtime@6.11.6", + "esutils": "npm:esutils@2.0.2", + "lodash": "npm:lodash@4.16.4", + "to-fast-properties": "npm:to-fast-properties@1.0.2" + } + }, + "npm:array-changes@1.3.1": { + "map": { + "arraydiff-papandreou": "npm:arraydiff-papandreou@0.1.1-patch1" + } + }, + "npm:array-changes-async@2.2.1": { + "map": { + "arraydiff-async": "npm:arraydiff-async@0.2.0" + } + }, + "npm:is-finite@1.0.2": { + "map": { + "number-is-nan": "npm:number-is-nan@1.0.1" + } + }, + "npm:babel-runtime@6.11.6": { + "map": { + "core-js": "npm:core-js@2.4.1", + "regenerator-runtime": "npm:regenerator-runtime@0.9.5" + } + } } - }, - "npm:babel-runtime@6.11.6": { - "map": { - "core-js": "npm:core-js@2.4.1", - "regenerator-runtime": "npm:regenerator-runtime@0.9.5" + }, + transpiler: "plugin-babel", + babelOptions: { + "optional": [ + "runtime", + "optimisation.modules.system" + ], + "sourceMaps": true, + "plugins": [ + "babel-plugin-transform-react-jsx" + ] + }, + trace: true, + map: { + "jsdom": "node_modules/jsdom/lib/jsdom.js" + }, + packages: { + "CMSConsole": { + "main": "console/console.js", + "format": "esm" } - } } - }, - transpiler: "plugin-babel", - babelOptions: { - "optional": [ - "runtime", - "optimisation.modules.system" - ], - "sourceMaps": true, - "plugins": [ - "babel-plugin-transform-react-jsx" - ] - }, - trace: true, - map: { - "jsdom": "node_modules/jsdom/lib/jsdom.js" - }, - packages: { - "CMSConsole": { - "main": "console/console.js", - "format": "esm" - } - } }); SystemJS.config({ - packageConfigPaths: [ - "npm:@*/*.json", - "npm:*.json", - "github:*/*.json", - "local:*.json" - ], - map: { - "fixed-data-table-2": "npm:fixed-data-table-2@0.7.6", - "immutable": "npm:immutable@3.8.1", - "github/url-polyfill": "github:github/url-polyfill@0.5.6", - "bluebird": "npm:bluebird@3.4.6", - "module": "npm:jspm-nodelibs-module@0.2.0", - "plugin-babel": "npm:systemjs-plugin-babel@0.0.13", - "magicpen-media": "npm:magicpen-media@1.5.1", - "messy": "npm:messy@6.12.2", - "net": "npm:jspm-nodelibs-net@0.2.0", - "os": "github:jspm/nodelibs-os@0.2.0-alpha", - "punycode": "npm:jspm-nodelibs-punycode@0.2.0", - "querystring": "npm:jspm-nodelibs-querystring@0.2.0", - "rc-table": "npm:rc-table@5.0.3", - "react": "npm:react@15.3.2", - "react-dimensions": "npm:react-dimensions@1.3.0", - "react-dom": "npm:react-dom@15.3.2", - "react-select": "npm:react-select@1.0.0-rc.2", - "redux-immutablejs": "npm:redux-immutablejs@0.0.8", - "redux-observer": "npm:redux-observer@1.0.0", - "repl": "npm:jspm-nodelibs-repl@0.2.0", - "reselect": "npm:reselect@2.5.4", - "styled-components": "npm:styled-components@1.1.1", - "text": "github:systemjs/plugin-text@0.0.9", - "tls": "npm:jspm-nodelibs-tls@0.2.0", - "tty": "npm:jspm-nodelibs-tty@0.2.0", - "unexpected": "npm:unexpected@10.18.1", - "unexpected-messy": "npm:unexpected-messy@6.2.0", - "constants": "npm:jspm-nodelibs-constants@0.2.0", - "assert": "npm:jspm-nodelibs-assert@0.2.0", - "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha", - "child_process": "github:jspm/nodelibs-child_process@0.2.0-alpha", - "crypto": "github:jspm/nodelibs-crypto@0.2.0-alpha", - "domain": "github:jspm/nodelibs-domain@0.2.0-alpha", - "events": "github:jspm/nodelibs-events@0.2.0-alpha", - "fs": "github:jspm/nodelibs-fs@0.2.0-alpha", - "http": "github:jspm/nodelibs-http@0.2.0-alpha", - "https": "github:jspm/nodelibs-https@0.2.0-alpha", - "path": "github:jspm/nodelibs-path@0.2.0-alpha", - "process": "github:jspm/nodelibs-process@0.2.0-alpha", - "stream": "github:jspm/nodelibs-stream@0.2.0-alpha", - "string_decoder": "github:jspm/nodelibs-string_decoder@0.2.0-alpha", - "normalizr": "npm:normalizr@2.2.1", - "react-redux": "npm:react-redux@4.4.5", - "redux": "npm:redux@3.6.0", - "redux-thunk": "npm:redux-thunk@2.1.0", - "svg": "github:npbenjohnson/plugin-svg@0.1.0", - "url": "github:jspm/nodelibs-url@0.2.0-alpha", - "url-polyfill": "github:github/url-polyfill@0.5.6", - "util": "github:jspm/nodelibs-util@0.2.0-alpha", - "vm": "github:jspm/nodelibs-vm@0.2.0-alpha", - "wampy": "npm:wampy@4.0.0", - "whatwg-fetch": "npm:whatwg-fetch@1.1.1", - "zlib": "github:jspm/nodelibs-zlib@0.2.0-alpha" - }, - packages: { - "npm:bn.js@4.11.6": { - "map": {} - }, - "npm:browserify-aes@1.0.6": { - "map": { - "buffer-xor": "npm:buffer-xor@1.0.3", - "cipher-base": "npm:cipher-base@1.0.3", - "create-hash": "npm:create-hash@1.1.2", - "evp_bytestokey": "npm:evp_bytestokey@1.0.0", - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:browserify-cipher@1.0.0": { - "map": { - "browserify-aes": "npm:browserify-aes@1.0.6", - "browserify-des": "npm:browserify-des@1.0.0", - "evp_bytestokey": "npm:evp_bytestokey@1.0.0" - } - }, - "npm:browserify-des@1.0.0": { - "map": { - "cipher-base": "npm:cipher-base@1.0.3", - "des.js": "npm:des.js@1.0.0", - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:browserify-rsa@4.0.1": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:browserify-sign@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "browserify-rsa": "npm:browserify-rsa@4.0.1", - "create-hash": "npm:create-hash@1.1.2", - "create-hmac": "npm:create-hmac@1.1.4", - "elliptic": "npm:elliptic@6.3.2", - "inherits": "npm:inherits@2.0.3", - "parse-asn1": "npm:parse-asn1@5.0.0" - } - }, - "npm:browserify-zlib@0.1.4": { - "map": { - "pako": "npm:pako@0.2.9", - "readable-stream": "npm:readable-stream@2.2.2" - } - }, - "npm:buffer-xor@1.0.3": { - "map": {} - }, - "npm:core-util-is@1.0.2": { - "map": {} - }, - "npm:create-ecdh@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "elliptic": "npm:elliptic@6.3.2" - } - }, - "npm:create-hash@1.1.2": { - "map": { - "cipher-base": "npm:cipher-base@1.0.3", - "inherits": "npm:inherits@2.0.3", - "ripemd160": "npm:ripemd160@1.0.1", - "sha.js": "npm:sha.js@2.4.8" - } - }, - "npm:create-hmac@1.1.4": { - "map": { - "create-hash": "npm:create-hash@1.1.2", - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:crypto-browserify@3.11.0": { - "map": { - "browserify-cipher": "npm:browserify-cipher@1.0.0", - "browserify-sign": "npm:browserify-sign@4.0.0", - "create-ecdh": "npm:create-ecdh@4.0.0", - "create-hash": "npm:create-hash@1.1.2", - "create-hmac": "npm:create-hmac@1.1.4", - "diffie-hellman": "npm:diffie-hellman@5.0.2", - "inherits": "npm:inherits@2.0.3", - "pbkdf2": "npm:pbkdf2@3.0.9", - "public-encrypt": "npm:public-encrypt@4.0.0", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:des.js@1.0.0": { - "map": { - "inherits": "npm:inherits@2.0.3", - "minimalistic-assert": "npm:minimalistic-assert@1.0.0" - } - }, - "npm:diffie-hellman@5.0.2": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "miller-rabin": "npm:miller-rabin@4.0.0", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:domain-browser@1.1.7": { - "map": {} - }, - "npm:evp_bytestokey@1.0.0": { - "map": { - "create-hash": "npm:create-hash@1.1.2" - } - }, - "npm:has-flag@1.0.0": { - "map": {} - }, - "npm:hash.js@1.0.3": { - "map": { - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:iconv-lite@0.4.13": { - "map": {} - }, - "npm:invariant@2.2.1": { - "map": { - "loose-envify": "npm:loose-envify@1.2.0" - } - }, - "npm:loose-envify@1.2.0": { - "map": { - "js-tokens": "npm:js-tokens@1.0.3" - } - }, - "npm:miller-rabin@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "brorand": "npm:brorand@1.0.6" - } - }, - "npm:normalizr@2.2.1": { - "map": { - "lodash": "npm:lodash@4.16.4" - } - }, - "npm:pako@0.2.9": { - "map": {} - }, - "npm:parse-asn1@5.0.0": { - "map": { - "asn1.js": "npm:asn1.js@4.9.0", - "browserify-aes": "npm:browserify-aes@1.0.6", - "create-hash": "npm:create-hash@1.1.2", - "evp_bytestokey": "npm:evp_bytestokey@1.0.0", - "pbkdf2": "npm:pbkdf2@3.0.9" - } - }, - "npm:process-nextick-args@1.0.7": { - "map": {} - }, - "npm:public-encrypt@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "browserify-rsa": "npm:browserify-rsa@4.0.1", - "create-hash": "npm:create-hash@1.1.2", - "parse-asn1": "npm:parse-asn1@5.0.0", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:punycode@1.3.2": { - "map": {} - }, - "npm:randombytes@2.0.3": { - "map": {} - }, - "npm:react-redux@4.4.5": { - "map": { - "hoist-non-react-statics": "npm:hoist-non-react-statics@1.2.0", - "invariant": "npm:invariant@2.2.1", - "lodash": "npm:lodash@4.16.4", - "loose-envify": "npm:loose-envify@1.2.0" - } - }, - "npm:ripemd160@1.0.1": { - "map": {} - }, - "npm:string_decoder@0.10.31": { - "map": {} - }, - "npm:supports-color@3.1.2": { - "map": { - "has-flag": "npm:has-flag@1.0.0" - } - }, - "npm:util-deprecate@1.0.2": { - "map": {} - }, - "npm:url@0.11.0": { - "map": { - "punycode": "npm:punycode@1.3.2", - "querystring": "npm:querystring@0.2.0" - } - }, - "npm:stream-browserify@2.0.1": { - "map": { - "inherits": "npm:inherits@2.0.3", - "readable-stream": "npm:readable-stream@2.2.2" - } - }, - "npm:gettemporaryfilepath@0.0.1": { - "map": {} - }, - "npm:iconv-lite@0.4.5": { - "map": {} - }, - "npm:lodash@3.10.0": { - "map": {} - }, - "npm:magicpen-media@1.5.1": { - "map": { - "gettemporaryfilepath": "npm:gettemporaryfilepath@0.0.1", - "lodash": "npm:lodash@3.10.0", - "mime": "npm:mime@1.3.4" - } - }, - "npm:mime@1.3.4": { - "map": {} - }, - "npm:quoted-printable@1.0.0": { - "map": { - "utf8": "npm:utf8@2.1.2" - } - }, - "npm:rfc2047@2.0.0": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.5" - } - }, - "npm:rfc2231@1.3.0": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.5" - } - }, - "npm:buffer@4.9.1": { - "map": { - "base64-js": "npm:base64-js@1.2.0", - "ieee754": "npm:ieee754@1.1.8", - "isarray": "npm:isarray@1.0.0" - } - }, - "npm:elliptic@6.3.2": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "inherits": "npm:inherits@2.0.3", - "brorand": "npm:brorand@1.0.6", - "hash.js": "npm:hash.js@1.0.3" - } - }, - "npm:cipher-base@1.0.3": { - "map": { - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:pbkdf2@3.0.9": { - "map": { - "create-hmac": "npm:create-hmac@1.1.4" - } - }, - "npm:rc-table@5.0.3": { - "map": { - "shallowequal": "npm:shallowequal@0.2.2", - "object-path": "npm:object-path@0.11.2", - "rc-util": "npm:rc-util@3.4.1" - } - }, - "npm:rc-util@3.4.1": { - "map": { - "shallowequal": "npm:shallowequal@0.2.2", - "add-dom-event-listener": "npm:add-dom-event-listener@1.0.1", - "classnames": "npm:classnames@2.2.5" - } - }, - "npm:shallowequal@0.2.2": { - "map": { - "lodash.keys": "npm:lodash.keys@3.1.2" - } - }, - "npm:add-dom-event-listener@1.0.1": { - "map": { - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:lodash.keys@3.1.2": { - "map": { - "lodash._getnative": "npm:lodash._getnative@3.9.1", - "lodash.isarray": "npm:lodash.isarray@3.0.4", - "lodash.isarguments": "npm:lodash.isarguments@3.1.0" - } - }, - "npm:react-dimensions@1.3.0": { - "map": { - "element-resize-event": "npm:element-resize-event@2.0.7" - } - }, - "npm:messy@6.12.2": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.13", - "underscore": "npm:underscore@1.8.3", - "rfc2231": "npm:rfc2231@1.3.0", - "quoted-printable": "npm:quoted-printable@1.0.0", - "rfc2047": "npm:rfc2047@2.0.0" - } - }, - "npm:unexpected-messy@6.2.0": { - "map": { - "underscore": "npm:underscore@1.7.0", - "minimist": "npm:minimist@1.1.1" - } - }, - "npm:redux@3.6.0": { - "map": { - "symbol-observable": "npm:symbol-observable@1.0.4", - "loose-envify": "npm:loose-envify@1.2.0", - "lodash-es": "npm:lodash-es@4.16.4", - "lodash": "npm:lodash@4.16.4" - } - }, - "npm:react-select@1.0.0-rc.2": { - "map": { - "react-input-autosize": "npm:react-input-autosize@1.1.0", - "classnames": "npm:classnames@2.2.5" - } - }, - "npm:core-js@1.2.7": { - "map": {} - }, - "npm:react@15.3.2": { - "map": { - "fbjs": "npm:fbjs@0.8.6", - "loose-envify": "npm:loose-envify@1.3.0", - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:isomorphic-fetch@2.2.1": { - "map": { - "node-fetch": "npm:node-fetch@1.6.3", - "whatwg-fetch": "npm:whatwg-fetch@1.1.1" - } - }, - "npm:promise@7.1.1": { - "map": { - "asap": "npm:asap@2.0.5" - } - }, - "npm:node-fetch@1.6.3": { - "map": { - "is-stream": "npm:is-stream@1.1.0", - "encoding": "npm:encoding@0.1.12" - } - }, - "npm:encoding@0.1.12": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.15" - } - }, - "npm:readable-stream@2.2.2": { - "map": { - "core-util-is": "npm:core-util-is@1.0.2", - "isarray": "npm:isarray@1.0.0", - "inherits": "npm:inherits@2.0.3", - "string_decoder": "npm:string_decoder@0.10.31", - "process-nextick-args": "npm:process-nextick-args@1.0.7", - "util-deprecate": "npm:util-deprecate@1.0.2", - "buffer-shims": "npm:buffer-shims@1.0.0" - } - }, - "npm:stream-http@2.5.0": { - "map": { - "inherits": "npm:inherits@2.0.3", - "readable-stream": "npm:readable-stream@2.2.2", - "builtin-status-codes": "npm:builtin-status-codes@2.0.0", - "to-arraybuffer": "npm:to-arraybuffer@1.0.1", - "xtend": "npm:xtend@4.0.1" - } - }, - "npm:sha.js@2.4.8": { - "map": { - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:asn1.js@4.9.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "inherits": "npm:inherits@2.0.3", - "minimalistic-assert": "npm:minimalistic-assert@1.0.0" - } - }, - "npm:wampy@4.0.0": { - "main": "build/wampy.js", - "map": { - "websocket": "npm:websocket@1.0.23", - "msgpack5": "npm:msgpack5@3.4.1" - } - }, - "npm:websocket@1.0.23": { - "map": { - "yaeti": "npm:yaeti@0.0.4", - "debug": "npm:debug@2.3.2", - "typedarray-to-buffer": "npm:typedarray-to-buffer@3.1.2", - "nan": "npm:nan@2.4.0" - } - }, - "npm:msgpack5@3.4.1": { - "map": { - "inherits": "npm:inherits@2.0.3", - "readable-stream": "npm:readable-stream@2.2.2", - "bl": "npm:bl@1.1.2" - } - }, - "npm:debug@2.3.2": { - "map": { - "ms": "npm:ms@0.7.2" - } - }, - "npm:bl@1.1.2": { - "map": { - "readable-stream": "npm:readable-stream@2.0.6" - } - }, - "npm:typedarray-to-buffer@3.1.2": { - "map": { - "is-typedarray": "npm:is-typedarray@1.0.0" - } - }, - "npm:readable-stream@2.0.6": { - "map": { - "core-util-is": "npm:core-util-is@1.0.2", - "inherits": "npm:inherits@2.0.3", - "isarray": "npm:isarray@1.0.0", - "process-nextick-args": "npm:process-nextick-args@1.0.7", - "string_decoder": "npm:string_decoder@0.10.31", - "util-deprecate": "npm:util-deprecate@1.0.2" - } - }, - "npm:fbjs@0.8.6": { - "map": { - "loose-envify": "npm:loose-envify@1.3.0", - "object-assign": "npm:object-assign@4.1.0", - "core-js": "npm:core-js@1.2.7", - "isomorphic-fetch": "npm:isomorphic-fetch@2.2.1", - "promise": "npm:promise@7.1.1", - "ua-parser-js": "npm:ua-parser-js@0.7.12" - } - }, - "npm:loose-envify@1.3.0": { - "map": { - "js-tokens": "npm:js-tokens@2.0.0" - } - }, - "npm:styled-components@1.1.1": { - "map": { - "buffer": "npm:buffer@5.0.1", - "fbjs": "npm:fbjs@0.8.6", - "supports-color": "npm:supports-color@3.1.2", - "glamor": "npm:glamor@2.19.0", - "lodash": "npm:lodash@4.17.2", - "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" - } - }, - "npm:glamor@2.19.0": { - "map": { - "fbjs": "npm:fbjs@0.8.6", - "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" - } - }, - "npm:buffer@5.0.1": { - "map": { - "ieee754": "npm:ieee754@1.1.8", - "base64-js": "npm:base64-js@1.2.0" - } - }, - "npm:inline-style-prefixer@2.0.4": { - "map": { - "bowser": "npm:bowser@1.5.0", - "hyphenate-style-name": "npm:hyphenate-style-name@1.0.2" - } - }, - "npm:jspm-nodelibs-punycode@0.2.0": { - "map": { - "punycode-browserify": "npm:punycode@1.4.1" - } - }, - "github:jspm/nodelibs-http@0.2.0-alpha": { - "map": { - "http-browserify": "npm:stream-http@2.5.0" - } - }, - "github:jspm/nodelibs-buffer@0.2.0-alpha": { - "map": { - "buffer-browserify": "npm:buffer@4.9.1" - } - }, - "github:jspm/nodelibs-stream@0.2.0-alpha": { - "map": { - "stream-browserify": "npm:stream-browserify@2.0.1" - } - }, - "github:jspm/nodelibs-url@0.2.0-alpha": { - "map": { - "url-browserify": "npm:url@0.11.0" - } - }, - "github:jspm/nodelibs-domain@0.2.0-alpha": { - "map": { - "domain-browserify": "npm:domain-browser@1.1.7" - } - }, - "github:jspm/nodelibs-os@0.2.0-alpha": { - "map": { - "os-browserify": "npm:os-browserify@0.2.1" - } - }, - "github:jspm/nodelibs-zlib@0.2.0-alpha": { - "map": { - "zlib-browserify": "npm:browserify-zlib@0.1.4" - } - }, - "github:jspm/nodelibs-string_decoder@0.2.0-alpha": { - "map": { - "string_decoder-browserify": "npm:string_decoder@0.10.31" - } - }, - "github:jspm/nodelibs-crypto@0.2.0-alpha": { - "map": { - "crypto-browserify": "npm:crypto-browserify@3.11.0" - } + packageConfigPaths: [ + "npm:@*/*.json", + "npm:*.json", + "github:*/*.json", + "local:*.json" + ], + map: { + "fixed-data-table-2": "npm:fixed-data-table-2@0.7.6", + "immutable": "npm:immutable@3.8.1", + "github/url-polyfill": "github:github/url-polyfill@0.5.6", + "bluebird": "npm:bluebird@3.4.6", + "module": "npm:jspm-nodelibs-module@0.2.0", + "plugin-babel": "npm:systemjs-plugin-babel@0.0.13", + "magicpen-media": "npm:magicpen-media@1.5.1", + "messy": "npm:messy@6.12.2", + "net": "npm:jspm-nodelibs-net@0.2.0", + "os": "npm:jspm-nodelibs-os@0.2.0", + "punycode": "npm:jspm-nodelibs-punycode@0.2.0", + "querystring": "npm:jspm-nodelibs-querystring@0.2.0", + "rc-table": "npm:rc-table@5.0.3", + "react": "npm:react@15.3.2", + "react-dimensions": "npm:react-dimensions@1.3.0", + "react-dom": "npm:react-dom@15.3.2", + "react-select": "npm:react-select@1.0.0-rc.2", + "redux-immutablejs": "npm:redux-immutablejs@0.0.8", + "redux-observer": "npm:redux-observer@1.0.0", + "repl": "npm:jspm-nodelibs-repl@0.2.0", + "reselect": "npm:reselect@2.5.4", + "styled-components": "npm:styled-components@1.1.1", + "text": "github:systemjs/plugin-text@0.0.9", + "tls": "npm:jspm-nodelibs-tls@0.2.0", + "tty": "npm:jspm-nodelibs-tty@0.2.0", + "unexpected": "npm:unexpected@10.18.1", + "unexpected-messy": "npm:unexpected-messy@6.2.0", + "constants": "npm:jspm-nodelibs-constants@0.2.0", + "assert": "npm:jspm-nodelibs-assert@0.2.0", + "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha", + "child_process": "npm:jspm-nodelibs-child_process@0.2.0", + "crypto": "npm:jspm-nodelibs-crypto@0.2.0", + "domain": "npm:jspm-nodelibs-domain@0.2.0", + "events": "github:jspm/nodelibs-events@0.2.0-alpha", + "fs": "github:jspm/nodelibs-fs@0.2.0-alpha", + "http": "github:jspm/nodelibs-http@0.2.0-alpha", + "https": "npm:jspm-nodelibs-https@0.2.0", + "path": "github:jspm/nodelibs-path@0.2.0-alpha", + "process": "github:jspm/nodelibs-process@0.2.0-alpha", + "stream": "github:jspm/nodelibs-stream@0.2.0-alpha", + "string_decoder": "npm:jspm-nodelibs-string_decoder@0.2.0", + "normalizr": "npm:normalizr@2.2.1", + "react-redux": "npm:react-redux@4.4.5", + "redux": "npm:redux@3.6.0", + "redux-thunk": "npm:redux-thunk@2.1.0", + "svg": "github:npbenjohnson/plugin-svg@0.1.0", + "url": "github:jspm/nodelibs-url@0.2.0-alpha", + "url-polyfill": "github:github/url-polyfill@0.5.6", + "util": "github:jspm/nodelibs-util@0.2.0-alpha", + "vm": "npm:jspm-nodelibs-vm@0.2.0", + "wampy": "npm:wampy@4.0.0", + "whatwg-fetch": "npm:whatwg-fetch@1.1.1", + "zlib": "npm:jspm-nodelibs-zlib@0.2.0" + }, + packages: { + "npm:bn.js@4.11.6": { + "map": {} + }, + "npm:browserify-aes@1.0.6": { + "map": { + "buffer-xor": "npm:buffer-xor@1.0.3", + "cipher-base": "npm:cipher-base@1.0.3", + "create-hash": "npm:create-hash@1.1.2", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0", + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:browserify-cipher@1.0.0": { + "map": { + "browserify-aes": "npm:browserify-aes@1.0.6", + "browserify-des": "npm:browserify-des@1.0.0", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0" + } + }, + "npm:browserify-des@1.0.0": { + "map": { + "cipher-base": "npm:cipher-base@1.0.3", + "des.js": "npm:des.js@1.0.0", + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:browserify-rsa@4.0.1": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:browserify-sign@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "browserify-rsa": "npm:browserify-rsa@4.0.1", + "create-hash": "npm:create-hash@1.1.2", + "create-hmac": "npm:create-hmac@1.1.4", + "elliptic": "npm:elliptic@6.3.2", + "inherits": "npm:inherits@2.0.3", + "parse-asn1": "npm:parse-asn1@5.0.0" + } + }, + "npm:browserify-zlib@0.1.4": { + "map": { + "pako": "npm:pako@0.2.9", + "readable-stream": "npm:readable-stream@2.2.2" + } + }, + "npm:buffer-xor@1.0.3": { + "map": {} + }, + "npm:core-util-is@1.0.2": { + "map": {} + }, + "npm:create-ecdh@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "elliptic": "npm:elliptic@6.3.2" + } + }, + "npm:create-hash@1.1.2": { + "map": { + "cipher-base": "npm:cipher-base@1.0.3", + "inherits": "npm:inherits@2.0.3", + "ripemd160": "npm:ripemd160@1.0.1", + "sha.js": "npm:sha.js@2.4.8" + } + }, + "npm:create-hmac@1.1.4": { + "map": { + "create-hash": "npm:create-hash@1.1.2", + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:crypto-browserify@3.11.0": { + "map": { + "browserify-cipher": "npm:browserify-cipher@1.0.0", + "browserify-sign": "npm:browserify-sign@4.0.0", + "create-ecdh": "npm:create-ecdh@4.0.0", + "create-hash": "npm:create-hash@1.1.2", + "create-hmac": "npm:create-hmac@1.1.4", + "diffie-hellman": "npm:diffie-hellman@5.0.2", + "inherits": "npm:inherits@2.0.3", + "pbkdf2": "npm:pbkdf2@3.0.9", + "public-encrypt": "npm:public-encrypt@4.0.0", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:des.js@1.0.0": { + "map": { + "inherits": "npm:inherits@2.0.3", + "minimalistic-assert": "npm:minimalistic-assert@1.0.0" + } + }, + "npm:diffie-hellman@5.0.2": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "miller-rabin": "npm:miller-rabin@4.0.0", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:domain-browser@1.1.7": { + "map": {} + }, + "npm:evp_bytestokey@1.0.0": { + "map": { + "create-hash": "npm:create-hash@1.1.2" + } + }, + "npm:has-flag@1.0.0": { + "map": {} + }, + "npm:hash.js@1.0.3": { + "map": { + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:iconv-lite@0.4.13": { + "map": {} + }, + "npm:invariant@2.2.1": { + "map": { + "loose-envify": "npm:loose-envify@1.2.0" + } + }, + "npm:loose-envify@1.2.0": { + "map": { + "js-tokens": "npm:js-tokens@1.0.3" + } + }, + "npm:miller-rabin@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "brorand": "npm:brorand@1.0.6" + } + }, + "npm:normalizr@2.2.1": { + "map": { + "lodash": "npm:lodash@4.16.4" + } + }, + "npm:pako@0.2.9": { + "map": {} + }, + "npm:parse-asn1@5.0.0": { + "map": { + "asn1.js": "npm:asn1.js@4.9.0", + "browserify-aes": "npm:browserify-aes@1.0.6", + "create-hash": "npm:create-hash@1.1.2", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0", + "pbkdf2": "npm:pbkdf2@3.0.9" + } + }, + "npm:process-nextick-args@1.0.7": { + "map": {} + }, + "npm:public-encrypt@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "browserify-rsa": "npm:browserify-rsa@4.0.1", + "create-hash": "npm:create-hash@1.1.2", + "parse-asn1": "npm:parse-asn1@5.0.0", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:punycode@1.3.2": { + "map": {} + }, + "npm:randombytes@2.0.3": { + "map": {} + }, + "npm:react-redux@4.4.5": { + "map": { + "hoist-non-react-statics": "npm:hoist-non-react-statics@1.2.0", + "invariant": "npm:invariant@2.2.1", + "lodash": "npm:lodash@4.16.4", + "loose-envify": "npm:loose-envify@1.2.0" + } + }, + "npm:ripemd160@1.0.1": { + "map": {} + }, + "npm:string_decoder@0.10.31": { + "map": {} + }, + "npm:supports-color@3.1.2": { + "map": { + "has-flag": "npm:has-flag@1.0.0" + } + }, + "npm:util-deprecate@1.0.2": { + "map": {} + }, + "npm:url@0.11.0": { + "map": { + "punycode": "npm:punycode@1.3.2", + "querystring": "npm:querystring@0.2.0" + } + }, + "npm:stream-browserify@2.0.1": { + "map": { + "inherits": "npm:inherits@2.0.3", + "readable-stream": "npm:readable-stream@2.2.2" + } + }, + "npm:gettemporaryfilepath@0.0.1": { + "map": {} + }, + "npm:iconv-lite@0.4.5": { + "map": {} + }, + "npm:lodash@3.10.0": { + "map": {} + }, + "npm:magicpen-media@1.5.1": { + "map": { + "gettemporaryfilepath": "npm:gettemporaryfilepath@0.0.1", + "lodash": "npm:lodash@3.10.0", + "mime": "npm:mime@1.3.4" + } + }, + "npm:mime@1.3.4": { + "map": {} + }, + "npm:quoted-printable@1.0.0": { + "map": { + "utf8": "npm:utf8@2.1.2" + } + }, + "npm:rfc2047@2.0.0": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.5" + } + }, + "npm:rfc2231@1.3.0": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.5" + } + }, + "npm:buffer@4.9.1": { + "map": { + "base64-js": "npm:base64-js@1.2.0", + "ieee754": "npm:ieee754@1.1.8", + "isarray": "npm:isarray@1.0.0" + } + }, + "npm:elliptic@6.3.2": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "inherits": "npm:inherits@2.0.3", + "brorand": "npm:brorand@1.0.6", + "hash.js": "npm:hash.js@1.0.3" + } + }, + "npm:cipher-base@1.0.3": { + "map": { + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:pbkdf2@3.0.9": { + "map": { + "create-hmac": "npm:create-hmac@1.1.4" + } + }, + "npm:rc-table@5.0.3": { + "map": { + "shallowequal": "npm:shallowequal@0.2.2", + "object-path": "npm:object-path@0.11.2", + "rc-util": "npm:rc-util@3.4.1" + } + }, + "npm:rc-util@3.4.1": { + "map": { + "shallowequal": "npm:shallowequal@0.2.2", + "add-dom-event-listener": "npm:add-dom-event-listener@1.0.1", + "classnames": "npm:classnames@2.2.5" + } + }, + "npm:shallowequal@0.2.2": { + "map": { + "lodash.keys": "npm:lodash.keys@3.1.2" + } + }, + "npm:add-dom-event-listener@1.0.1": { + "map": { + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:lodash.keys@3.1.2": { + "map": { + "lodash._getnative": "npm:lodash._getnative@3.9.1", + "lodash.isarray": "npm:lodash.isarray@3.0.4", + "lodash.isarguments": "npm:lodash.isarguments@3.1.0" + } + }, + "npm:react-dimensions@1.3.0": { + "map": { + "element-resize-event": "npm:element-resize-event@2.0.7" + } + }, + "npm:messy@6.12.2": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.13", + "underscore": "npm:underscore@1.8.3", + "rfc2231": "npm:rfc2231@1.3.0", + "quoted-printable": "npm:quoted-printable@1.0.0", + "rfc2047": "npm:rfc2047@2.0.0" + } + }, + "npm:unexpected-messy@6.2.0": { + "map": { + "underscore": "npm:underscore@1.7.0", + "minimist": "npm:minimist@1.1.1" + } + }, + "npm:redux@3.6.0": { + "map": { + "symbol-observable": "npm:symbol-observable@1.0.4", + "loose-envify": "npm:loose-envify@1.2.0", + "lodash-es": "npm:lodash-es@4.16.4", + "lodash": "npm:lodash@4.16.4" + } + }, + "npm:react-select@1.0.0-rc.2": { + "map": { + "react-input-autosize": "npm:react-input-autosize@1.1.0", + "classnames": "npm:classnames@2.2.5" + } + }, + "npm:core-js@1.2.7": { + "map": {} + }, + "npm:react@15.3.2": { + "map": { + "fbjs": "npm:fbjs@0.8.6", + "loose-envify": "npm:loose-envify@1.3.0", + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:isomorphic-fetch@2.2.1": { + "map": { + "node-fetch": "npm:node-fetch@1.6.3", + "whatwg-fetch": "npm:whatwg-fetch@1.1.1" + } + }, + "npm:promise@7.1.1": { + "map": { + "asap": "npm:asap@2.0.5" + } + }, + "npm:node-fetch@1.6.3": { + "map": { + "is-stream": "npm:is-stream@1.1.0", + "encoding": "npm:encoding@0.1.12" + } + }, + "npm:encoding@0.1.12": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.15" + } + }, + "npm:readable-stream@2.2.2": { + "map": { + "core-util-is": "npm:core-util-is@1.0.2", + "isarray": "npm:isarray@1.0.0", + "inherits": "npm:inherits@2.0.3", + "string_decoder": "npm:string_decoder@0.10.31", + "process-nextick-args": "npm:process-nextick-args@1.0.7", + "util-deprecate": "npm:util-deprecate@1.0.2", + "buffer-shims": "npm:buffer-shims@1.0.0" + } + }, + "npm:stream-http@2.5.0": { + "map": { + "inherits": "npm:inherits@2.0.3", + "readable-stream": "npm:readable-stream@2.2.2", + "builtin-status-codes": "npm:builtin-status-codes@2.0.0", + "to-arraybuffer": "npm:to-arraybuffer@1.0.1", + "xtend": "npm:xtend@4.0.1" + } + }, + "npm:sha.js@2.4.8": { + "map": { + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:asn1.js@4.9.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "inherits": "npm:inherits@2.0.3", + "minimalistic-assert": "npm:minimalistic-assert@1.0.0" + } + }, + "npm:wampy@4.0.0": { + "main": "build/wampy.js", + "map": { + "websocket": "npm:websocket@1.0.23", + "msgpack5": "npm:msgpack5@3.4.1" + } + }, + "npm:websocket@1.0.23": { + "map": { + "yaeti": "npm:yaeti@0.0.4", + "debug": "npm:debug@2.3.2", + "typedarray-to-buffer": "npm:typedarray-to-buffer@3.1.2", + "nan": "npm:nan@2.4.0" + } + }, + "npm:msgpack5@3.4.1": { + "map": { + "inherits": "npm:inherits@2.0.3", + "readable-stream": "npm:readable-stream@2.2.2", + "bl": "npm:bl@1.1.2" + } + }, + "npm:debug@2.3.2": { + "map": { + "ms": "npm:ms@0.7.2" + } + }, + "npm:bl@1.1.2": { + "map": { + "readable-stream": "npm:readable-stream@2.0.6" + } + }, + "npm:typedarray-to-buffer@3.1.2": { + "map": { + "is-typedarray": "npm:is-typedarray@1.0.0" + } + }, + "npm:readable-stream@2.0.6": { + "map": { + "core-util-is": "npm:core-util-is@1.0.2", + "inherits": "npm:inherits@2.0.3", + "isarray": "npm:isarray@1.0.0", + "process-nextick-args": "npm:process-nextick-args@1.0.7", + "string_decoder": "npm:string_decoder@0.10.31", + "util-deprecate": "npm:util-deprecate@1.0.2" + } + }, + "npm:fbjs@0.8.6": { + "map": { + "loose-envify": "npm:loose-envify@1.3.0", + "object-assign": "npm:object-assign@4.1.0", + "core-js": "npm:core-js@1.2.7", + "isomorphic-fetch": "npm:isomorphic-fetch@2.2.1", + "promise": "npm:promise@7.1.1", + "ua-parser-js": "npm:ua-parser-js@0.7.12" + } + }, + "npm:loose-envify@1.3.0": { + "map": { + "js-tokens": "npm:js-tokens@2.0.0" + } + }, + "npm:styled-components@1.1.1": { + "map": { + "buffer": "npm:buffer@5.0.1", + "fbjs": "npm:fbjs@0.8.6", + "supports-color": "npm:supports-color@3.1.2", + "glamor": "npm:glamor@2.19.0", + "lodash": "npm:lodash@4.17.2", + "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" + } + }, + "npm:glamor@2.19.0": { + "map": { + "fbjs": "npm:fbjs@0.8.6", + "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" + } + }, + "npm:buffer@5.0.1": { + "map": { + "ieee754": "npm:ieee754@1.1.8", + "base64-js": "npm:base64-js@1.2.0" + } + }, + "npm:inline-style-prefixer@2.0.4": { + "map": { + "bowser": "npm:bowser@1.5.0", + "hyphenate-style-name": "npm:hyphenate-style-name@1.0.2" + } + }, + "npm:jspm-nodelibs-punycode@0.2.0": { + "map": { + "punycode-browserify": "npm:punycode@1.4.1" + } + }, + "npm:jspm-nodelibs-domain@0.2.0": { + "map": { + "domain-browserify": "npm:domain-browser@1.1.7" + } + }, + "npm:jspm-nodelibs-crypto@0.2.0": { + "map": { + "crypto-browserify": "npm:crypto-browserify@3.11.0" + } + }, + "npm:jspm-nodelibs-zlib@0.2.0": { + "map": { + "zlib-browserify": "npm:browserify-zlib@0.1.4" + } + }, + "npm:jspm-nodelibs-string_decoder@0.2.0": { + "map": { + "string_decoder-browserify": "npm:string_decoder@0.10.31" + } + }, + "npm:jspm-nodelibs-os@0.2.0": { + "map": { + "os-browserify": "npm:os-browserify@0.2.1" + } + }, + "github:jspm/nodelibs-http@0.2.0-alpha": { + "map": { + "http-browserify": "npm:stream-http@2.5.0" + } + }, + "github:jspm/nodelibs-buffer@0.2.0-alpha": { + "map": { + "buffer-browserify": "npm:buffer@4.9.1" + } + }, + "github:jspm/nodelibs-stream@0.2.0-alpha": { + "map": { + "stream-browserify": "npm:stream-browserify@2.0.1" + } + }, + "github:jspm/nodelibs-url@0.2.0-alpha": { + "map": { + "url-browserify": "npm:url@0.11.0" + } + } } - } }); diff --git a/Website/package.json b/Website/package.json index 3df4409518..e8a976bf69 100644 --- a/Website/package.json +++ b/Website/package.json @@ -79,7 +79,7 @@ "react-immutable-proptypes": "npm:react-immutable-proptypes@^2.1.0", "sinon": "npm:sinon@^1.17.5", "source-map": "npm:source-map@0.2", - "systemjs-hot-reloader": "github:alexisvincent/systemjs-hot-reloader@^0.6.0", + "systemjs-hot-reloader": "github:capaj/systemjs-hot-reloader@^0.6.0", "systemjs-hot-reloader-store": "github:peteruithoven/systemjs-hot-reloader-store@^1.0.0", "tweetnacl": "npm:tweetnacl@0.13", "unexpected-dom": "npm:unexpected-dom@^3.1.0", @@ -93,20 +93,20 @@ "assert": "npm:jspm-nodelibs-assert@^0.2.0", "bluebird": "npm:bluebird@^3.0.0", "buffer": "github:jspm/nodelibs-buffer@^0.2.0-alpha", - "child_process": "github:jspm/nodelibs-child_process@^0.2.0-alpha", + "child_process": "npm:jspm-nodelibs-child_process@^0.2.0", "constants": "npm:jspm-nodelibs-constants@^0.2.0", - "crypto": "github:jspm/nodelibs-crypto@^0.2.0-alpha", - "domain": "github:jspm/nodelibs-domain@^0.2.0-alpha", + "crypto": "npm:jspm-nodelibs-crypto@^0.2.0", + "domain": "npm:jspm-nodelibs-domain@^0.2.0", "events": "github:jspm/nodelibs-events@^0.2.0-alpha", "fs": "github:jspm/nodelibs-fs@^0.2.0-alpha", "http": "github:jspm/nodelibs-http@^0.2.0-alpha", - "https": "github:jspm/nodelibs-https@^0.2.0-alpha", + "https": "npm:jspm-nodelibs-https@^0.2.0", "immutable": "npm:immutable@^3.8.1", "magicpen-media": "npm:magicpen-media@^1.5.0", "messy": "npm:messy@^6.12.0", "module": "npm:jspm-nodelibs-module@^0.2.0", "net": "npm:jspm-nodelibs-net@^0.2.0", - "os": "github:jspm/nodelibs-os@^0.2.0-alpha", + "os": "npm:jspm-nodelibs-os@^0.2.0", "path": "github:jspm/nodelibs-path@^0.2.0-alpha", "process": "github:jspm/nodelibs-process@^0.2.0-alpha", "punycode": "npm:jspm-nodelibs-punycode@^0.2.0", @@ -116,15 +116,15 @@ "redux": "npm:redux@^3.5.2", "repl": "npm:jspm-nodelibs-repl@^0.2.0", "stream": "github:jspm/nodelibs-stream@^0.2.0-alpha", - "string_decoder": "github:jspm/nodelibs-string_decoder@^0.2.0-alpha", + "string_decoder": "npm:jspm-nodelibs-string_decoder@^0.2.0", "tls": "npm:jspm-nodelibs-tls@^0.2.0", "tty": "npm:jspm-nodelibs-tty@^0.2.0", "unexpected": "npm:unexpected@^10.10.0", "unexpected-messy": "npm:unexpected-messy@^6.0.0", "url": "github:jspm/nodelibs-url@^0.2.0-alpha", "util": "github:jspm/nodelibs-util@^0.2.0-alpha", - "vm": "github:jspm/nodelibs-vm@^0.2.0-alpha", - "zlib": "github:jspm/nodelibs-zlib@^0.2.0-alpha" + "vm": "npm:jspm-nodelibs-vm@^0.2.0", + "zlib": "npm:jspm-nodelibs-zlib@^0.2.0" }, "overrides": { "github:github/url-polyfill@0.5.6": { @@ -226,11 +226,6 @@ "lodash": "^4.15.0", "supports-color": "^3.1.2" } - }, - "npm:unexpected@10.18.1": { - "main": "unexpected.js", - "dependencies": {}, - "jspmPackage": true } } } From 1276afcff5d65bb4e9f47d858d3d270efc5f8edd Mon Sep 17 00:00:00 2001 From: dabitbol Date: Wed, 1 Mar 2017 15:35:17 -0500 Subject: [PATCH 042/135] Update jspm.config.js --- Website/jspm.config.js | 1734 ++++++++++++++++++++-------------------- 1 file changed, 867 insertions(+), 867 deletions(-) diff --git a/Website/jspm.config.js b/Website/jspm.config.js index 6979f19882..b4b8603e6c 100644 --- a/Website/jspm.config.js +++ b/Website/jspm.config.js @@ -1,878 +1,878 @@ SystemJS.config({ - paths: { - "console/": "Composite/console/", - "github:": "jspm_packages/github/", - "npm:": "jspm_packages/npm/", - "local:": "jspm_packages/local/", - "CMSConsole/": "Composite/" - }, - meta: { - "console/*": { - "format": "esm" - } + paths: { + "console/": "Composite/console/", + "github:": "jspm_packages/github/", + "npm:": "jspm_packages/npm/", + "local:": "jspm_packages/local/", + "CMSConsole/": "Composite/" + }, + meta: { + "console/*": { + "format": "esm" + } + }, + browserConfig: { + "baseURL": "/" + }, + sassPluginOptions: { + "autoprefixer": true + }, + devConfig: { + "paths": { + "unittest/": "test/unit/" + }, + "meta": { + "unittest/*": { + "format": "esm" + } }, - browserConfig: { - "baseURL": "/" - }, - sassPluginOptions: { - "autoprefixer": true - }, - devConfig: { - "paths": { - "unittest/": "test/unit/" - }, - "meta": { - "unittest/*": { - "format": "esm" - } - }, + "map": { + "babel-runtime": "npm:babel-runtime@5.8.38", + "core-js": "npm:core-js@1.2.7", + "glob": "npm:glob@7.1.1", + "react-addons-test-utils": "npm:react-addons-test-utils@15.3.2", + "sinon": "npm:sinon@1.17.6", + "systemjs-hot-reloader": "github:capaj/systemjs-hot-reloader@0.6.0", + "systemjs-hot-reloader-store": "github:peteruithoven/systemjs-hot-reloader-store@1.0.0", + "unexpected-dom": "npm:unexpected-dom@3.1.0", + "unexpected-react": "npm:unexpected-react@3.2.4", + "unexpected-sinon": "npm:unexpected-sinon@10.5.1", + "source-map": "npm:source-map@0.2.0", + "jsbn": "npm:jsbn@0.1.0", + "tweetnacl": "npm:tweetnacl@0.13.3", + "jodid25519": "npm:jodid25519@1.0.2", + "ecc-jsbn": "npm:ecc-jsbn@0.1.1", + "dns": "npm:jspm-nodelibs-dns@0.2.0", + "dgram": "npm:jspm-nodelibs-dgram@0.2.0", + "babel-plugin-transform-react-jsx": "npm:babel-plugin-transform-react-jsx@6.8.0", + "unexpected-mitm": "npm:unexpected-mitm@9.3.4", + "zurvan": "npm:zurvan@0.3.2", + "unexpected-zurvan": "npm:unexpected-zurvan@0.1.0", + "react-immutable-proptypes": "npm:react-immutable-proptypes@2.1.0" + }, + "packages": { + "github:capaj/systemjs-hot-reloader@0.6.0": { "map": { - "babel-runtime": "npm:babel-runtime@5.8.38", - "core-js": "npm:core-js@1.2.7", - "glob": "npm:glob@7.1.1", - "react-addons-test-utils": "npm:react-addons-test-utils@15.3.2", - "sinon": "npm:sinon@1.17.6", - "systemjs-hot-reloader": "github:capaj/systemjs-hot-reloader@0.6.0", - "systemjs-hot-reloader-store": "github:peteruithoven/systemjs-hot-reloader-store@1.0.0", - "unexpected-dom": "npm:unexpected-dom@3.1.0", - "unexpected-react": "npm:unexpected-react@3.2.4", - "unexpected-sinon": "npm:unexpected-sinon@10.5.1", - "source-map": "npm:source-map@0.2.0", - "jsbn": "npm:jsbn@0.1.0", - "tweetnacl": "npm:tweetnacl@0.13.3", - "jodid25519": "npm:jodid25519@1.0.2", - "ecc-jsbn": "npm:ecc-jsbn@0.1.1", - "dns": "npm:jspm-nodelibs-dns@0.2.0", - "dgram": "npm:jspm-nodelibs-dgram@0.2.0", - "babel-plugin-transform-react-jsx": "npm:babel-plugin-transform-react-jsx@6.8.0", - "unexpected-mitm": "npm:unexpected-mitm@9.3.4", - "zurvan": "npm:zurvan@0.3.2", - "unexpected-zurvan": "npm:unexpected-zurvan@0.1.0", - "react-immutable-proptypes": "npm:react-immutable-proptypes@2.1.0" - }, - "packages": { - "github:capaj/systemjs-hot-reloader@0.6.0": { - "map": { - "debug": "npm:debug@2.2.0", - "socket.io-client": "github:socketio/socket.io-client@1.5.0", - "weakee": "npm:weakee@1.0.0" - } - }, - "npm:amdefine@1.0.0": { - "map": {} - }, - "npm:babel-runtime@5.8.38": { - "map": {} - }, - "npm:brace-expansion@1.1.6": { - "map": { - "balanced-match": "npm:balanced-match@0.4.2", - "concat-map": "npm:concat-map@0.0.1" - } - }, - "npm:debug@2.2.0": { - "map": { - "ms": "npm:ms@0.7.1" - } - }, - "npm:ecc-jsbn@0.1.1": { - "map": { - "jsbn": "npm:jsbn@0.1.0" - } - }, - "npm:formatio@1.1.1": { - "map": { - "samsam": "npm:samsam@1.1.3" - } - }, - "npm:fs.realpath@1.0.0": { - "map": {} - }, - "npm:jodid25519@1.0.2": { - "map": { - "jsbn": "npm:jsbn@0.1.0" - } - }, - "npm:magicpen-prism@2.2.1": { - "map": {} - }, - "npm:source-map@0.2.0": { - "map": { - "amdefine": "npm:amdefine@1.0.0" - } - }, - "npm:unexpected-dom@3.1.0": { - "map": { - "extend": "npm:extend@3.0.0", - "magicpen-prism": "npm:magicpen-prism@2.2.1" - } - }, - "npm:unexpected-htmllike-jsx-adapter@1.0.0": { - "map": { - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:unexpected-htmllike-reactrendered-adapter@2.0.1": { - "map": { - "object-assign": "npm:object-assign@4.1.0", - "react-render-hook": "npm:react-render-hook@0.1.4" - } - }, - "npm:unexpected-htmllike@2.1.1": { - "map": { - "array-changes": "npm:array-changes@1.3.1", - "array-changes-async": "npm:array-changes-async@2.2.1", - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:util@0.10.3": { - "map": { - "inherits": "npm:inherits@2.0.1" - } - }, - "npm:babel-plugin-transform-react-jsx@6.8.0": { - "map": { - "babel-runtime": "npm:babel-runtime@6.11.6", - "babel-plugin-syntax-jsx": "npm:babel-plugin-syntax-jsx@6.13.0", - "babel-helper-builder-react-jsx": "npm:babel-helper-builder-react-jsx@6.9.0" - } - }, - "npm:babel-helper-builder-react-jsx@6.9.0": { - "map": { - "babel-runtime": "npm:babel-runtime@6.11.6", - "esutils": "npm:esutils@2.0.2", - "babel-types": "npm:babel-types@6.16.0", - "lodash": "npm:lodash@4.16.4" - } - }, - "npm:detect-indent@3.0.0": { - "map": { - "repeating": "npm:repeating@1.1.3", - "get-stdin": "npm:get-stdin@3.0.2", - "minimist": "npm:minimist@1.2.0" - } - }, - "npm:repeating@1.1.3": { - "map": { - "is-finite": "npm:is-finite@1.0.2" - } - }, - "npm:memoizesync@0.5.0": { - "map": { - "lru-cache": "npm:lru-cache@2.3.1" - } - }, - "npm:inherits@2.0.1": { - "map": {} - }, - "npm:unexpected-mitm@9.3.4": { - "map": { - "messy": "npm:messy@6.12.2", - "callsite": "npm:callsite@1.0.0", - "underscore": "npm:underscore@1.7.0", - "detect-indent": "npm:detect-indent@3.0.0", - "memoizesync": "npm:memoizesync@0.5.0", - "mitm-papandreou": "npm:mitm-papandreou@1.3.1-patch1" - } - }, - "npm:sinon@1.17.6": { - "map": { - "lolex": "npm:lolex@1.3.2", - "samsam": "npm:samsam@1.1.2", - "formatio": "npm:formatio@1.1.1", - "util": "npm:util@0.10.3" - } - }, - "npm:unexpected-react@3.2.4": { - "map": { - "react-render-hook": "npm:react-render-hook@0.1.4", - "unexpected-htmllike-reactrendered-adapter": "npm:unexpected-htmllike-reactrendered-adapter@2.0.1", - "unexpected-htmllike-jsx-adapter": "npm:unexpected-htmllike-jsx-adapter@1.0.0", - "unexpected-htmllike": "npm:unexpected-htmllike@2.1.1", - "magicpen-prism": "npm:magicpen-prism@2.2.1" - } - }, - "npm:glob@7.1.1": { - "map": { - "inflight": "npm:inflight@1.0.6", - "once": "npm:once@1.4.0", - "minimatch": "npm:minimatch@3.0.3", - "path-is-absolute": "npm:path-is-absolute@1.0.1", - "inherits": "npm:inherits@2.0.3", - "fs.realpath": "npm:fs.realpath@1.0.0" - } - }, - "npm:inflight@1.0.6": { - "map": { - "once": "npm:once@1.4.0", - "wrappy": "npm:wrappy@1.0.2" - } - }, - "npm:mitm-papandreou@1.3.1-patch1": { - "map": { - "underscore": "npm:underscore@1.5.2" - } - }, - "npm:minimatch@3.0.3": { - "map": { - "brace-expansion": "npm:brace-expansion@1.1.6" - } - }, - "npm:once@1.4.0": { - "map": { - "wrappy": "npm:wrappy@1.0.2" - } - }, - "npm:babel-types@6.16.0": { - "map": { - "babel-runtime": "npm:babel-runtime@6.11.6", - "esutils": "npm:esutils@2.0.2", - "lodash": "npm:lodash@4.16.4", - "to-fast-properties": "npm:to-fast-properties@1.0.2" - } - }, - "npm:array-changes@1.3.1": { - "map": { - "arraydiff-papandreou": "npm:arraydiff-papandreou@0.1.1-patch1" - } - }, - "npm:array-changes-async@2.2.1": { - "map": { - "arraydiff-async": "npm:arraydiff-async@0.2.0" - } - }, - "npm:is-finite@1.0.2": { - "map": { - "number-is-nan": "npm:number-is-nan@1.0.1" - } - }, - "npm:babel-runtime@6.11.6": { - "map": { - "core-js": "npm:core-js@2.4.1", - "regenerator-runtime": "npm:regenerator-runtime@0.9.5" - } - } + "debug": "npm:debug@2.2.0", + "socket.io-client": "github:socketio/socket.io-client@1.5.0", + "weakee": "npm:weakee@1.0.0" } - }, - transpiler: "plugin-babel", - babelOptions: { - "optional": [ - "runtime", - "optimisation.modules.system" - ], - "sourceMaps": true, - "plugins": [ - "babel-plugin-transform-react-jsx" - ] - }, - trace: true, - map: { - "jsdom": "node_modules/jsdom/lib/jsdom.js" - }, - packages: { - "CMSConsole": { - "main": "console/console.js", - "format": "esm" + }, + "npm:amdefine@1.0.0": { + "map": {} + }, + "npm:babel-runtime@5.8.38": { + "map": {} + }, + "npm:brace-expansion@1.1.6": { + "map": { + "balanced-match": "npm:balanced-match@0.4.2", + "concat-map": "npm:concat-map@0.0.1" + } + }, + "npm:debug@2.2.0": { + "map": { + "ms": "npm:ms@0.7.1" + } + }, + "npm:ecc-jsbn@0.1.1": { + "map": { + "jsbn": "npm:jsbn@0.1.0" + } + }, + "npm:formatio@1.1.1": { + "map": { + "samsam": "npm:samsam@1.1.3" + } + }, + "npm:fs.realpath@1.0.0": { + "map": {} + }, + "npm:jodid25519@1.0.2": { + "map": { + "jsbn": "npm:jsbn@0.1.0" + } + }, + "npm:magicpen-prism@2.2.1": { + "map": {} + }, + "npm:source-map@0.2.0": { + "map": { + "amdefine": "npm:amdefine@1.0.0" + } + }, + "npm:unexpected-dom@3.1.0": { + "map": { + "extend": "npm:extend@3.0.0", + "magicpen-prism": "npm:magicpen-prism@2.2.1" + } + }, + "npm:unexpected-htmllike-jsx-adapter@1.0.0": { + "map": { + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:unexpected-htmllike-reactrendered-adapter@2.0.1": { + "map": { + "object-assign": "npm:object-assign@4.1.0", + "react-render-hook": "npm:react-render-hook@0.1.4" + } + }, + "npm:unexpected-htmllike@2.1.1": { + "map": { + "array-changes": "npm:array-changes@1.3.1", + "array-changes-async": "npm:array-changes-async@2.2.1", + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:util@0.10.3": { + "map": { + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:babel-plugin-transform-react-jsx@6.8.0": { + "map": { + "babel-runtime": "npm:babel-runtime@6.11.6", + "babel-plugin-syntax-jsx": "npm:babel-plugin-syntax-jsx@6.13.0", + "babel-helper-builder-react-jsx": "npm:babel-helper-builder-react-jsx@6.9.0" + } + }, + "npm:babel-helper-builder-react-jsx@6.9.0": { + "map": { + "babel-runtime": "npm:babel-runtime@6.11.6", + "esutils": "npm:esutils@2.0.2", + "babel-types": "npm:babel-types@6.16.0", + "lodash": "npm:lodash@4.16.4" + } + }, + "npm:detect-indent@3.0.0": { + "map": { + "repeating": "npm:repeating@1.1.3", + "get-stdin": "npm:get-stdin@3.0.2", + "minimist": "npm:minimist@1.2.0" + } + }, + "npm:repeating@1.1.3": { + "map": { + "is-finite": "npm:is-finite@1.0.2" + } + }, + "npm:memoizesync@0.5.0": { + "map": { + "lru-cache": "npm:lru-cache@2.3.1" + } + }, + "npm:inherits@2.0.1": { + "map": {} + }, + "npm:unexpected-mitm@9.3.4": { + "map": { + "messy": "npm:messy@6.12.2", + "callsite": "npm:callsite@1.0.0", + "underscore": "npm:underscore@1.7.0", + "detect-indent": "npm:detect-indent@3.0.0", + "memoizesync": "npm:memoizesync@0.5.0", + "mitm-papandreou": "npm:mitm-papandreou@1.3.1-patch1" + } + }, + "npm:sinon@1.17.6": { + "map": { + "lolex": "npm:lolex@1.3.2", + "samsam": "npm:samsam@1.1.2", + "formatio": "npm:formatio@1.1.1", + "util": "npm:util@0.10.3" } + }, + "npm:unexpected-react@3.2.4": { + "map": { + "react-render-hook": "npm:react-render-hook@0.1.4", + "unexpected-htmllike-reactrendered-adapter": "npm:unexpected-htmllike-reactrendered-adapter@2.0.1", + "unexpected-htmllike-jsx-adapter": "npm:unexpected-htmllike-jsx-adapter@1.0.0", + "unexpected-htmllike": "npm:unexpected-htmllike@2.1.1", + "magicpen-prism": "npm:magicpen-prism@2.2.1" + } + }, + "npm:glob@7.1.1": { + "map": { + "inflight": "npm:inflight@1.0.6", + "once": "npm:once@1.4.0", + "minimatch": "npm:minimatch@3.0.3", + "path-is-absolute": "npm:path-is-absolute@1.0.1", + "inherits": "npm:inherits@2.0.3", + "fs.realpath": "npm:fs.realpath@1.0.0" + } + }, + "npm:inflight@1.0.6": { + "map": { + "once": "npm:once@1.4.0", + "wrappy": "npm:wrappy@1.0.2" + } + }, + "npm:mitm-papandreou@1.3.1-patch1": { + "map": { + "underscore": "npm:underscore@1.5.2" + } + }, + "npm:minimatch@3.0.3": { + "map": { + "brace-expansion": "npm:brace-expansion@1.1.6" + } + }, + "npm:once@1.4.0": { + "map": { + "wrappy": "npm:wrappy@1.0.2" + } + }, + "npm:babel-types@6.16.0": { + "map": { + "babel-runtime": "npm:babel-runtime@6.11.6", + "esutils": "npm:esutils@2.0.2", + "lodash": "npm:lodash@4.16.4", + "to-fast-properties": "npm:to-fast-properties@1.0.2" + } + }, + "npm:array-changes@1.3.1": { + "map": { + "arraydiff-papandreou": "npm:arraydiff-papandreou@0.1.1-patch1" + } + }, + "npm:array-changes-async@2.2.1": { + "map": { + "arraydiff-async": "npm:arraydiff-async@0.2.0" + } + }, + "npm:is-finite@1.0.2": { + "map": { + "number-is-nan": "npm:number-is-nan@1.0.1" + } + }, + "npm:babel-runtime@6.11.6": { + "map": { + "core-js": "npm:core-js@2.4.1", + "regenerator-runtime": "npm:regenerator-runtime@0.9.5" + } + } } + }, + transpiler: "plugin-babel", + babelOptions: { + "optional": [ + "runtime", + "optimisation.modules.system" + ], + "sourceMaps": true, + "plugins": [ + "babel-plugin-transform-react-jsx" + ] + }, + trace: true, + map: { + "jsdom": "node_modules/jsdom/lib/jsdom.js" + }, + packages: { + "CMSConsole": { + "main": "console/console.js", + "format": "esm" + } + } }); SystemJS.config({ - packageConfigPaths: [ - "npm:@*/*.json", - "npm:*.json", - "github:*/*.json", - "local:*.json" - ], - map: { - "fixed-data-table-2": "npm:fixed-data-table-2@0.7.6", - "immutable": "npm:immutable@3.8.1", - "github/url-polyfill": "github:github/url-polyfill@0.5.6", - "bluebird": "npm:bluebird@3.4.6", - "module": "npm:jspm-nodelibs-module@0.2.0", - "plugin-babel": "npm:systemjs-plugin-babel@0.0.13", - "magicpen-media": "npm:magicpen-media@1.5.1", - "messy": "npm:messy@6.12.2", - "net": "npm:jspm-nodelibs-net@0.2.0", - "os": "npm:jspm-nodelibs-os@0.2.0", - "punycode": "npm:jspm-nodelibs-punycode@0.2.0", - "querystring": "npm:jspm-nodelibs-querystring@0.2.0", - "rc-table": "npm:rc-table@5.0.3", - "react": "npm:react@15.3.2", - "react-dimensions": "npm:react-dimensions@1.3.0", - "react-dom": "npm:react-dom@15.3.2", - "react-select": "npm:react-select@1.0.0-rc.2", - "redux-immutablejs": "npm:redux-immutablejs@0.0.8", - "redux-observer": "npm:redux-observer@1.0.0", - "repl": "npm:jspm-nodelibs-repl@0.2.0", - "reselect": "npm:reselect@2.5.4", - "styled-components": "npm:styled-components@1.1.1", - "text": "github:systemjs/plugin-text@0.0.9", - "tls": "npm:jspm-nodelibs-tls@0.2.0", - "tty": "npm:jspm-nodelibs-tty@0.2.0", - "unexpected": "npm:unexpected@10.18.1", - "unexpected-messy": "npm:unexpected-messy@6.2.0", - "constants": "npm:jspm-nodelibs-constants@0.2.0", - "assert": "npm:jspm-nodelibs-assert@0.2.0", - "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha", - "child_process": "npm:jspm-nodelibs-child_process@0.2.0", - "crypto": "npm:jspm-nodelibs-crypto@0.2.0", - "domain": "npm:jspm-nodelibs-domain@0.2.0", - "events": "github:jspm/nodelibs-events@0.2.0-alpha", - "fs": "github:jspm/nodelibs-fs@0.2.0-alpha", - "http": "github:jspm/nodelibs-http@0.2.0-alpha", - "https": "npm:jspm-nodelibs-https@0.2.0", - "path": "github:jspm/nodelibs-path@0.2.0-alpha", - "process": "github:jspm/nodelibs-process@0.2.0-alpha", - "stream": "github:jspm/nodelibs-stream@0.2.0-alpha", - "string_decoder": "npm:jspm-nodelibs-string_decoder@0.2.0", - "normalizr": "npm:normalizr@2.2.1", - "react-redux": "npm:react-redux@4.4.5", - "redux": "npm:redux@3.6.0", - "redux-thunk": "npm:redux-thunk@2.1.0", - "svg": "github:npbenjohnson/plugin-svg@0.1.0", - "url": "github:jspm/nodelibs-url@0.2.0-alpha", - "url-polyfill": "github:github/url-polyfill@0.5.6", - "util": "github:jspm/nodelibs-util@0.2.0-alpha", - "vm": "npm:jspm-nodelibs-vm@0.2.0", - "wampy": "npm:wampy@4.0.0", - "whatwg-fetch": "npm:whatwg-fetch@1.1.1", - "zlib": "npm:jspm-nodelibs-zlib@0.2.0" - }, - packages: { - "npm:bn.js@4.11.6": { - "map": {} - }, - "npm:browserify-aes@1.0.6": { - "map": { - "buffer-xor": "npm:buffer-xor@1.0.3", - "cipher-base": "npm:cipher-base@1.0.3", - "create-hash": "npm:create-hash@1.1.2", - "evp_bytestokey": "npm:evp_bytestokey@1.0.0", - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:browserify-cipher@1.0.0": { - "map": { - "browserify-aes": "npm:browserify-aes@1.0.6", - "browserify-des": "npm:browserify-des@1.0.0", - "evp_bytestokey": "npm:evp_bytestokey@1.0.0" - } - }, - "npm:browserify-des@1.0.0": { - "map": { - "cipher-base": "npm:cipher-base@1.0.3", - "des.js": "npm:des.js@1.0.0", - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:browserify-rsa@4.0.1": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:browserify-sign@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "browserify-rsa": "npm:browserify-rsa@4.0.1", - "create-hash": "npm:create-hash@1.1.2", - "create-hmac": "npm:create-hmac@1.1.4", - "elliptic": "npm:elliptic@6.3.2", - "inherits": "npm:inherits@2.0.3", - "parse-asn1": "npm:parse-asn1@5.0.0" - } - }, - "npm:browserify-zlib@0.1.4": { - "map": { - "pako": "npm:pako@0.2.9", - "readable-stream": "npm:readable-stream@2.2.2" - } - }, - "npm:buffer-xor@1.0.3": { - "map": {} - }, - "npm:core-util-is@1.0.2": { - "map": {} - }, - "npm:create-ecdh@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "elliptic": "npm:elliptic@6.3.2" - } - }, - "npm:create-hash@1.1.2": { - "map": { - "cipher-base": "npm:cipher-base@1.0.3", - "inherits": "npm:inherits@2.0.3", - "ripemd160": "npm:ripemd160@1.0.1", - "sha.js": "npm:sha.js@2.4.8" - } - }, - "npm:create-hmac@1.1.4": { - "map": { - "create-hash": "npm:create-hash@1.1.2", - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:crypto-browserify@3.11.0": { - "map": { - "browserify-cipher": "npm:browserify-cipher@1.0.0", - "browserify-sign": "npm:browserify-sign@4.0.0", - "create-ecdh": "npm:create-ecdh@4.0.0", - "create-hash": "npm:create-hash@1.1.2", - "create-hmac": "npm:create-hmac@1.1.4", - "diffie-hellman": "npm:diffie-hellman@5.0.2", - "inherits": "npm:inherits@2.0.3", - "pbkdf2": "npm:pbkdf2@3.0.9", - "public-encrypt": "npm:public-encrypt@4.0.0", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:des.js@1.0.0": { - "map": { - "inherits": "npm:inherits@2.0.3", - "minimalistic-assert": "npm:minimalistic-assert@1.0.0" - } - }, - "npm:diffie-hellman@5.0.2": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "miller-rabin": "npm:miller-rabin@4.0.0", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:domain-browser@1.1.7": { - "map": {} - }, - "npm:evp_bytestokey@1.0.0": { - "map": { - "create-hash": "npm:create-hash@1.1.2" - } - }, - "npm:has-flag@1.0.0": { - "map": {} - }, - "npm:hash.js@1.0.3": { - "map": { - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:iconv-lite@0.4.13": { - "map": {} - }, - "npm:invariant@2.2.1": { - "map": { - "loose-envify": "npm:loose-envify@1.2.0" - } - }, - "npm:loose-envify@1.2.0": { - "map": { - "js-tokens": "npm:js-tokens@1.0.3" - } - }, - "npm:miller-rabin@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "brorand": "npm:brorand@1.0.6" - } - }, - "npm:normalizr@2.2.1": { - "map": { - "lodash": "npm:lodash@4.16.4" - } - }, - "npm:pako@0.2.9": { - "map": {} - }, - "npm:parse-asn1@5.0.0": { - "map": { - "asn1.js": "npm:asn1.js@4.9.0", - "browserify-aes": "npm:browserify-aes@1.0.6", - "create-hash": "npm:create-hash@1.1.2", - "evp_bytestokey": "npm:evp_bytestokey@1.0.0", - "pbkdf2": "npm:pbkdf2@3.0.9" - } - }, - "npm:process-nextick-args@1.0.7": { - "map": {} - }, - "npm:public-encrypt@4.0.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "browserify-rsa": "npm:browserify-rsa@4.0.1", - "create-hash": "npm:create-hash@1.1.2", - "parse-asn1": "npm:parse-asn1@5.0.0", - "randombytes": "npm:randombytes@2.0.3" - } - }, - "npm:punycode@1.3.2": { - "map": {} - }, - "npm:randombytes@2.0.3": { - "map": {} - }, - "npm:react-redux@4.4.5": { - "map": { - "hoist-non-react-statics": "npm:hoist-non-react-statics@1.2.0", - "invariant": "npm:invariant@2.2.1", - "lodash": "npm:lodash@4.16.4", - "loose-envify": "npm:loose-envify@1.2.0" - } - }, - "npm:ripemd160@1.0.1": { - "map": {} - }, - "npm:string_decoder@0.10.31": { - "map": {} - }, - "npm:supports-color@3.1.2": { - "map": { - "has-flag": "npm:has-flag@1.0.0" - } - }, - "npm:util-deprecate@1.0.2": { - "map": {} - }, - "npm:url@0.11.0": { - "map": { - "punycode": "npm:punycode@1.3.2", - "querystring": "npm:querystring@0.2.0" - } - }, - "npm:stream-browserify@2.0.1": { - "map": { - "inherits": "npm:inherits@2.0.3", - "readable-stream": "npm:readable-stream@2.2.2" - } - }, - "npm:gettemporaryfilepath@0.0.1": { - "map": {} - }, - "npm:iconv-lite@0.4.5": { - "map": {} - }, - "npm:lodash@3.10.0": { - "map": {} - }, - "npm:magicpen-media@1.5.1": { - "map": { - "gettemporaryfilepath": "npm:gettemporaryfilepath@0.0.1", - "lodash": "npm:lodash@3.10.0", - "mime": "npm:mime@1.3.4" - } - }, - "npm:mime@1.3.4": { - "map": {} - }, - "npm:quoted-printable@1.0.0": { - "map": { - "utf8": "npm:utf8@2.1.2" - } - }, - "npm:rfc2047@2.0.0": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.5" - } - }, - "npm:rfc2231@1.3.0": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.5" - } - }, - "npm:buffer@4.9.1": { - "map": { - "base64-js": "npm:base64-js@1.2.0", - "ieee754": "npm:ieee754@1.1.8", - "isarray": "npm:isarray@1.0.0" - } - }, - "npm:elliptic@6.3.2": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "inherits": "npm:inherits@2.0.3", - "brorand": "npm:brorand@1.0.6", - "hash.js": "npm:hash.js@1.0.3" - } - }, - "npm:cipher-base@1.0.3": { - "map": { - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:pbkdf2@3.0.9": { - "map": { - "create-hmac": "npm:create-hmac@1.1.4" - } - }, - "npm:rc-table@5.0.3": { - "map": { - "shallowequal": "npm:shallowequal@0.2.2", - "object-path": "npm:object-path@0.11.2", - "rc-util": "npm:rc-util@3.4.1" - } - }, - "npm:rc-util@3.4.1": { - "map": { - "shallowequal": "npm:shallowequal@0.2.2", - "add-dom-event-listener": "npm:add-dom-event-listener@1.0.1", - "classnames": "npm:classnames@2.2.5" - } - }, - "npm:shallowequal@0.2.2": { - "map": { - "lodash.keys": "npm:lodash.keys@3.1.2" - } - }, - "npm:add-dom-event-listener@1.0.1": { - "map": { - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:lodash.keys@3.1.2": { - "map": { - "lodash._getnative": "npm:lodash._getnative@3.9.1", - "lodash.isarray": "npm:lodash.isarray@3.0.4", - "lodash.isarguments": "npm:lodash.isarguments@3.1.0" - } - }, - "npm:react-dimensions@1.3.0": { - "map": { - "element-resize-event": "npm:element-resize-event@2.0.7" - } - }, - "npm:messy@6.12.2": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.13", - "underscore": "npm:underscore@1.8.3", - "rfc2231": "npm:rfc2231@1.3.0", - "quoted-printable": "npm:quoted-printable@1.0.0", - "rfc2047": "npm:rfc2047@2.0.0" - } - }, - "npm:unexpected-messy@6.2.0": { - "map": { - "underscore": "npm:underscore@1.7.0", - "minimist": "npm:minimist@1.1.1" - } - }, - "npm:redux@3.6.0": { - "map": { - "symbol-observable": "npm:symbol-observable@1.0.4", - "loose-envify": "npm:loose-envify@1.2.0", - "lodash-es": "npm:lodash-es@4.16.4", - "lodash": "npm:lodash@4.16.4" - } - }, - "npm:react-select@1.0.0-rc.2": { - "map": { - "react-input-autosize": "npm:react-input-autosize@1.1.0", - "classnames": "npm:classnames@2.2.5" - } - }, - "npm:core-js@1.2.7": { - "map": {} - }, - "npm:react@15.3.2": { - "map": { - "fbjs": "npm:fbjs@0.8.6", - "loose-envify": "npm:loose-envify@1.3.0", - "object-assign": "npm:object-assign@4.1.0" - } - }, - "npm:isomorphic-fetch@2.2.1": { - "map": { - "node-fetch": "npm:node-fetch@1.6.3", - "whatwg-fetch": "npm:whatwg-fetch@1.1.1" - } - }, - "npm:promise@7.1.1": { - "map": { - "asap": "npm:asap@2.0.5" - } - }, - "npm:node-fetch@1.6.3": { - "map": { - "is-stream": "npm:is-stream@1.1.0", - "encoding": "npm:encoding@0.1.12" - } - }, - "npm:encoding@0.1.12": { - "map": { - "iconv-lite": "npm:iconv-lite@0.4.15" - } - }, - "npm:readable-stream@2.2.2": { - "map": { - "core-util-is": "npm:core-util-is@1.0.2", - "isarray": "npm:isarray@1.0.0", - "inherits": "npm:inherits@2.0.3", - "string_decoder": "npm:string_decoder@0.10.31", - "process-nextick-args": "npm:process-nextick-args@1.0.7", - "util-deprecate": "npm:util-deprecate@1.0.2", - "buffer-shims": "npm:buffer-shims@1.0.0" - } - }, - "npm:stream-http@2.5.0": { - "map": { - "inherits": "npm:inherits@2.0.3", - "readable-stream": "npm:readable-stream@2.2.2", - "builtin-status-codes": "npm:builtin-status-codes@2.0.0", - "to-arraybuffer": "npm:to-arraybuffer@1.0.1", - "xtend": "npm:xtend@4.0.1" - } - }, - "npm:sha.js@2.4.8": { - "map": { - "inherits": "npm:inherits@2.0.3" - } - }, - "npm:asn1.js@4.9.0": { - "map": { - "bn.js": "npm:bn.js@4.11.6", - "inherits": "npm:inherits@2.0.3", - "minimalistic-assert": "npm:minimalistic-assert@1.0.0" - } - }, - "npm:wampy@4.0.0": { - "main": "build/wampy.js", - "map": { - "websocket": "npm:websocket@1.0.23", - "msgpack5": "npm:msgpack5@3.4.1" - } - }, - "npm:websocket@1.0.23": { - "map": { - "yaeti": "npm:yaeti@0.0.4", - "debug": "npm:debug@2.3.2", - "typedarray-to-buffer": "npm:typedarray-to-buffer@3.1.2", - "nan": "npm:nan@2.4.0" - } - }, - "npm:msgpack5@3.4.1": { - "map": { - "inherits": "npm:inherits@2.0.3", - "readable-stream": "npm:readable-stream@2.2.2", - "bl": "npm:bl@1.1.2" - } - }, - "npm:debug@2.3.2": { - "map": { - "ms": "npm:ms@0.7.2" - } - }, - "npm:bl@1.1.2": { - "map": { - "readable-stream": "npm:readable-stream@2.0.6" - } - }, - "npm:typedarray-to-buffer@3.1.2": { - "map": { - "is-typedarray": "npm:is-typedarray@1.0.0" - } - }, - "npm:readable-stream@2.0.6": { - "map": { - "core-util-is": "npm:core-util-is@1.0.2", - "inherits": "npm:inherits@2.0.3", - "isarray": "npm:isarray@1.0.0", - "process-nextick-args": "npm:process-nextick-args@1.0.7", - "string_decoder": "npm:string_decoder@0.10.31", - "util-deprecate": "npm:util-deprecate@1.0.2" - } - }, - "npm:fbjs@0.8.6": { - "map": { - "loose-envify": "npm:loose-envify@1.3.0", - "object-assign": "npm:object-assign@4.1.0", - "core-js": "npm:core-js@1.2.7", - "isomorphic-fetch": "npm:isomorphic-fetch@2.2.1", - "promise": "npm:promise@7.1.1", - "ua-parser-js": "npm:ua-parser-js@0.7.12" - } - }, - "npm:loose-envify@1.3.0": { - "map": { - "js-tokens": "npm:js-tokens@2.0.0" - } - }, - "npm:styled-components@1.1.1": { - "map": { - "buffer": "npm:buffer@5.0.1", - "fbjs": "npm:fbjs@0.8.6", - "supports-color": "npm:supports-color@3.1.2", - "glamor": "npm:glamor@2.19.0", - "lodash": "npm:lodash@4.17.2", - "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" - } - }, - "npm:glamor@2.19.0": { - "map": { - "fbjs": "npm:fbjs@0.8.6", - "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" - } - }, - "npm:buffer@5.0.1": { - "map": { - "ieee754": "npm:ieee754@1.1.8", - "base64-js": "npm:base64-js@1.2.0" - } - }, - "npm:inline-style-prefixer@2.0.4": { - "map": { - "bowser": "npm:bowser@1.5.0", - "hyphenate-style-name": "npm:hyphenate-style-name@1.0.2" - } - }, - "npm:jspm-nodelibs-punycode@0.2.0": { - "map": { - "punycode-browserify": "npm:punycode@1.4.1" - } - }, - "npm:jspm-nodelibs-domain@0.2.0": { - "map": { - "domain-browserify": "npm:domain-browser@1.1.7" - } - }, - "npm:jspm-nodelibs-crypto@0.2.0": { - "map": { - "crypto-browserify": "npm:crypto-browserify@3.11.0" - } - }, - "npm:jspm-nodelibs-zlib@0.2.0": { - "map": { - "zlib-browserify": "npm:browserify-zlib@0.1.4" - } - }, - "npm:jspm-nodelibs-string_decoder@0.2.0": { - "map": { - "string_decoder-browserify": "npm:string_decoder@0.10.31" - } - }, - "npm:jspm-nodelibs-os@0.2.0": { - "map": { - "os-browserify": "npm:os-browserify@0.2.1" - } - }, - "github:jspm/nodelibs-http@0.2.0-alpha": { - "map": { - "http-browserify": "npm:stream-http@2.5.0" - } - }, - "github:jspm/nodelibs-buffer@0.2.0-alpha": { - "map": { - "buffer-browserify": "npm:buffer@4.9.1" - } - }, - "github:jspm/nodelibs-stream@0.2.0-alpha": { - "map": { - "stream-browserify": "npm:stream-browserify@2.0.1" - } - }, - "github:jspm/nodelibs-url@0.2.0-alpha": { - "map": { - "url-browserify": "npm:url@0.11.0" - } - } + packageConfigPaths: [ + "npm:@*/*.json", + "npm:*.json", + "github:*/*.json", + "local:*.json" + ], + map: { + "fixed-data-table-2": "npm:fixed-data-table-2@0.7.6", + "immutable": "npm:immutable@3.8.1", + "github/url-polyfill": "github:github/url-polyfill@0.5.6", + "bluebird": "npm:bluebird@3.4.6", + "module": "npm:jspm-nodelibs-module@0.2.0", + "plugin-babel": "npm:systemjs-plugin-babel@0.0.13", + "magicpen-media": "npm:magicpen-media@1.5.1", + "messy": "npm:messy@6.12.2", + "net": "npm:jspm-nodelibs-net@0.2.0", + "os": "npm:jspm-nodelibs-os@0.2.0", + "punycode": "npm:jspm-nodelibs-punycode@0.2.0", + "querystring": "npm:jspm-nodelibs-querystring@0.2.0", + "rc-table": "npm:rc-table@5.0.3", + "react": "npm:react@15.3.2", + "react-dimensions": "npm:react-dimensions@1.3.0", + "react-dom": "npm:react-dom@15.3.2", + "react-select": "npm:react-select@1.0.0-rc.2", + "redux-immutablejs": "npm:redux-immutablejs@0.0.8", + "redux-observer": "npm:redux-observer@1.0.0", + "repl": "npm:jspm-nodelibs-repl@0.2.0", + "reselect": "npm:reselect@2.5.4", + "styled-components": "npm:styled-components@1.1.1", + "text": "github:systemjs/plugin-text@0.0.9", + "tls": "npm:jspm-nodelibs-tls@0.2.0", + "tty": "npm:jspm-nodelibs-tty@0.2.0", + "unexpected": "npm:unexpected@10.18.1", + "unexpected-messy": "npm:unexpected-messy@6.2.0", + "constants": "npm:jspm-nodelibs-constants@0.2.0", + "assert": "npm:jspm-nodelibs-assert@0.2.0", + "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha", + "child_process": "npm:jspm-nodelibs-child_process@0.2.0", + "crypto": "npm:jspm-nodelibs-crypto@0.2.0", + "domain": "npm:jspm-nodelibs-domain@0.2.0", + "events": "github:jspm/nodelibs-events@0.2.0-alpha", + "fs": "github:jspm/nodelibs-fs@0.2.0-alpha", + "http": "github:jspm/nodelibs-http@0.2.0-alpha", + "https": "npm:jspm-nodelibs-https@0.2.0", + "path": "github:jspm/nodelibs-path@0.2.0-alpha", + "process": "github:jspm/nodelibs-process@0.2.0-alpha", + "stream": "github:jspm/nodelibs-stream@0.2.0-alpha", + "string_decoder": "npm:jspm-nodelibs-string_decoder@0.2.0", + "normalizr": "npm:normalizr@2.2.1", + "react-redux": "npm:react-redux@4.4.5", + "redux": "npm:redux@3.6.0", + "redux-thunk": "npm:redux-thunk@2.1.0", + "svg": "github:npbenjohnson/plugin-svg@0.1.0", + "url": "github:jspm/nodelibs-url@0.2.0-alpha", + "url-polyfill": "github:github/url-polyfill@0.5.6", + "util": "github:jspm/nodelibs-util@0.2.0-alpha", + "vm": "npm:jspm-nodelibs-vm@0.2.0", + "wampy": "npm:wampy@4.0.0", + "whatwg-fetch": "npm:whatwg-fetch@1.1.1", + "zlib": "npm:jspm-nodelibs-zlib@0.2.0" + }, + packages: { + "npm:bn.js@4.11.6": { + "map": {} + }, + "npm:browserify-aes@1.0.6": { + "map": { + "buffer-xor": "npm:buffer-xor@1.0.3", + "cipher-base": "npm:cipher-base@1.0.3", + "create-hash": "npm:create-hash@1.1.2", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0", + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:browserify-cipher@1.0.0": { + "map": { + "browserify-aes": "npm:browserify-aes@1.0.6", + "browserify-des": "npm:browserify-des@1.0.0", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0" + } + }, + "npm:browserify-des@1.0.0": { + "map": { + "cipher-base": "npm:cipher-base@1.0.3", + "des.js": "npm:des.js@1.0.0", + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:browserify-rsa@4.0.1": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:browserify-sign@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "browserify-rsa": "npm:browserify-rsa@4.0.1", + "create-hash": "npm:create-hash@1.1.2", + "create-hmac": "npm:create-hmac@1.1.4", + "elliptic": "npm:elliptic@6.3.2", + "inherits": "npm:inherits@2.0.3", + "parse-asn1": "npm:parse-asn1@5.0.0" + } + }, + "npm:browserify-zlib@0.1.4": { + "map": { + "pako": "npm:pako@0.2.9", + "readable-stream": "npm:readable-stream@2.2.2" + } + }, + "npm:buffer-xor@1.0.3": { + "map": {} + }, + "npm:core-util-is@1.0.2": { + "map": {} + }, + "npm:create-ecdh@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "elliptic": "npm:elliptic@6.3.2" + } + }, + "npm:create-hash@1.1.2": { + "map": { + "cipher-base": "npm:cipher-base@1.0.3", + "inherits": "npm:inherits@2.0.3", + "ripemd160": "npm:ripemd160@1.0.1", + "sha.js": "npm:sha.js@2.4.8" + } + }, + "npm:create-hmac@1.1.4": { + "map": { + "create-hash": "npm:create-hash@1.1.2", + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:crypto-browserify@3.11.0": { + "map": { + "browserify-cipher": "npm:browserify-cipher@1.0.0", + "browserify-sign": "npm:browserify-sign@4.0.0", + "create-ecdh": "npm:create-ecdh@4.0.0", + "create-hash": "npm:create-hash@1.1.2", + "create-hmac": "npm:create-hmac@1.1.4", + "diffie-hellman": "npm:diffie-hellman@5.0.2", + "inherits": "npm:inherits@2.0.3", + "pbkdf2": "npm:pbkdf2@3.0.9", + "public-encrypt": "npm:public-encrypt@4.0.0", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:des.js@1.0.0": { + "map": { + "inherits": "npm:inherits@2.0.3", + "minimalistic-assert": "npm:minimalistic-assert@1.0.0" + } + }, + "npm:diffie-hellman@5.0.2": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "miller-rabin": "npm:miller-rabin@4.0.0", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:domain-browser@1.1.7": { + "map": {} + }, + "npm:evp_bytestokey@1.0.0": { + "map": { + "create-hash": "npm:create-hash@1.1.2" + } + }, + "npm:has-flag@1.0.0": { + "map": {} + }, + "npm:hash.js@1.0.3": { + "map": { + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:iconv-lite@0.4.13": { + "map": {} + }, + "npm:invariant@2.2.1": { + "map": { + "loose-envify": "npm:loose-envify@1.2.0" + } + }, + "npm:loose-envify@1.2.0": { + "map": { + "js-tokens": "npm:js-tokens@1.0.3" + } + }, + "npm:miller-rabin@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "brorand": "npm:brorand@1.0.6" + } + }, + "npm:normalizr@2.2.1": { + "map": { + "lodash": "npm:lodash@4.16.4" + } + }, + "npm:pako@0.2.9": { + "map": {} + }, + "npm:parse-asn1@5.0.0": { + "map": { + "asn1.js": "npm:asn1.js@4.9.0", + "browserify-aes": "npm:browserify-aes@1.0.6", + "create-hash": "npm:create-hash@1.1.2", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0", + "pbkdf2": "npm:pbkdf2@3.0.9" + } + }, + "npm:process-nextick-args@1.0.7": { + "map": {} + }, + "npm:public-encrypt@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "browserify-rsa": "npm:browserify-rsa@4.0.1", + "create-hash": "npm:create-hash@1.1.2", + "parse-asn1": "npm:parse-asn1@5.0.0", + "randombytes": "npm:randombytes@2.0.3" + } + }, + "npm:punycode@1.3.2": { + "map": {} + }, + "npm:randombytes@2.0.3": { + "map": {} + }, + "npm:react-redux@4.4.5": { + "map": { + "hoist-non-react-statics": "npm:hoist-non-react-statics@1.2.0", + "invariant": "npm:invariant@2.2.1", + "lodash": "npm:lodash@4.16.4", + "loose-envify": "npm:loose-envify@1.2.0" + } + }, + "npm:ripemd160@1.0.1": { + "map": {} + }, + "npm:string_decoder@0.10.31": { + "map": {} + }, + "npm:supports-color@3.1.2": { + "map": { + "has-flag": "npm:has-flag@1.0.0" + } + }, + "npm:util-deprecate@1.0.2": { + "map": {} + }, + "npm:url@0.11.0": { + "map": { + "punycode": "npm:punycode@1.3.2", + "querystring": "npm:querystring@0.2.0" + } + }, + "npm:stream-browserify@2.0.1": { + "map": { + "inherits": "npm:inherits@2.0.3", + "readable-stream": "npm:readable-stream@2.2.2" + } + }, + "npm:gettemporaryfilepath@0.0.1": { + "map": {} + }, + "npm:iconv-lite@0.4.5": { + "map": {} + }, + "npm:lodash@3.10.0": { + "map": {} + }, + "npm:magicpen-media@1.5.1": { + "map": { + "gettemporaryfilepath": "npm:gettemporaryfilepath@0.0.1", + "lodash": "npm:lodash@3.10.0", + "mime": "npm:mime@1.3.4" + } + }, + "npm:mime@1.3.4": { + "map": {} + }, + "npm:quoted-printable@1.0.0": { + "map": { + "utf8": "npm:utf8@2.1.2" + } + }, + "npm:rfc2047@2.0.0": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.5" + } + }, + "npm:rfc2231@1.3.0": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.5" + } + }, + "npm:buffer@4.9.1": { + "map": { + "base64-js": "npm:base64-js@1.2.0", + "ieee754": "npm:ieee754@1.1.8", + "isarray": "npm:isarray@1.0.0" + } + }, + "npm:elliptic@6.3.2": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "inherits": "npm:inherits@2.0.3", + "brorand": "npm:brorand@1.0.6", + "hash.js": "npm:hash.js@1.0.3" + } + }, + "npm:cipher-base@1.0.3": { + "map": { + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:pbkdf2@3.0.9": { + "map": { + "create-hmac": "npm:create-hmac@1.1.4" + } + }, + "npm:rc-table@5.0.3": { + "map": { + "shallowequal": "npm:shallowequal@0.2.2", + "object-path": "npm:object-path@0.11.2", + "rc-util": "npm:rc-util@3.4.1" + } + }, + "npm:rc-util@3.4.1": { + "map": { + "shallowequal": "npm:shallowequal@0.2.2", + "add-dom-event-listener": "npm:add-dom-event-listener@1.0.1", + "classnames": "npm:classnames@2.2.5" + } + }, + "npm:shallowequal@0.2.2": { + "map": { + "lodash.keys": "npm:lodash.keys@3.1.2" + } + }, + "npm:add-dom-event-listener@1.0.1": { + "map": { + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:lodash.keys@3.1.2": { + "map": { + "lodash._getnative": "npm:lodash._getnative@3.9.1", + "lodash.isarray": "npm:lodash.isarray@3.0.4", + "lodash.isarguments": "npm:lodash.isarguments@3.1.0" + } + }, + "npm:react-dimensions@1.3.0": { + "map": { + "element-resize-event": "npm:element-resize-event@2.0.7" + } + }, + "npm:messy@6.12.2": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.13", + "underscore": "npm:underscore@1.8.3", + "rfc2231": "npm:rfc2231@1.3.0", + "quoted-printable": "npm:quoted-printable@1.0.0", + "rfc2047": "npm:rfc2047@2.0.0" + } + }, + "npm:unexpected-messy@6.2.0": { + "map": { + "underscore": "npm:underscore@1.7.0", + "minimist": "npm:minimist@1.1.1" + } + }, + "npm:redux@3.6.0": { + "map": { + "symbol-observable": "npm:symbol-observable@1.0.4", + "loose-envify": "npm:loose-envify@1.2.0", + "lodash-es": "npm:lodash-es@4.16.4", + "lodash": "npm:lodash@4.16.4" + } + }, + "npm:react-select@1.0.0-rc.2": { + "map": { + "react-input-autosize": "npm:react-input-autosize@1.1.0", + "classnames": "npm:classnames@2.2.5" + } + }, + "npm:core-js@1.2.7": { + "map": {} + }, + "npm:react@15.3.2": { + "map": { + "fbjs": "npm:fbjs@0.8.6", + "loose-envify": "npm:loose-envify@1.3.0", + "object-assign": "npm:object-assign@4.1.0" + } + }, + "npm:isomorphic-fetch@2.2.1": { + "map": { + "node-fetch": "npm:node-fetch@1.6.3", + "whatwg-fetch": "npm:whatwg-fetch@1.1.1" + } + }, + "npm:promise@7.1.1": { + "map": { + "asap": "npm:asap@2.0.5" + } + }, + "npm:node-fetch@1.6.3": { + "map": { + "is-stream": "npm:is-stream@1.1.0", + "encoding": "npm:encoding@0.1.12" + } + }, + "npm:encoding@0.1.12": { + "map": { + "iconv-lite": "npm:iconv-lite@0.4.15" + } + }, + "npm:readable-stream@2.2.2": { + "map": { + "core-util-is": "npm:core-util-is@1.0.2", + "isarray": "npm:isarray@1.0.0", + "inherits": "npm:inherits@2.0.3", + "string_decoder": "npm:string_decoder@0.10.31", + "process-nextick-args": "npm:process-nextick-args@1.0.7", + "util-deprecate": "npm:util-deprecate@1.0.2", + "buffer-shims": "npm:buffer-shims@1.0.0" + } + }, + "npm:stream-http@2.5.0": { + "map": { + "inherits": "npm:inherits@2.0.3", + "readable-stream": "npm:readable-stream@2.2.2", + "builtin-status-codes": "npm:builtin-status-codes@2.0.0", + "to-arraybuffer": "npm:to-arraybuffer@1.0.1", + "xtend": "npm:xtend@4.0.1" + } + }, + "npm:sha.js@2.4.8": { + "map": { + "inherits": "npm:inherits@2.0.3" + } + }, + "npm:asn1.js@4.9.0": { + "map": { + "bn.js": "npm:bn.js@4.11.6", + "inherits": "npm:inherits@2.0.3", + "minimalistic-assert": "npm:minimalistic-assert@1.0.0" + } + }, + "npm:wampy@4.0.0": { + "main": "build/wampy.js", + "map": { + "websocket": "npm:websocket@1.0.23", + "msgpack5": "npm:msgpack5@3.4.1" + } + }, + "npm:websocket@1.0.23": { + "map": { + "yaeti": "npm:yaeti@0.0.4", + "debug": "npm:debug@2.3.2", + "typedarray-to-buffer": "npm:typedarray-to-buffer@3.1.2", + "nan": "npm:nan@2.4.0" + } + }, + "npm:msgpack5@3.4.1": { + "map": { + "inherits": "npm:inherits@2.0.3", + "readable-stream": "npm:readable-stream@2.2.2", + "bl": "npm:bl@1.1.2" + } + }, + "npm:debug@2.3.2": { + "map": { + "ms": "npm:ms@0.7.2" + } + }, + "npm:bl@1.1.2": { + "map": { + "readable-stream": "npm:readable-stream@2.0.6" + } + }, + "npm:typedarray-to-buffer@3.1.2": { + "map": { + "is-typedarray": "npm:is-typedarray@1.0.0" + } + }, + "npm:readable-stream@2.0.6": { + "map": { + "core-util-is": "npm:core-util-is@1.0.2", + "inherits": "npm:inherits@2.0.3", + "isarray": "npm:isarray@1.0.0", + "process-nextick-args": "npm:process-nextick-args@1.0.7", + "string_decoder": "npm:string_decoder@0.10.31", + "util-deprecate": "npm:util-deprecate@1.0.2" + } + }, + "npm:fbjs@0.8.6": { + "map": { + "loose-envify": "npm:loose-envify@1.3.0", + "object-assign": "npm:object-assign@4.1.0", + "core-js": "npm:core-js@1.2.7", + "isomorphic-fetch": "npm:isomorphic-fetch@2.2.1", + "promise": "npm:promise@7.1.1", + "ua-parser-js": "npm:ua-parser-js@0.7.12" + } + }, + "npm:loose-envify@1.3.0": { + "map": { + "js-tokens": "npm:js-tokens@2.0.0" + } + }, + "npm:styled-components@1.1.1": { + "map": { + "buffer": "npm:buffer@5.0.1", + "fbjs": "npm:fbjs@0.8.6", + "supports-color": "npm:supports-color@3.1.2", + "glamor": "npm:glamor@2.19.0", + "lodash": "npm:lodash@4.17.2", + "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" + } + }, + "npm:glamor@2.19.0": { + "map": { + "fbjs": "npm:fbjs@0.8.6", + "inline-style-prefixer": "npm:inline-style-prefixer@2.0.4" + } + }, + "npm:buffer@5.0.1": { + "map": { + "ieee754": "npm:ieee754@1.1.8", + "base64-js": "npm:base64-js@1.2.0" + } + }, + "npm:inline-style-prefixer@2.0.4": { + "map": { + "bowser": "npm:bowser@1.5.0", + "hyphenate-style-name": "npm:hyphenate-style-name@1.0.2" + } + }, + "npm:jspm-nodelibs-punycode@0.2.0": { + "map": { + "punycode-browserify": "npm:punycode@1.4.1" + } + }, + "npm:jspm-nodelibs-domain@0.2.0": { + "map": { + "domain-browserify": "npm:domain-browser@1.1.7" + } + }, + "npm:jspm-nodelibs-crypto@0.2.0": { + "map": { + "crypto-browserify": "npm:crypto-browserify@3.11.0" + } + }, + "npm:jspm-nodelibs-zlib@0.2.0": { + "map": { + "zlib-browserify": "npm:browserify-zlib@0.1.4" + } + }, + "npm:jspm-nodelibs-string_decoder@0.2.0": { + "map": { + "string_decoder-browserify": "npm:string_decoder@0.10.31" + } + }, + "npm:jspm-nodelibs-os@0.2.0": { + "map": { + "os-browserify": "npm:os-browserify@0.2.1" + } + }, + "github:jspm/nodelibs-http@0.2.0-alpha": { + "map": { + "http-browserify": "npm:stream-http@2.5.0" + } + }, + "github:jspm/nodelibs-buffer@0.2.0-alpha": { + "map": { + "buffer-browserify": "npm:buffer@4.9.1" + } + }, + "github:jspm/nodelibs-stream@0.2.0-alpha": { + "map": { + "stream-browserify": "npm:stream-browserify@2.0.1" + } + }, + "github:jspm/nodelibs-url@0.2.0-alpha": { + "map": { + "url-browserify": "npm:url@0.11.0" + } } + } }); From 30eb939ae6605c549a8272d637951cbcc545e874 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Thu, 2 Mar 2017 12:47:57 +0100 Subject: [PATCH 043/135] log if wamprouter could not be initialized --- .../WebClient/Services/WampRouter/WampRouter.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs b/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs index da422ed36e..81bc636205 100644 --- a/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs +++ b/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs @@ -19,8 +19,17 @@ internal class WampRouter public WampRouter() { LogProvider.SetCurrentLogProvider(new WampLogger()); - - StartWampRouter(); + try + { + StartWampRouter(); + Log.LogInformation(nameof(WampRouter),"Wamp router initiated successfully"); + } + catch (Exception e) + { + Log.LogCritical(nameof(WampRouter), "Wamp router could not be instantiated"); + Log.LogCritical(nameof(WampRouter), e); + } + } public void RegisterCallee(IRpcService instance) From 3a72b32fdbadafa63ce8c7097abe72a707f73163 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Thu, 2 Mar 2017 13:04:08 +0100 Subject: [PATCH 044/135] fix nonascii character --- Website/test/e2e/suite/content/multiEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/test/e2e/suite/content/multiEditor.js b/Website/test/e2e/suite/content/multiEditor.js index 715dd8ddeb..fa6d82ce35 100644 --- a/Website/test/e2e/suite/content/multiEditor.js +++ b/Website/test/e2e/suite/content/multiEditor.js @@ -12,7 +12,7 @@ module.exports = { .selectTreeNodeAction("Venus Starter Site", "Edit Page") .page.editor() .selectEditOnContent(1) - .clickDataBySibilings("ĐĄontent") + .clickDataBySibilings("Content") .changeElementContent('h1 > em', 'Jupiter') .acceptChanges() .clickDataBySibilings("Background Image") From a0fbebadbf3f9ebdc55a6f9c5abc08edf6a26f5e Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Thu, 2 Mar 2017 14:04:07 +0100 Subject: [PATCH 045/135] nightwatch fix --- Website/test/e2e/suite/content/multiEditor.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Website/test/e2e/suite/content/multiEditor.js b/Website/test/e2e/suite/content/multiEditor.js index fa6d82ce35..384692bf5f 100644 --- a/Website/test/e2e/suite/content/multiEditor.js +++ b/Website/test/e2e/suite/content/multiEditor.js @@ -13,9 +13,11 @@ module.exports = { .page.editor() .selectEditOnContent(1) .clickDataBySibilings("Content") + .pause(browser.globals.timeouts.basic) .changeElementContent('h1 > em', 'Jupiter') .acceptChanges() .clickDataBySibilings("Background Image") + .pause(browser.globals.timeouts.basic) .clickLabel("Select
") .clickLabel("Copenhagen","Media Archive") .clickLabel("Botanical_Garden__Photographer_Ty_Stange.jpg") From 137af2db51edcf152106d9d2daa0240147d3aabc Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 2 Mar 2017 14:08:47 +0100 Subject: [PATCH 046/135] Introducing a delay for the control pre-loading --- Composite/Core/WebClient/BrowserRender.cs | 25 ++++++++++--------- .../Core/WebClient/BuildManagerHelper.cs | 23 +++++++++++------ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Composite/Core/WebClient/BrowserRender.cs b/Composite/Core/WebClient/BrowserRender.cs index fd2f63b39e..fdad01dcfd 100644 --- a/Composite/Core/WebClient/BrowserRender.cs +++ b/Composite/Core/WebClient/BrowserRender.cs @@ -34,7 +34,7 @@ static BrowserRender() private static DateTime _lastUsageDate = DateTime.MinValue; private static readonly TimeSpan RecycleOnIdleInterval = TimeSpan.FromSeconds(30); private const int RecycleTimerInterval_ms = 10000; - private const int EnsureReadinessDelay_ms = 3000; + private const int EnsureReadinessDelay_ms = 30000; private static volatile bool Enabled = true; private static volatile bool ServerAvailabilityChecked; @@ -55,7 +55,13 @@ public static void EnsureReadiness() HttpCookie[] cookies = GetAuthenticationCookies(context); Task.Factory.StartNew(async () => { - await Task.Delay(EnsureReadinessDelay_ms); + const int delaySlice = 500; + for (int i = 0; i < EnsureReadinessDelay_ms / delaySlice; i++) + { + if (!SystemFullyOnline) return; + await Task.Delay(delaySlice); + } + await CheckServerAvailabilityAsync(context, cookies); }); } @@ -179,16 +185,11 @@ private static HttpCookie[] GetAuthenticationCookies(HttpContext context) } - private static bool SystemFullyOnline - { - get - { - return ApplicationOnlineHandlerFacade.IsApplicationOnline - && GlobalInitializerFacade.SystemCoreInitialized - && !GlobalInitializerFacade.SystemCoreInitializing - && SystemSetupFacade.IsSystemFirstTimeInitialized; - } - } + private static bool SystemFullyOnline => + ApplicationOnlineHandlerFacade.IsApplicationOnline + && GlobalInitializerFacade.SystemCoreInitialized + && !GlobalInitializerFacade.SystemCoreInitializing + && SystemSetupFacade.IsSystemFirstTimeInitialized; private static async Task CheckServerAvailabilityAsync(HttpContext context, HttpCookie[] cookies) diff --git a/Composite/Core/WebClient/BuildManagerHelper.cs b/Composite/Core/WebClient/BuildManagerHelper.cs index a41377d8e5..80870dbe58 100644 --- a/Composite/Core/WebClient/BuildManagerHelper.cs +++ b/Composite/Core/WebClient/BuildManagerHelper.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; using System.Web.Compilation; @@ -18,7 +17,8 @@ namespace Composite.Core.WebClient internal static class BuildManagerHelper { private static DateTime? _delayPreloadTo = null; - private static TimeSpan _preloadDelay = TimeSpan.FromSeconds(2); + private static TimeSpan PreloadDelay = TimeSpan.FromSeconds(2); + private static TimeSpan InitializationDelay = TimeSpan.FromSeconds(30); private static readonly string LogTitle = typeof (BuildManagerHelper).Name; private static int _preloadingInitiated; @@ -34,10 +34,19 @@ public static void InitializeControlPreLoading() } } + private static bool IsRestarting => HostingEnvironment.ApplicationHost.ShutdownInitiated(); + private static void LoadAllControls() { try { + const int waitSlice = 500; + for (int i = 0; i < InitializationDelay.Milliseconds / waitSlice; i++) + { + if(IsRestarting) return; + Thread.Sleep(waitSlice); + } + const string configFileFilePath = "~/App_Data/Composite/Composite.config"; var config = XDocument.Load(PathUtil.Resolve(configFileFilePath)); @@ -52,7 +61,7 @@ private static void LoadAllControls() { if (!C1File.Exists(PathUtil.Resolve(controlPath))) { - Log.LogWarning(LogTitle, "Missing a control file '{0}' referenced in '{1}'", controlPath, configFileFilePath); + Log.LogWarning(LogTitle, $"Missing a control file '{controlPath}' referenced in '{configFileFilePath}'"); continue; } @@ -87,7 +96,7 @@ private static void LoadAllControls() { while (true) { - if (HostingEnvironment.ApplicationHost.ShutdownInitiated()) return; + if (IsRestarting) return; Thread.MemoryBarrier(); var waitUntil = _delayPreloadTo; @@ -139,9 +148,9 @@ private static void LoadAllControls() /// public static Type GetCompiledType(string virtualPath) { - using(BuildManagerHelper.DisableUrlMetadataCachingScope()) + using (DisableUrlMetadataCachingScope()) { - return System.Web.Compilation.BuildManager.GetCompiledType(virtualPath); + return BuildManager.GetCompiledType(virtualPath); } } @@ -169,7 +178,7 @@ public static void DisableUrlMetadataCaching(bool disableCaching) /// public static IDisposable DisableUrlMetadataCachingScope() { - _delayPreloadTo = DateTime.Now.Add(_preloadDelay); + _delayPreloadTo = DateTime.Now.Add(PreloadDelay); return new DisableUrlMedataScope(); } From 85b07648ef3c22f002d1f2da15855637e7c605e9 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 2 Mar 2017 16:01:26 +0100 Subject: [PATCH 047/135] Using the latest Roslyn compiler for dynamic Razor/WebForm files compilation --- .../AspNet/Roslyn/AssemblyMetadataCache.cs | 90 ++++ Composite/AspNet/Roslyn/CSharpCodeProvider.cs | 23 + .../Roslyn/CSharpCompilationArguments.cs | 175 +++++++ Composite/AspNet/Roslyn/CSharpCompiler.cs | 99 ++++ .../Roslyn/CommonCompilationArguments.cs | 126 +++++ Composite/AspNet/Roslyn/CommonCompiler.cs | 486 ++++++++++++++++++ Composite/AspNet/Roslyn/CompilationUtil.cs | 68 +++ Composite/AspNet/Roslyn/Res.Designer.cs | 135 +++++ Composite/AspNet/Roslyn/Res.resx | 144 ++++++ Composite/Composite.csproj | 29 ++ Composite/packages.config | 4 + Website/DebugBuild.Web.config | 11 +- Website/ReleaseBuild.Web.config | 11 +- Website/WebSite.csproj | 4 - Website/packages.config | 7 - 15 files changed, 1389 insertions(+), 23 deletions(-) create mode 100644 Composite/AspNet/Roslyn/AssemblyMetadataCache.cs create mode 100644 Composite/AspNet/Roslyn/CSharpCodeProvider.cs create mode 100644 Composite/AspNet/Roslyn/CSharpCompilationArguments.cs create mode 100644 Composite/AspNet/Roslyn/CSharpCompiler.cs create mode 100644 Composite/AspNet/Roslyn/CommonCompilationArguments.cs create mode 100644 Composite/AspNet/Roslyn/CommonCompiler.cs create mode 100644 Composite/AspNet/Roslyn/CompilationUtil.cs create mode 100644 Composite/AspNet/Roslyn/Res.Designer.cs create mode 100644 Composite/AspNet/Roslyn/Res.resx diff --git a/Composite/AspNet/Roslyn/AssemblyMetadataCache.cs b/Composite/AspNet/Roslyn/AssemblyMetadataCache.cs new file mode 100644 index 0000000000..ea53fc1d94 --- /dev/null +++ b/Composite/AspNet/Roslyn/AssemblyMetadataCache.cs @@ -0,0 +1,90 @@ +ï»żusing Microsoft.CodeAnalysis; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading; + +namespace Composite.AspNet.Roslyn +{ + internal class AssemblyMetadataCache + { + private const long MaxInactiveTicksAllowed = 1200000000L; + + private const long MillisecondsInOneMinutes = 60000L; + + private static AssemblyMetadataCache instance = new AssemblyMetadataCache(); + + private ConcurrentDictionary dictionary; + + private DateTime lastActiveTime; + + private volatile Timer timer; + + private object lockObject; + + private AssemblyMetadataCache() + { + this.dictionary = new ConcurrentDictionary(); + this.lockObject = new object(); + this.Activate(); + } + + public static AssemblyMetadataCache GetInstance() + { + return AssemblyMetadataCache.instance; + } + + public AssemblyMetadata GetOrAdd(string key, Func func) + { + this.Activate(); + this.StartTimer(); + return this.dictionary.GetOrAdd(key, func); + } + + private void Activate() + { + this.lastActiveTime = DateTime.Now; + } + + private void StartTimer() + { + if (this.timer == null) + { + lock (this.lockObject) + { + if (this.timer == null) + { + this.timer = new Timer(new TimerCallback(this.ClearIfInactive), null, MillisecondsInOneMinutes, MillisecondsInOneMinutes); + } + } + } + } + + private bool IsActive() + { + return DateTime.Now.Ticks - this.lastActiveTime.Ticks > MaxInactiveTicksAllowed; + } + + private void ClearIfInactive(object state) + { + if (!this.IsActive()) + { + Timer timer = this.timer; + if (Interlocked.CompareExchange(ref this.timer, null, timer) == timer && timer != null) + { + timer.Dispose(); + } + ICollection keys = this.dictionary.Keys; + foreach (string current in keys) + { + AssemblyMetadata assemblyMetadata; + this.dictionary.TryRemove(current, out assemblyMetadata); + if (assemblyMetadata != null) + { + assemblyMetadata.Dispose(); + } + } + } + } + } +} diff --git a/Composite/AspNet/Roslyn/CSharpCodeProvider.cs b/Composite/AspNet/Roslyn/CSharpCodeProvider.cs new file mode 100644 index 0000000000..f1b2b05790 --- /dev/null +++ b/Composite/AspNet/Roslyn/CSharpCodeProvider.cs @@ -0,0 +1,23 @@ +ï»żusing System; +using System.CodeDom.Compiler; + +namespace Composite.AspNet.Roslyn +{ + public sealed class CSharpCodeProvider : Microsoft.CSharp.CSharpCodeProvider + { + + //public CSharpCodeProvider() : this(null) + //{ + //} + + //internal CSharpCodeProvider(ICompilerSettings compilerSettings = null) + //{ + //} + + [Obsolete("Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.")] + public override ICodeCompiler CreateCompiler() + { + return new CSharpCompiler(this); + } + } +} diff --git a/Composite/AspNet/Roslyn/CSharpCompilationArguments.cs b/Composite/AspNet/Roslyn/CSharpCompilationArguments.cs new file mode 100644 index 0000000000..eb6b127c97 --- /dev/null +++ b/Composite/AspNet/Roslyn/CSharpCompilationArguments.cs @@ -0,0 +1,175 @@ +ï»żusing Microsoft.CodeAnalysis.CSharp; +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Composite.AspNet.Roslyn +{ + internal class CSharpCompilationArguments : CommonCompilationArguments + { + internal CSharpCompilationArguments(CompilerParameters parameters, TextWriter outputWriter) : this(CSharpCompilationArguments.CorrectedParamaters(parameters), true, outputWriter) + { + } + + private CSharpCompilationArguments(CompilerParameters parameters, bool corrected, TextWriter outputWriter) : base(parameters, CSharpCompilationArguments.BuildCommandLineArguments(parameters, outputWriter)) + { + } + + private static CompilerParameters CorrectedParamaters(CompilerParameters parameters) + { + if (parameters.OutputAssembly == null) + { + string fileName = Path.GetFileName(parameters.TempFiles.BasePath); + string str = parameters.GenerateExecutable ? ".exe" : ".dll"; + parameters.OutputAssembly = "OutputAssembly_" + fileName + str; + } + Type typeFromHandle = typeof(CSharpCodeProvider); + CommonCompilationArguments.FixTreatWarningsAsErrors(parameters, typeFromHandle); + return parameters; + } + + private static CSharpCommandLineArguments BuildCommandLineArguments(CompilerParameters parameters, TextWriter outputWriter) + { + IEnumerable enumerable = CSharpCompilationArguments.BuildCommandLineArgArray(parameters); + outputWriter.Write(Res.Compilation_Arguments); + foreach (string current in enumerable) + { + outputWriter.Write(current + " "); + } + outputWriter.WriteLine(); + enumerable = enumerable.Concat(new string[] + { + "SuppressNoSourceFileSpecifiedWarning" + }); + string currentDirectory = Environment.CurrentDirectory; + string environmentVariable = Environment.GetEnvironmentVariable("LIB"); + CSharpCommandLineParser @default = CSharpCommandLineParser.Default; + return @default.Parse(enumerable, currentDirectory, environmentVariable); + } + + private static IEnumerable BuildCommandLineArgArray(CompilerParameters parameters) + { + string text = CSharpCompilationArguments.BuildCommandLineArgString(parameters); + char[] array = text.ToCharArray(); + bool flag = false; + for (int i = 0; i < array.Length; i++) + { + if (array[i] == '"') + { + flag = !flag; + } + if (!flag && array[i] == ' ') + { + array[i] = '\n'; + } + } + IEnumerable lines = new string(array).Split('\n'); + return lines.Where(str => !string.IsNullOrWhiteSpace(str)); + } + + private static string BuildCommandLineArgString(CompilerParameters parameters) + { + StringBuilder stringBuilder = new StringBuilder(); + if (parameters.GenerateExecutable) + { + stringBuilder.Append("/t:exe "); + if (parameters.MainClass != null && parameters.MainClass.Length > 0) + { + stringBuilder.Append("/main:"); + stringBuilder.Append(parameters.MainClass); + stringBuilder.Append(" "); + } + } + else + { + stringBuilder.Append("/t:library "); + } + stringBuilder.Append("/utf8output "); + string location = typeof(object).Assembly.Location; + string text = parameters.CoreAssemblyFileName; + if (string.IsNullOrWhiteSpace(text)) + { + text = location; + } + if (!string.IsNullOrWhiteSpace(text)) + { + stringBuilder.Append("/nostdlib+ "); + stringBuilder.Append("/R:\"").Append(text.Trim()).Append("\" "); + } + string text2 = null; + try + { + Assembly assembly = Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); + text2 = assembly.Location; + } + catch + { + } + if (text2 != null) + { + stringBuilder.Append($"/R:\"{text2}\" "); + } + foreach (string current in parameters.ReferencedAssemblies) + { + stringBuilder.Append("/R:"); + stringBuilder.Append("\""); + stringBuilder.Append(current); + stringBuilder.Append("\""); + stringBuilder.Append(" "); + } + stringBuilder.Append("/out:"); + stringBuilder.Append("\""); + stringBuilder.Append(parameters.OutputAssembly); + stringBuilder.Append("\""); + stringBuilder.Append(" "); + if (parameters.IncludeDebugInformation) + { + stringBuilder.Append("/D:DEBUG "); + stringBuilder.Append("/debug+ "); + stringBuilder.Append("/optimize- "); + } + else + { + stringBuilder.Append("/debug- "); + stringBuilder.Append("/optimize+ "); + } + if (parameters.Win32Resource != null) + { + stringBuilder.Append("/win32res:\"" + parameters.Win32Resource + "\" "); + } + foreach (string current2 in parameters.EmbeddedResources) + { + stringBuilder.Append("/res:\""); + stringBuilder.Append(current2); + stringBuilder.Append("\" "); + } + foreach (string current3 in parameters.LinkedResources) + { + stringBuilder.Append("/linkres:\""); + stringBuilder.Append(current3); + stringBuilder.Append("\" "); + } + if (parameters.TreatWarningsAsErrors) + { + stringBuilder.Append("/warnaserror+ "); + } + else + { + stringBuilder.Append("/warnaserror- "); + } + if (parameters.WarningLevel >= 0) + { + stringBuilder.Append("/w:" + parameters.WarningLevel + " "); + } + if (parameters.CompilerOptions != null) + { + stringBuilder.Append(parameters.CompilerOptions + " "); + } + return stringBuilder.ToString(); + } + } +} diff --git a/Composite/AspNet/Roslyn/CSharpCompiler.cs b/Composite/AspNet/Roslyn/CSharpCompiler.cs new file mode 100644 index 0000000000..40d0183d65 --- /dev/null +++ b/Composite/AspNet/Roslyn/CSharpCompiler.cs @@ -0,0 +1,99 @@ +ï»żusing Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CSharp; +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; + +namespace Composite.AspNet.Roslyn +{ + internal class CSharpCompiler : CommonCompiler + { + [CompilerGenerated] + private static Func _treePredicate; + + public CSharpCompiler(CSharpCodeProvider oldProvider) : base(oldProvider) + { + } + + internal override SyntaxTree ParseText(string text) + { + return CSharpSyntaxTree.ParseText(text); + } + + internal override SyntaxTree ParseFile(string filename) + { + var text = File.ReadAllText(filename); + return ParseText(text); + } + + internal override CommonCompilationArguments ArgumentsFromParameters(CompilerParameters parameters, TextWriter outputWriter) + { + return new CSharpCompilationArguments(parameters, outputWriter); + } + + internal override Microsoft.CodeAnalysis.Compilation CreateCompilation(CommonCompilationArguments arguments, IEnumerable syntaxTrees) + { + var provider = new DesktopStrongNameProvider(arguments.CmdArguments.KeyFileSearchPaths); + var cSharpCompilationOptions = ((CSharpCommandLineArguments)arguments.CmdArguments) + .CompilationOptions + .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) + .WithStrongNameProvider(provider); + + return CSharpCompilation.Create(arguments.OutputFileName, + syntaxTrees + .Where(tree => tree != null), + arguments.MetadataReferences, cSharpCompilationOptions); + } + + internal override CompilerError CompilerErrorFromDiagnostic(Diagnostic diagnostic, TextWriter consoleOutput) + { + string value = CSharpDiagnosticFormatter.Instance.Format(diagnostic, null); + consoleOutput.WriteLine(value); + var compilerError = new CompilerError + { + IsWarning = diagnostic.Severity == DiagnosticSeverity.Warning && !diagnostic.IsWarningAsError, + ErrorNumber = diagnostic.Id, + ErrorText = this.GetErrorNumber(diagnostic) + }; + switch (diagnostic.Location.Kind) + { + case LocationKind.SourceFile: + case LocationKind.XmlFile: + { + FileLinePositionSpan lineSpan = diagnostic.Location.GetLineSpan(); + FileLinePositionSpan mappedLineSpan = diagnostic.Location.GetMappedLineSpan(); + if (lineSpan.IsValid && mappedLineSpan.IsValid) + { + if (!mappedLineSpan.HasMappedPath) + { + compilerError.FileName = lineSpan.Path; + compilerError.Line = lineSpan.Span.Start.Line + 1; + compilerError.Column = lineSpan.Span.Start.Character + 1; + } + else + { + compilerError.FileName = mappedLineSpan.Path; + compilerError.Line = mappedLineSpan.Span.Start.Line + 1; + compilerError.Column = mappedLineSpan.Span.Start.Character + 1; + } + } + break; + } + case LocationKind.MetadataFile: + compilerError.FileName = diagnostic.Location.MetadataModule.Name; + break; + } + return compilerError; + } + + internal string GetErrorNumber(Diagnostic diagnostic) + { + return $"{(diagnostic.IsWarningAsError ? "Warning as Error: " : "")}{diagnostic.GetMessage(null)}"; + } + } +} \ No newline at end of file diff --git a/Composite/AspNet/Roslyn/CommonCompilationArguments.cs b/Composite/AspNet/Roslyn/CommonCompilationArguments.cs new file mode 100644 index 0000000000..62c92a3216 --- /dev/null +++ b/Composite/AspNet/Roslyn/CommonCompilationArguments.cs @@ -0,0 +1,126 @@ +ï»żusing Microsoft.CodeAnalysis; +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IO; +using System.Runtime.CompilerServices; + +namespace Composite.AspNet.Roslyn +{ + internal abstract class CommonCompilationArguments + { + private CommandLineArguments cmdArguments; + + private string outputFileName; + + private string outputFileDirectory; + + internal string FinalOutputPath; + + internal string FinalPdbFilePath; + + internal string Win32ResourceFile; + + [CompilerGenerated] + private static Func _getAssemblyMetaData; + + internal CommandLineArguments CmdArguments => this.cmdArguments; + + internal List MetadataReferences + { + get; + set; + } + + internal string OutputFileName => this.outputFileName; + + internal string OutputFileDirectory => this.outputFileDirectory; + + internal CommonCompilationArguments(CompilerParameters parameters, CommandLineArguments cmdArguments) + { + this.cmdArguments = cmdArguments; + this.MetadataReferences = new List(); + ImmutableArray.Enumerator enumerator = this.CmdArguments.MetadataReferences.GetEnumerator(); + while (enumerator.MoveNext()) + { + CommandLineReference current = enumerator.Current; + string reference = current.Reference; + string text = this.ResolveReference(this.CmdArguments, reference); + if (text == null) + { + throw new ArgumentException(string.Format(Res.Cannot_Resolve_Reference, reference)); + } + var cache = AssemblyMetadataCache.GetInstance(); + + var assemblyMetadata = cache.GetOrAdd(text, AssemblyMetadata.CreateFromFile); + this.MetadataReferences.Add(assemblyMetadata.GetReference()); + } + this.ParseOutputFile(parameters.OutputAssembly, this.CmdArguments.BaseDirectory, out this.outputFileName, out this.outputFileDirectory); + this.FinalOutputPath = Path.Combine(this.OutputFileDirectory, this.OutputFileName); + if (parameters.IncludeDebugInformation) + { + this.FinalPdbFilePath = (this.CmdArguments.PdbPath ?? Path.ChangeExtension(this.FinalOutputPath, ".pdb")); + } + string win32ResourceFile = this.CmdArguments.Win32ResourceFile; + if (!string.IsNullOrWhiteSpace(win32ResourceFile)) + { + this.Win32ResourceFile = Path.Combine(this.CmdArguments.BaseDirectory, win32ResourceFile); + } + } + + //private MetadataReference CreateMetaDataReference(AssemblyMetadata assemblyMetadata) + //{ + // // Obsolete: new MetadataImageReference(assemblyMetadata, null, default(ImmutableArray), false, null, null) + + // var properties = new MetadataReferenceProperties(); + // DocumentationProvider documentationProvider = null; + // string filePath = null; + // string display = null; + + // var type = typeof (MetadataReference).Assembly.GetType("Microsoft.CodeAnalysis.MetadataImageReference"); + // var constructor = type.GetConstructors(BindingFlags.NonPublic).First(); + // return (MetadataReference) constructor.Invoke(new object[] {assemblyMetadata, properties, documentationProvider, filePath, display}); + //} + + private string ResolveReference(CommandLineArguments arguments, string reference) + { + string path = Path.Combine(arguments.BaseDirectory, reference); + if (File.Exists(path)) + { + return Path.GetFullPath(path); + } + ImmutableArray.Enumerator enumerator = arguments.ReferencePaths.GetEnumerator(); + while (enumerator.MoveNext()) + { + string current = enumerator.Current; + path = Path.Combine(current, reference); + if (File.Exists(path)) + { + return Path.GetFullPath(path); + } + } + return null; + } + + internal void ParseOutputFile(string value, string baseDirectory, out string outputFileName, out string outputDirectory) + { + outputFileName = null; + outputDirectory = null; + string arg = null; + string unquoted = CompilationUtil.RemoveAllQuotes(value); + CompilationUtil.ParseAndNormalizeFile(unquoted, baseDirectory, out outputFileName, out outputDirectory, out arg); + if (outputFileName == null) + { + outputFileName = null; + outputDirectory = baseDirectory; + throw new InvalidDataException(string.Format(Res.Cannot_Resolve_Path, arg)); + } + } + + internal static void FixTreatWarningsAsErrors(CompilerParameters parameters, Type codeDomProviderType) + { + parameters.TreatWarningsAsErrors = false; + } + } +} diff --git a/Composite/AspNet/Roslyn/CommonCompiler.cs b/Composite/AspNet/Roslyn/CommonCompiler.cs new file mode 100644 index 0000000000..c608001fb2 --- /dev/null +++ b/Composite/AspNet/Roslyn/CommonCompiler.cs @@ -0,0 +1,486 @@ +ï»żusing Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Emit; +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Security; +using System.Security.Permissions; +using System.Text; +using System.Threading; + +namespace Composite.AspNet.Roslyn +{ + internal abstract class CommonCompiler : ICodeCompiler + { + private const int Failed = 1; + + private const int Succeeded = 0; + + protected readonly CodeDomProvider _oldProvider; + + private readonly HashSet reportedDiagnostics = new HashSet(); + + private static readonly string CompilerErrorMessageFormat = "{0}({1},{2}): error {3}: {4}"; + + public CommonCompiler(CodeDomProvider oldProvider) + { + this._oldProvider = oldProvider; + } + + internal abstract SyntaxTree ParseText(string text); + + internal abstract SyntaxTree ParseFile(string file); + + internal abstract Compilation CreateCompilation(CommonCompilationArguments arguments, IEnumerable syntaxTrees); + + internal Compilation CreateCompilation(CommonCompilationArguments arguments, IEnumerable syntaxTrees, TextWriter outputWriter) + { + Compilation result; + try + { + result = this.CreateCompilation(arguments, syntaxTrees); + } + catch (Exception ex) + { + if (outputWriter != null) + { + outputWriter.WriteLine(CommonCompiler.GetErrorOutput(null, string.Format(Res.Internal_Compiler_Error, ex.Message))); + } + result = null; + } + return result; + } + + internal abstract CommonCompilationArguments ArgumentsFromParameters(CompilerParameters parameters, TextWriter outputWriter); + + internal CommonCompilationArguments ArgumentsFromParametersNoThrow(CompilerParameters parameters, TextWriter outputWriter) + { + CommonCompilationArguments result; + try + { + result = this.ArgumentsFromParameters(parameters, outputWriter); + } + catch (Exception ex) + { + if (outputWriter != null) + { + outputWriter.WriteLine(CommonCompiler.GetErrorOutput(null, string.Format(Res.Internal_Compiler_Error, ex.Message))); + } + result = null; + } + return result; + } + + public CompilerResults CompileAssemblyFromDom(CompilerParameters parameters, CodeCompileUnit compilationUnit) + { + return this.CompileAssemblyFromDomBatch(parameters, new CodeCompileUnit[] + { + compilationUnit + }); + } + + public CompilerResults CompileAssemblyFromDomBatch(CompilerParameters parameters, CodeCompileUnit[] compilationUnits) + { + Func func = null; + CompilerResults result; + try + { + if (func == null) + { + func = c => + { + var stringWriter = new StringWriter(); + this._oldProvider.GenerateCodeFromCompileUnit(c, stringWriter, new CodeGeneratorOptions()); + return this.ParseText(stringWriter.ToString()); + }; + } + IEnumerable syntaxTrees = compilationUnits.Select(func); + result = this.Compile(parameters, syntaxTrees); + } + finally + { + parameters.TempFiles.Delete(); + } + return result; + } + + public CompilerResults CompileAssemblyFromFile(CompilerParameters parameters, string fileName) + { + return this.CompileAssemblyFromFileBatch(parameters, new string[] + { + fileName + }); + } + + public CompilerResults CompileAssemblyFromFileBatch(CompilerParameters parameters, string[] fileNames) + { + Func func = null; + CompilerResults result; + try + { + if (func == null) + { + func = ParseFile; + } + result = this.Compile(parameters, fileNames.Select(func)); + } + finally + { + parameters.TempFiles.Delete(); + } + return result; + } + + public CompilerResults CompileAssemblyFromSource(CompilerParameters parameters, string source) + { + return this.CompileAssemblyFromSourceBatch(parameters, new string[] + { + source + }); + } + + public CompilerResults CompileAssemblyFromSourceBatch(CompilerParameters parameters, string[] sources) + { + Func func = null; + CompilerResults result; + try + { + if (func == null) + { + func = ParseText; + } + result = this.Compile(parameters, sources.Select(func)); + } + finally + { + parameters.TempFiles.Delete(); + } + return result; + } + + internal CompilerResults Compile(CompilerParameters parameters, IEnumerable syntaxTrees) + { + CompilerResults result; + using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) + { + CompilerResults compilerResults = this.Compile(parameters, syntaxTrees, stringWriter); + using (StringReader stringReader = new StringReader(stringWriter.ToString())) + { + string[] array = CommonCompiler.ReadAllLines(stringReader, Encoding.UTF8); + string[] array2 = array; + for (int i = 0; i < array2.Length; i++) + { + string value = array2[i]; + compilerResults.Output.Add(value); + } + } + result = compilerResults; + } + return result; + } + + internal CompilerResults Compile(CompilerParameters parameters, IEnumerable syntaxTrees, TextWriter outputWriter) + { + CompilerResults compilerResults = new CompilerResults(parameters.TempFiles); + compilerResults.NativeCompilerReturnValue = 1; + CommonCompilationArguments commonCompilationArguments = this.ArgumentsFromParametersNoThrow(parameters, outputWriter); + if (commonCompilationArguments == null) + { + return compilerResults; + } + if (commonCompilationArguments.CmdArguments.DisplayLogo) + { + this.PrintLogo(outputWriter); + } + if (commonCompilationArguments.CmdArguments.DisplayHelp) + { + this.PrintHelp(outputWriter); + return null; + } + if (this.ErrorInDiagnostics(commonCompilationArguments.CmdArguments.Errors, compilerResults, outputWriter)) + { + return compilerResults; + } + Compilation compilation = this.CreateCompilation(commonCompilationArguments, syntaxTrees, outputWriter); + if (compilation == null + || this.ErrorInDiagnostics(compilation.GetParseDiagnostics(default(CancellationToken)), compilerResults, outputWriter) + || this.ErrorInDiagnostics(compilation.GetDeclarationDiagnostics(default(CancellationToken)), compilerResults, outputWriter)) + { + return compilerResults; + } + SecurityPermission securityPermission = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); + securityPermission.Assert(); + try + { + compilerResults.Evidence = parameters.Evidence; + } + finally + { + CodeAccessPermission.RevertAssert(); + } + bool flag = false; + MemoryStream outputStream = new MemoryStream(); + MemoryStream pdbStream = null; + if (commonCompilationArguments.FinalPdbFilePath != null) + { + pdbStream = new MemoryStream(); + } + CompilerResults result; + using (outputStream) + { + using (pdbStream) + { + try + { + FileStream documentationStream = null; + string documentationPath = commonCompilationArguments.CmdArguments.DocumentationPath; + if (documentationPath != null) + { + documentationStream = OpenFile(documentationPath, outputWriter, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read | FileShare.Write | FileShare.Delete); + if (documentationStream == null) + { + result = compilerResults; + return result; + } + documentationStream.SetLength(0L); + } + Stream win32resourceFileStream = null; + if (!string.IsNullOrWhiteSpace(commonCompilationArguments.Win32ResourceFile)) + { + win32resourceFileStream = OpenFile(commonCompilationArguments.Win32ResourceFile, outputWriter, FileMode.Open, FileAccess.ReadWrite, FileShare.None); + } + EmitResult emitResult; + using (win32resourceFileStream) + { + using (documentationStream) + { + //// Obsolete + //emitResult = compilation.Emit(outputStream, + // commonCompilationArguments.OutputFileName, + // commonCompilationArguments.FinalPdbFilePath, + // pdbStream, documentationStream, default(CancellationToken), + // win32resourceFileStream, commonCompilationArguments.CmdArguments.ManifestResources); + + //var emitOptions = new EmitOptions(); + + emitResult = compilation.Emit(outputStream, + pdbStream, + null, + win32resourceFileStream, + commonCompilationArguments.CmdArguments.ManifestResources, + null, + null); + } + } + if (this.ErrorInDiagnostics(emitResult.Diagnostics, compilerResults, outputWriter)) + { + result = compilerResults; + } + else + { + if (!parameters.GenerateInMemory) + { + if (!CommonCompiler.WriteMemoryStreamToFile(outputStream, commonCompilationArguments.FinalOutputPath, outputWriter)) + { + flag = true; + result = compilerResults; + return result; + } + if (commonCompilationArguments.FinalPdbFilePath != null && !CommonCompiler.WriteMemoryStreamToFile(pdbStream, commonCompilationArguments.FinalPdbFilePath, outputWriter)) + { + flag = true; + result = compilerResults; + return result; + } + compilerResults.PathToAssembly = parameters.OutputAssembly; + } + else + { + byte[] rawAssembly = outputStream.ToArray(); + byte[] rawSymbolStore = null; + if (pdbStream != null) + { + try + { + rawSymbolStore = pdbStream.ToArray(); + } + catch + { + } + } + SecurityPermission securityPermission2 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); + securityPermission2.Assert(); + try + { + compilerResults.CompiledAssembly = Assembly.Load(rawAssembly, rawSymbolStore, parameters.Evidence); + } + finally + { + CodeAccessPermission.RevertAssert(); + } + compilerResults.CompiledAssembly = Assembly.Load(rawAssembly, rawSymbolStore); + } + compilerResults.NativeCompilerReturnValue = 0; + result = compilerResults; + } + } + finally + { + if (flag) + { + if (commonCompilationArguments.FinalOutputPath != null) + { + CommonCompiler.TryDeleteFile(commonCompilationArguments.FinalOutputPath); + } + if (commonCompilationArguments.FinalPdbFilePath != null) + { + CommonCompiler.TryDeleteFile(commonCompilationArguments.FinalPdbFilePath); + } + } + } + } + } + return result; + } + + private static bool WriteMemoryStreamToFile(MemoryStream memoryStream, string filename, TextWriter outputWriter) + { + bool result; + using (FileStream fileStream = CommonCompiler.CreateFile(filename, outputWriter)) + { + if (fileStream == null) + { + result = false; + } + else + { + memoryStream.Position = 0L; + memoryStream.CopyTo(fileStream); + result = true; + } + } + return result; + } + + internal static string[] ReadAllLines(StringReader stringReader, Encoding encoding) + { + List list = new List(); + string item; + while ((item = stringReader.ReadLine()) != null) + { + list.Add(item); + } + return list.ToArray(); + } + + internal void PrintHelp(TextWriter outputWriter) + { + throw new NotImplementedException(); + } + + internal void PrintLogo(TextWriter outputWriter) + { + outputWriter.WriteLine(Res.Product_Name); + outputWriter.WriteLine(Res.Copyright); + outputWriter.WriteLine(); + } + + internal bool ErrorInDiagnostics(IEnumerable diagnostics, CompilerResults results, TextWriter consoleOutput) + { + bool result = false; + foreach (Diagnostic current in diagnostics) + { + if (!this.reportedDiagnostics.Contains(current) + && current.Severity != DiagnosticSeverity.Info + && current.Severity != DiagnosticSeverity.Hidden) + { + this.reportedDiagnostics.Add(current); + if (current.Severity == DiagnosticSeverity.Error || current.IsWarningAsError) + { + result = true; + results.NativeCompilerReturnValue = 1; + } + CompilerError compilerError = this.CompilerErrorFromDiagnostic(current, consoleOutput); + if (compilerError != null) + { + results.Errors.Add(compilerError); + } + } + } + return result; + } + + internal abstract CompilerError CompilerErrorFromDiagnostic(Diagnostic diagnostic, TextWriter consoleOutput); + + internal static string GetErrorOutput(string errorNumber, string errorText) + { + return CommonCompiler.GetErrorOutput(null, 0, 0, errorNumber, errorText); + } + + internal static string GetErrorOutput(string filename = null, int line = 0, int column = 0, string errorNumber = null, string errorText = null) + { + return string.Format(CommonCompiler.CompilerErrorMessageFormat, new object[] + { + filename, + line, + column, + errorNumber, + errorText + }); + } + + internal static FileStream OpenFile(string filePath, TextWriter outputWriter, FileMode mode = FileMode.Open, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.None) + { + FileStream result; + try + { + result = File.Open(filePath, mode, access, share); + } + catch (Exception ex) + { + outputWriter?.WriteLine(GetErrorOutput(null, string.Format(Res.Compiler_Failed_To_Open_File, filePath, ex.Message))); + result = null; + } + return result; + } + + internal static FileStream CreateFile(string filePath, TextWriter outputWriter) + { + FileStream result; + try + { + result = File.Create(filePath, 1024); + } + catch (Exception ex) + { + outputWriter?.WriteLine(CommonCompiler.GetErrorOutput(null, string.Format(Res.Compiler_Failed_To_Create_File, filePath, ex.Message))); + result = null; + } + return result; + } + + internal static bool TryDeleteFile(string filePath) + { + bool result; + try + { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + result = true; + } + catch + { + result = false; + } + return result; + } + } +} diff --git a/Composite/AspNet/Roslyn/CompilationUtil.cs b/Composite/AspNet/Roslyn/CompilationUtil.cs new file mode 100644 index 0000000000..e12953cd36 --- /dev/null +++ b/Composite/AspNet/Roslyn/CompilationUtil.cs @@ -0,0 +1,68 @@ +ï»żusing System; +using System.IO; + +namespace Composite.AspNet.Roslyn +{ + internal static class CompilationUtil + { + internal static string RemoveAllQuotes(string arg) + { + return arg?.Replace("\"", ""); + } + + internal static string RemoveTrailingSpacesAndDots(string path) + { + if (path == null) + { + return path; + } + int length = path.Length; + int i = length - 1; + while (i >= 0) + { + char c = path[i]; + if (!char.IsWhiteSpace(c) && c != '.') + { + if (i != length - 1) + { + return path.Substring(0, i + 1); + } + return path; + } + + i--; + } + return string.Empty; + } + + internal static void ParseAndNormalizeFile(string unquoted, string baseDirectory, out string outputFileName, out string outputDirectory, out string invalidPath) + { + outputFileName = null; + outputDirectory = null; + invalidPath = unquoted; + string text = Path.Combine(baseDirectory, unquoted); + if (text != null) + { + try + { + text = Path.GetFullPath(text); + invalidPath = text; + outputFileName = Path.GetFileName(text); + outputDirectory = Path.GetDirectoryName(text); + } + catch (Exception) + { + text = null; + } + if (outputFileName != null) + { + outputFileName = CompilationUtil.RemoveTrailingSpacesAndDots(outputFileName); + } + } + if (text == null) + { + outputFileName = null; + } + } + } +} diff --git a/Composite/AspNet/Roslyn/Res.Designer.cs b/Composite/AspNet/Roslyn/Res.Designer.cs new file mode 100644 index 0000000000..4cd46bf909 --- /dev/null +++ b/Composite/AspNet/Roslyn/Res.Designer.cs @@ -0,0 +1,135 @@ +ï»ż//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Composite.AspNet.Roslyn { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Res { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Res() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Composite.AspNet.Roslyn.Res", typeof(Res).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to File name '{0}' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long.. + /// + internal static string Cannot_Resolve_Path { + get { + return ResourceManager.GetString("Cannot_Resolve_Path", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Assembly reference '{0}' is invalid and cannot be resolved.. + /// + internal static string Cannot_Resolve_Reference { + get { + return ResourceManager.GetString("Cannot_Resolve_Reference", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Compilation parameters:. + /// + internal static string Compilation_Arguments { + get { + return ResourceManager.GetString("Compilation_Arguments", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot create file: {0}. The error message is {1}. + /// + internal static string Compiler_Failed_To_Create_File { + get { + return ResourceManager.GetString("Compiler_Failed_To_Create_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot open file: {0}. The error message is {1}. + /// + internal static string Compiler_Failed_To_Open_File { + get { + return ResourceManager.GetString("Compiler_Failed_To_Open_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Copyright (C) Microsoft Corporation. All rights reserved.. + /// + internal static string Copyright { + get { + return ResourceManager.GetString("Copyright", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Internal Compiler Error: {0}. + /// + internal static string Internal_Compiler_Error { + get { + return ResourceManager.GetString("Internal_Compiler_Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CodeDOM Providers for .NET Compiler Platform (“Roslyn”). + /// + internal static string Product_Name { + get { + return ResourceManager.GetString("Product_Name", resourceCulture); + } + } + } +} diff --git a/Composite/AspNet/Roslyn/Res.resx b/Composite/AspNet/Roslyn/Res.resx new file mode 100644 index 0000000000..9c272a4987 --- /dev/null +++ b/Composite/AspNet/Roslyn/Res.resx @@ -0,0 +1,144 @@ +ï»ż + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + File name '{0}' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long. + + + Assembly reference '{0}' is invalid and cannot be resolved. + + + Compilation parameters: + + + Cannot create file: {0}. The error message is {1} + + + Cannot open file: {0}. The error message is {1} + + + Copyright (C) Microsoft Corporation. All rights reserved. + + + Internal Compiler Error: {0} + + + CodeDOM Providers for .NET Compiler Platform (“Roslyn”) + + \ No newline at end of file diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 7649a51e2e..8cbe01e822 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -70,6 +70,12 @@ ..\packages\Castle.Core.3.3.1\lib\net45\Castle.Core.dll True + + ..\Packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll + + + ..\Packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + ..\packages\Microsoft.Extensions.DependencyInjection.1.1.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll @@ -151,6 +157,9 @@ ..\packages\System.Reactive.Windows.Threading.3.0.0\lib\net45\System.Reactive.Windows.Threading.dll True + + ..\Packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + 3.0 @@ -251,6 +260,20 @@ + + + + + + Component + + + + + True + True + Res.resx + @@ -2660,6 +2683,12 @@ true + + + ResXFileCodeGenerator + Res.Designer.cs + + true Contains dll-s distributed with C1 CMS. Copyright 2017 - C1CMS + C1CMS OrckestraCMS CompositeC1 cms From c28fbdef2de6bc4ec7b58cb9fe0d996e01a6a74c Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 14 Mar 2017 10:28:08 +0100 Subject: [PATCH 060/135] Using Roslyn compiler v2.0, fixing compilation warnings --- Composite/AspNet/Roslyn/CSharpCodeProvider.cs | 2 ++ Composite/AspNet/Roslyn/CSharpCompiler.cs | 5 ---- .../Roslyn/CommonCompilationArguments.cs | 3 --- Composite/Composite.csproj | 23 +++++++++---------- Composite/packages.config | 10 ++++---- Website/DebugBuild.Web.config | 10 +++++++- Website/ReleaseBuild.Web.config | 10 +++++++- Website/WebSite.csproj | 21 ++++++++++++++--- Website/packages.config | 5 ++++ 9 files changed, 59 insertions(+), 30 deletions(-) diff --git a/Composite/AspNet/Roslyn/CSharpCodeProvider.cs b/Composite/AspNet/Roslyn/CSharpCodeProvider.cs index f1b2b05790..9f24b378cc 100644 --- a/Composite/AspNet/Roslyn/CSharpCodeProvider.cs +++ b/Composite/AspNet/Roslyn/CSharpCodeProvider.cs @@ -3,6 +3,7 @@ namespace Composite.AspNet.Roslyn { + /// public sealed class CSharpCodeProvider : Microsoft.CSharp.CSharpCodeProvider { @@ -14,6 +15,7 @@ public sealed class CSharpCodeProvider : Microsoft.CSharp.CSharpCodeProvider //{ //} + /// [Obsolete("Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.")] public override ICodeCompiler CreateCompiler() { diff --git a/Composite/AspNet/Roslyn/CSharpCompiler.cs b/Composite/AspNet/Roslyn/CSharpCompiler.cs index 40d0183d65..aafaea6aa0 100644 --- a/Composite/AspNet/Roslyn/CSharpCompiler.cs +++ b/Composite/AspNet/Roslyn/CSharpCompiler.cs @@ -6,16 +6,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; namespace Composite.AspNet.Roslyn { internal class CSharpCompiler : CommonCompiler { - [CompilerGenerated] - private static Func _treePredicate; - public CSharpCompiler(CSharpCodeProvider oldProvider) : base(oldProvider) { } diff --git a/Composite/AspNet/Roslyn/CommonCompilationArguments.cs b/Composite/AspNet/Roslyn/CommonCompilationArguments.cs index 62c92a3216..2863958904 100644 --- a/Composite/AspNet/Roslyn/CommonCompilationArguments.cs +++ b/Composite/AspNet/Roslyn/CommonCompilationArguments.cs @@ -22,9 +22,6 @@ internal abstract class CommonCompilationArguments internal string Win32ResourceFile; - [CompilerGenerated] - private static Func _getAssemblyMetaData; - internal CommandLineArguments CmdArguments => this.cmdArguments; internal List MetadataReferences diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 8cbe01e822..10ecf5f305 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -70,11 +70,11 @@ ..\packages\Castle.Core.3.3.1\lib\net45\Castle.Core.dll True - - ..\Packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll + + ..\packages\Microsoft.CodeAnalysis.Common.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll - - ..\Packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + + ..\packages\Microsoft.CodeAnalysis.CSharp.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll @@ -110,9 +110,9 @@ True - - False - ..\Packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + True @@ -157,8 +157,8 @@ ..\packages\System.Reactive.Windows.Threading.3.0.0\lib\net45\System.Reactive.Windows.Threading.dll True - - ..\Packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + + ..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll @@ -174,9 +174,8 @@ True - - ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll - True + + ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll diff --git a/Composite/packages.config b/Composite/packages.config index 6406beebdd..296dd55706 100644 --- a/Composite/packages.config +++ b/Composite/packages.config @@ -4,14 +4,14 @@ - - + + - + @@ -21,9 +21,9 @@ - + - + diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index 73c647bc9d..087f062fd4 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -98,7 +98,15 @@ - + + + + + + + + + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index d9fafd63a9..d2a0b36a76 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -100,7 +100,15 @@ - + + + + + + + + + diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index 803c48ed4d..2c5eea4d14 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -88,12 +88,18 @@ True - + False - ..\Packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + ..\Packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + ..\packages\System.IO.FileSystem.4.0.1\lib\net46\System.IO.FileSystem.dll + + + ..\packages\System.IO.FileSystem.Primitives.4.0.1\lib\net46\System.IO.FileSystem.Primitives.dll + ..\packages\System.Reactive.Core.3.0.0\lib\net46\System.Reactive.Core.dll True @@ -109,6 +115,12 @@ ..\Packages\Microsoft.Bcl.Metadata.1.0.11-alpha\lib\portable-net45+win8\System.Reflection.Metadata.dll + + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + False ..\Composite\bin\Debug\System.Threading.Tasks.Dataflow.dll @@ -161,6 +173,9 @@ + + ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + False ..\bin\TidyNet.dll @@ -2767,7 +2782,7 @@ - + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index 3f1f09600d..349ffb2349 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -20,7 +20,7 @@ - + From 415922c9d73809076c8fad7b64b115aac7b4c41a Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Tue, 14 Mar 2017 17:09:53 +0100 Subject: [PATCH 065/135] fix --- Website/test/e2e/suite/data/CreateGlobalDataTypes.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Website/test/e2e/suite/data/CreateGlobalDataTypes.js b/Website/test/e2e/suite/data/CreateGlobalDataTypes.js index bf6018e386..1986a97a16 100644 --- a/Website/test/e2e/suite/data/CreateGlobalDataTypes.js +++ b/Website/test/e2e/suite/data/CreateGlobalDataTypes.js @@ -19,6 +19,16 @@ module.exports = { .setFieldValue("Type name", "Parent") .selectContentTab("Fields") .clickLabel("Add New") + .setFieldValue("Name", "MyStringField") + .clickLabel("Add New") + .setFieldValue("Name", "MyIntField") + .clickDataBySibilings("Field type") + .clickText("Integer") + .clickLabel("Add New") + .setFieldValue("Name", "MyDateTimeField") + .clickDataBySibilings("Field type") + .clickText("Date") + .clickLabel("Add New") .clickSave() .closeDocumentTab("Parents") .assertTreeNodeHasChild("Global Datatypes","Auto.Tests.Parent") From df91bb1b6556f6a7dc07393fc8d8f9d56559d328 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 15 Mar 2017 13:42:38 +0100 Subject: [PATCH 066/135] retry finding frame based on selector for incremental delays till 60 sec --- Website/test/e2e/commands/selectFrame.js | 18 +++++++++++++++++- .../test/e2e/commands/selectFrameWithXpath.js | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Website/test/e2e/commands/selectFrame.js b/Website/test/e2e/commands/selectFrame.js index d13b86a331..5bd674ae60 100644 --- a/Website/test/e2e/commands/selectFrame.js +++ b/Website/test/e2e/commands/selectFrame.js @@ -1,5 +1,6 @@ var util = require('util'); var events = require('events'); +var Q = require('q'); function SelectFrame() { events.EventEmitter.call(this); @@ -95,10 +96,25 @@ function findSelectorInsideFrame(client, selector) { }); } +function retry(operation, delay) { + return operation().then(function(reason) { + if(reason){ + return true; + } + if(delay>60000){ + return false; + } + console.log('did not find selector retrying after '+delay+' ms'); + return Q.delay(delay).then(retry.bind(null, operation, delay * 2 )); + + }); +} + + SelectFrame.prototype.command = function(selector, noReset) { var reset = noReset ? Promise.resolve() : framePromise(this.client.api, null); reset - .then(() => findSelectorInsideFrame(this.client.api, selector)) + .then(() => retry(()=>findSelectorInsideFrame(this.client.api, selector),500)) .then(found => { if (!found) { this.client.assertion(false, 'not found', 'found', 'Did not find selector <' + selector + '> in any frame.', this.abortOnFailure, this._stackTrace); diff --git a/Website/test/e2e/commands/selectFrameWithXpath.js b/Website/test/e2e/commands/selectFrameWithXpath.js index 3944baa5e2..58f5a66fdd 100644 --- a/Website/test/e2e/commands/selectFrameWithXpath.js +++ b/Website/test/e2e/commands/selectFrameWithXpath.js @@ -1,5 +1,6 @@ var util = require('util'); var events = require('events'); +var Q = require('q'); function SelectFrameWithXpath() { events.EventEmitter.call(this); @@ -95,10 +96,24 @@ function findSelectorInsideFrame(client, selector) { }); } +function retry(operation, delay) { + return operation().then(function(reason) { + if(reason){ + return true; + } + if(delay>60000){ + return false; + } + console.log('did not find selector retrying after '+delay+' ms'); + return Q.delay(delay).then(retry.bind(null, operation, delay * 2 )); + + }); +} + SelectFrameWithXpath.prototype.command = function(selector, noReset) { var reset = noReset ? Promise.resolve() : framePromise(this.client.api, null); reset - .then(() => findSelectorInsideFrame(this.client.api, selector)) + .then(() => retry(()=>findSelectorInsideFrame(this.client.api, selector),500)) .then(found => { if (!found) { this.client.assertion(false, 'not found', 'found', 'Did not find selector <' + selector + '> in any frame.', this.abortOnFailure, this._stackTrace); From 39f68cbd00cc9ff7d7d9c85581032f24583e6a26 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 15 Mar 2017 14:15:13 +0100 Subject: [PATCH 067/135] XmlDataProvider refactoring - the same exceptions were logged multiple times --- .../XmlDataProviderDocumentWriter.cs | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/XmlDataProviderDocumentWriter.cs b/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/XmlDataProviderDocumentWriter.cs index d1a8d806d8..b8fe53d5fd 100644 --- a/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/XmlDataProviderDocumentWriter.cs +++ b/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/XmlDataProviderDocumentWriter.cs @@ -2,7 +2,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Xml.Linq; using Composite.Core.Extensions; using Composite.Core; @@ -21,20 +20,22 @@ internal static class XmlDataProviderDocumentWriter private static readonly object _flushEnterLock = new object(); private static readonly object _flushExecuteLock = new object(); private static DateTime _activeFlushActivityStart = DateTime.MinValue; - private static System.Timers.Timer _autoCommitTimer; + private static readonly System.Timers.Timer _autoCommitTimer; private static readonly TimeSpan _updateFrequency = TimeSpan.FromMilliseconds(1000); private static readonly TimeSpan _fileIoDelay = TimeSpan.FromMilliseconds(10); // small pause between io operations to reduce asp.net appPool recycles due to FileWatcher buffer fills - edge case, but highly annoying private const int NumberOfRetries = 30; - private static readonly string LogTitle = "XmlDataProvider"; - private static bool forceImmediateWrite = false; + private static readonly string LogTitle = nameof(XmlDataProvider); + private static bool _forceImmediateWrite; static XmlDataProviderDocumentWriter() { - _autoCommitTimer = new System.Timers.Timer(_updateFrequency.TotalMilliseconds); - _autoCommitTimer.AutoReset = true; - _autoCommitTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnAutoCommitTimer); + _autoCommitTimer = new System.Timers.Timer(_updateFrequency.TotalMilliseconds) + { + AutoReset = true + }; + _autoCommitTimer.Elapsed += OnAutoCommitTimer; _autoCommitTimer.Start(); GlobalEventSystemFacade.SubscribeToShutDownEvent(OnShutDownEvent); @@ -43,7 +44,7 @@ static XmlDataProviderDocumentWriter() private static void OnShutDownEvent(ShutDownEventArgs args) { - forceImmediateWrite = true; + _forceImmediateWrite = true; Flush(); } @@ -52,7 +53,7 @@ internal static void Save(FileRecord fileRecord) { _dirtyRecords.Enqueue(fileRecord); - if (forceImmediateWrite) + if (_forceImmediateWrite) { Flush(); } @@ -91,7 +92,7 @@ internal static void Flush() { lock (_flushEnterLock) { - if (!forceImmediateWrite && (DateTime.Now - _activeFlushActivityStart).TotalSeconds < 30) + if (!_forceImmediateWrite && (DateTime.Now - _activeFlushActivityStart).TotalSeconds < 30) { return; } @@ -120,7 +121,15 @@ internal static void Flush() } catch (Exception ex) { + if (ex is DirectoryNotFoundException) + { + Log.LogWarning(LogTitle, $"Failed to save file '{fileRecord.FilePath}' as the underlying directory does not exist."); + continue; + } + + Log.LogCritical(LogTitle, $"Failed to save data to the file: '{fileRecord.FilePath}'"); Log.LogError(LogTitle, ex); + _dirtyRecords.Enqueue(fileRecord); } } @@ -135,15 +144,11 @@ internal static void Flush() [System.Diagnostics.CodeAnalysis.SuppressMessage("Composite.IO", "Composite.DoNotCallXmlWriterCreateWithPath:DoNotCallXmlWriterCreateWithPath", Justification = "This is what we want, to handle broken saves")] private static void DoSave(FileRecord fileRecord) { - XDocument xDocument = new XDocument(); - - XElement root = new XElement(GetRootElementName(fileRecord.ElementName)); - xDocument.Add(root); + var root = new XElement(GetRootElementName(fileRecord.ElementName)); + var xDocument = new XDocument(root); var recordSet = fileRecord.RecordSet; - List elements = new List(recordSet.Index.GetValues()); - - string key = fileRecord.FilePath.ToLowerInvariant(); + var elements = new List(recordSet.Index.GetValues()); Func, IOrderedEnumerable> orderer; if (TryGetFileOrderer(out orderer, fileRecord.FilePath)) @@ -168,9 +173,11 @@ private static void DoSave(FileRecord fileRecord) try { // Saving to temp file and file move to prevent broken saves - XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); - xmlWriterSettings.CheckCharacters = false; - xmlWriterSettings.Indent = true; + var xmlWriterSettings = new XmlWriterSettings + { + CheckCharacters = false, + Indent = true + }; using (XmlWriter xmlWriter = XmlWriter.Create(fileRecord.TempFilePath, xmlWriterSettings)) { @@ -209,19 +216,17 @@ private static void DoSave(FileRecord fileRecord) Log.LogCritical(LogTitle, "Failed deleting the file: " + fileRecord.FilePath); if (lastException != null) throw lastException; - throw new InvalidOperationException("Failed to delete a file, this code shouldn't be reacheable"); + throw new InvalidOperationException("Failed to delete a file, this code shouldn't be reachable"); } fileRecord.FileModificationDate = C1File.GetLastWriteTime(fileRecord.FilePath); } catch (Exception exception) { - Log.LogCritical(LogTitle, "Failed to save data to the file file:" + fileRecord.FilePath); - Log.LogCritical(LogTitle, exception); thrownException = exception; } } - // ThreadAbortException should have a higher prioriry, and therefore we're doing rethrow in a separate block + // ThreadAbortException should have a higher priority, and therefore we're doing rethrow in a separate block if (thrownException != null) throw thrownException; } From d1edf66fe50b29a9e2b6875e1bab612483148904 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 15 Mar 2017 16:03:35 +0100 Subject: [PATCH 068/135] fix reset site location --- Website/test/e2e/globals.js | 3 +- Website/test/e2e/reset.js | 294 ++++++++++++++++++------------------ 2 files changed, 149 insertions(+), 148 deletions(-) diff --git a/Website/test/e2e/globals.js b/Website/test/e2e/globals.js index d111f9c05f..7ea6d9a1d3 100644 --- a/Website/test/e2e/globals.js +++ b/Website/test/e2e/globals.js @@ -25,10 +25,11 @@ var templatesOnly = { } module.exports = { + siteLocation : "", asyncHookTimeout : 20000, timeouts : timeouts, setupOptions : setupOptions, - starterSites : starterSites, + starterSites : starterSites, beforeEach: function (browser, done) { browser.resizeWindow(1400, 1000, done); }, diff --git a/Website/test/e2e/reset.js b/Website/test/e2e/reset.js index 2c9313ab1a..ca711cb6ea 100644 --- a/Website/test/e2e/reset.js +++ b/Website/test/e2e/reset.js @@ -1,150 +1,149 @@ const removePaths = [ - 'Website/App_Data/Composite/Configuration/Composite.Forms.FormBuilder.xml', - 'Website/App_Data/Composite/Configuration/Composite.Media.ImageCrop.xml', - 'Website/App_Data/Composite/Configuration/DynamicXmlDataProvider.config', - 'Website/App_Data/Composite/Configuration/DynamicSqlDataProvider.config', - 'Website/App_Data/Composite/Configuration/FirstTimeStart.xml', - 'Website/App_Data/Composite/Configuration/InstallationInformation.xml', - 'Website/App_Data/Composite/Configuration/SystemInitialized.xml', - 'Website/App_Data/Composite/DataMetaData/', - 'Website/App_Data/Composite/DataStores/', - 'Website/App_Data/Composite/DynamicTypeForms/*', - 'Website/App_Data/Composite/InlineCSharpFunctions/', - 'Website/App_Data/Composite/LanguagePacks/', - 'Website/App_Data/Composite/PackageLicenses/', - 'Website/App_Data/Composite/Azure/', - 'Website/App_Data/Composite/Packages/*', - 'Website/App_Data/Media/*', - 'Website/App_Data/PageTemplateFeatures/', - 'Website/App_Data/PageTemplates/*.cshtml', - 'Website/App_Data/PageTemplates/*.master*', - 'Website/App_Data/Razor/Composite/', - 'Website/App_Data/Razor/Orckestra/', - 'Website/App_Data/Razor/Layout/', - 'Website/App_Data/Razor/PageBlocks/', - 'Website/App_Data/Razor/Widgets/', - 'Website/App_Data/Razor/Content/', - 'Website/App_Data/Razor/ -- !(web.config) ', - 'Website/App_Data/Components/', - 'Website/App_GlobalResources/', - 'Website/BlogMetaWeblog.ashx', - 'Website/BlogRssFeed.ashx', - 'Website/Composite/InstalledPackages/', - 'Website/Frontend/Composite/', - 'Website/Frontend/Orckestra/', - 'Website/Frontend/Images/*', - 'Website/Frontend/Scripts/*', - 'Website/Frontend/Styles/VisualEditor.less', - 'Website/Frontend/Styles/style.less', - 'Website/Frontend/Styles/style.min.css', - 'Website/Frontend/Styles/bootstrap', - 'Website/Frontend/Styles/font-awesome', - 'Website/Frontend/Styles/includes', - 'Website/Frontend/Styles/PageBlocks', - 'Website/Frontend/Styles/style.less', - 'Website/Frontend/Styles/style.min.css', - 'Website/Frontend/Styles/VisualEditor.common.less', - 'Website/Frontend/Styles/VisualEditor.less', - 'Website/Frontend/fonts/', - 'Website/bin/Antlr3.Runtime.dll', - 'Website/bin/Composite.Community.*.*', - 'Website/bin/Composite.Forms.FormBuilder.dll', - 'Website/bin/Composite.Forms.Renderer.dll', - 'Website/bin/Composite.Media.*.*', - 'Website/bin/Composite.Search.SimplePageSearch.dll', - 'Website/bin/Composite.XmlSerializers.dll', - 'Website/bin/Composite.Tools.*.*', - 'Website/bin/Composite.Web.*.*', - 'Website/bin/Orckestra.Web.Css.Less.dll', - 'Website/bin/CookComputing.XmlRpcV2.dll', - 'Website/bin/ICSharpCode.SharpZipLib.dll', - 'Website/bin/System.Web.Optimization.dll', - 'Website/bin/WebGrease.dll', - 'Website/Frontend/Composite/', - 'Website/App_Data/UserControls/ -- !(web.config)', - 'Website/App_Data/PageTemplateFeatures/', - 'Website/Web.config', - 'Website/App_Data/Composite/Composite.config', - 'Website/App_Data/Composite/Cache/Assemblies/*', - 'Website/App_Data/Composite/Cache/', - //'Website/App_Data/Composite/Cache/ResourceCache/*', - 'Website/App_Data/Xslt/*', - 'Website/App_Data/Composite/LogFiles/*', - 'Website/App_Code/*', - 'Website/App_Data/Composite/ApplicationState/', - //'Website/App_Data/Composite/ApplicationState/SerializedWorkflows/*', - 'Website/Composite/InstalledPackages/', - 'Website/BlogRssFeed.ashx', - 'Website/BlogCommentsRssFeed.ashx', - 'Website/BlogRssFeed.ashx', - 'Website/Bin/Composite.Community.Blog.dll', - 'Website/Bin/CookComputing.XmlRpcV2.dll', - 'Website/BlogMetaWeblog.ashx', - 'Website/App_Data/Razor/Composite/Community/Blog/', - 'Website/App_GlobalResources/Composite.Community.Blog/', - 'Website/Composite/InstalledPackages/content/forms/Composite.Community.Blog/', - 'Website/Composite/InstalledPackages/controls/FormsControls/Composite.Community.Blog/', - 'Website/Frontend/Composite/Community/Blog/', - 'Website/App_GlobalResources/Composite/Community/Blog.resx', - 'Website/App_GlobalResources/Composite/Community/Blog.ru-ru.resx', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Entries.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xmll', - 'Website/App_Data/Composite/DynamicTypeForms/Composite/Community/Blog/Authors.xml', - 'Website/App_Data/Composite/DynamicTypeForms/Composite/Community/Blog/Entries.xml', - 'Website/Bin/CompositeC1Contrib.RazorFunctions.dll', - 'Website/Bin/Microsoft.Web.*.dll', - 'Website/Bin/Composite.Community.Extranet.dll', - 'Website/Bin/Composite.Community.Newsletter.dll', - 'Website/Bin/Composite.Community.Newsletter.SubjectBased.dll', - 'Website/Bin/Composite.Community.Newsletter.DataTypeBased.dll', - 'Website/Bin/Composite.Community.Newsletter.FunctionBased.dll', - 'Website/Newsletter.ashx', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.Newsletter.SubjectBased.xml', - 'Website/App_Data/NewsletterType/', - 'Website/App_GlobalResources/Composite/Community/Newsletter.resx', - 'Website/Bin/Composite.Community.EventCalendar.dll', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.EventCalendar.EventsApp.xml', - 'Website/App_GlobalResources/Composite/Community/ContactForm.resx', - 'Website/App_GlobalResources/Composite/Community/ContactForm.ru-RU.resx', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.ContactForm.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.ContactFrom.EmailTemplate.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.ContactForm.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Community.ContactFrom.EmailTemplate.xml', - 'Website/Bin/Composite.Versioning.ContentVersioning.dll', - 'Website/App_Data/Composite/TreeDefinitions/Composite.Versioning.ContentVersioning.xml', - 'Website/Frontend/Composite/C1BaseSite/', - 'Website/Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.News.NewsItem.da-dk.xml', - 'Website/Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.News.NewsItem.en-us.xml', - 'Website/Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.TeaserSpot.da-dk.xml', - 'Website/Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.TeaserSpot.en-us.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.TemplateSites.Base01.News.NewsItem.xml', - 'Website/App_Data/Composite/TreeDefinitions/Composite.TemplateSites.Base01.TeaserSpot.xml', - 'Website/App_Data/Composite/TreeDefinitions/Orckestra.Lists.Tabs.xml', - 'Website/App_Data/Composite/TreeDefinitions/Orckestra.Lists.Portfolio.Application.xml', - 'Website/Frontend/Styles/Print.css', - 'Website/Frontend/Styles/Screen.css', - 'Website/Frontend/Styles/VisualEditor/VisualEditor.Config.css', - 'Website/Frontend/Styles/VisualEditor/VisualEditor.Config.xml', - 'Website/Frontend/Styles/VisualEditor/VisualEditor.Default.css', - 'Website/Frontend/Composite/Search/SimplePageSearch/Styles.css', - 'Website/Composite/content/forms/InstalledPackages/Composite.Tools.PackageCreator/', - 'Website/Bin/Composite.Tools.PackageCreator.dll', - 'Website/Composite/InstalledPackages/localization/Composite.Tools.PackageCreator.en-us.xml', - 'Website/App_Data/PackageCreator', - 'Website/App_Data/Composite/Configuration\Composite.Forms.FormBuilder.xml', - 'Website/App_Data/Composite/Configuration\Composite.Media.ImageCrop.xml', - 'Website/Frontend/Scripts/', - 'Website/Frontend/Styles/ -- !(VisualEditor.common.css)', - 'Website/Frontend/Images/', - 'Website/Frontend/Composite/', - 'Website/bin/Composite.Generated.dll', + 'App_Data/Composite/Configuration/Composite.Forms.FormBuilder.xml', + 'App_Data/Composite/Configuration/Composite.Media.ImageCrop.xml', + 'App_Data/Composite/Configuration/DynamicXmlDataProvider.config', + 'App_Data/Composite/Configuration/DynamicSqlDataProvider.config', + 'App_Data/Composite/Configuration/FirstTimeStart.xml', + 'App_Data/Composite/Configuration/InstallationInformation.xml', + 'App_Data/Composite/Configuration/SystemInitialized.xml', + 'App_Data/Composite/DataMetaData/', + 'App_Data/Composite/DataStores/', + 'App_Data/Composite/DynamicTypeForms/*', + 'App_Data/Composite/InlineCSharpFunctions/', + 'App_Data/Composite/LanguagePacks/', + 'App_Data/Composite/PackageLicenses/', + 'App_Data/Composite/Azure/', + 'App_Data/Composite/Packages/*', + 'App_Data/Media/*', + 'App_Data/PageTemplateFeatures/', + 'App_Data/PageTemplates/*.cshtml', + 'App_Data/PageTemplates/*.master*', + 'App_Data/Razor/Composite/', + 'App_Data/Razor/Orckestra/', + 'App_Data/Razor/Layout/', + 'App_Data/Razor/PageBlocks/', + 'App_Data/Razor/Widgets/', + 'App_Data/Razor/Content/', + 'App_Data/Razor/ -- !(web.config) ', + 'App_Data/Components/', + 'App_GlobalResources/', + 'BlogMetaWeblog.ashx', + 'BlogRssFeed.ashx', + 'Composite/InstalledPackages/', + 'Frontend/Composite/', + 'Frontend/Orckestra/', + 'Frontend/Images/*', + 'Frontend/Scripts/*', + 'Frontend/Styles/VisualEditor.less', + 'Frontend/Styles/style.less', + 'Frontend/Styles/style.min.css', + 'Frontend/Styles/bootstrap', + 'Frontend/Styles/font-awesome', + 'Frontend/Styles/includes', + 'Frontend/Styles/PageBlocks', + 'Frontend/Styles/style.less', + 'Frontend/Styles/style.min.css', + 'Frontend/Styles/VisualEditor.common.less', + 'Frontend/Styles/VisualEditor.less', + 'Frontend/fonts/', + 'bin/Antlr3.Runtime.dll', + 'bin/Composite.Community.*.*', + 'bin/Composite.Forms.FormBuilder.dll', + 'bin/Composite.Forms.Renderer.dll', + 'bin/Composite.Media.*.*', + 'bin/Composite.Search.SimplePageSearch.dll', + 'bin/Composite.XmlSerializers.dll', + 'bin/Composite.Tools.*.*', + 'bin/Composite.Web.*.*', + 'bin/Orckestra.Web.Css.Less.dll', + 'bin/CookComputing.XmlRpcV2.dll', + 'bin/ICSharpCode.SharpZipLib.dll', + 'bin/System.Web.Optimization.dll', + 'bin/WebGrease.dll', + 'Frontend/Composite/', + 'App_Data/UserControls/ -- !(web.config)', + 'App_Data/PageTemplateFeatures/', + 'Web.config', + 'App_Data/Composite/Composite.config', + 'App_Data/Composite/Cache/Assemblies/*', + 'App_Data/Composite/Cache/', + 'App_Data/Xslt/*', + 'App_Data/Composite/LogFiles/*', + 'App_Code/*', + 'App_Data/Composite/ApplicationState/', + 'Composite/InstalledPackages/', + 'BlogRssFeed.ashx', + 'BlogCommentsRssFeed.ashx', + 'BlogRssFeed.ashx', + 'Bin/Composite.Community.Blog.dll', + 'Bin/CookComputing.XmlRpcV2.dll', + 'BlogMetaWeblog.ashx', + 'App_Data/Razor/Composite/Community/Blog/', + 'App_GlobalResources/Composite.Community.Blog/', + 'Composite/InstalledPackages/content/forms/Composite.Community.Blog/', + 'Composite/InstalledPackages/controls/FormsControls/Composite.Community.Blog/', + 'Frontend/Composite/Community/Blog/', + 'App_GlobalResources/Composite/Community/Blog.resx', + 'App_GlobalResources/Composite/Community/Blog.ru-ru.resx', + 'App_Data/Composite/TreeDefinitions/Composite.Community.Blog.xml', + 'App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Entries.xml', + 'App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xml', + 'App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xmll', + 'App_Data/Composite/DynamicTypeForms/Composite/Community/Blog/Authors.xml', + 'App_Data/Composite/DynamicTypeForms/Composite/Community/Blog/Entries.xml', + 'Bin/CompositeC1Contrib.RazorFunctions.dll', + 'Bin/Microsoft.Web.*.dll', + 'Bin/Composite.Community.Extranet.dll', + 'Bin/Composite.Community.Newsletter.dll', + 'Bin/Composite.Community.Newsletter.SubjectBased.dll', + 'Bin/Composite.Community.Newsletter.DataTypeBased.dll', + 'Bin/Composite.Community.Newsletter.FunctionBased.dll', + 'Newsletter.ashx', + 'App_Data/Composite/TreeDefinitions/Composite.Community.Newsletter.SubjectBased.xml', + 'App_Data/NewsletterType/', + 'App_GlobalResources/Composite/Community/Newsletter.resx', + 'Bin/Composite.Community.EventCalendar.dll', + 'App_Data/Composite/TreeDefinitions/Composite.Community.EventCalendar.EventsApp.xml', + 'App_GlobalResources/Composite/Community/ContactForm.resx', + 'App_GlobalResources/Composite/Community/ContactForm.ru-RU.resx', + 'App_Data/Composite/TreeDefinitions/Composite.Community.ContactForm.xml', + 'App_Data/Composite/TreeDefinitions/Composite.Community.ContactFrom.EmailTemplate.xml', + 'App_Data/Composite/TreeDefinitions/Composite.Community.ContactForm.xml', + 'App_Data/Composite/TreeDefinitions/Composite.Community.ContactFrom.EmailTemplate.xml', + 'Bin/Composite.Versioning.ContentVersioning.dll', + 'App_Data/Composite/TreeDefinitions/Composite.Versioning.ContentVersioning.xml', + 'Frontend/Composite/C1BaseSite/', + 'Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.News.NewsItem.da-dk.xml', + 'Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.News.NewsItem.en-us.xml', + 'Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.TeaserSpot.da-dk.xml', + 'Composite/InstalledPackages/localization/Composite.TemplateSites.Base01.TeaserSpot.en-us.xml', + 'App_Data/Composite/TreeDefinitions/Composite.TemplateSites.Base01.News.NewsItem.xml', + 'App_Data/Composite/TreeDefinitions/Composite.TemplateSites.Base01.TeaserSpot.xml', + 'App_Data/Composite/TreeDefinitions/Orckestra.Lists.Tabs.xml', + 'App_Data/Composite/TreeDefinitions/Orckestra.Lists.Portfolio.Application.xml', + 'Frontend/Styles/Print.css', + 'Frontend/Styles/Screen.css', + 'Frontend/Styles/VisualEditor/VisualEditor.Config.css', + 'Frontend/Styles/VisualEditor/VisualEditor.Config.xml', + 'Frontend/Styles/VisualEditor/VisualEditor.Default.css', + 'Frontend/Composite/Search/SimplePageSearch/Styles.css', + 'Composite/content/forms/InstalledPackages/Composite.Tools.PackageCreator/', + 'Bin/Composite.Tools.PackageCreator.dll', + 'Composite/InstalledPackages/localization/Composite.Tools.PackageCreator.en-us.xml', + 'App_Data/PackageCreator', + 'App_Data/Composite/Configuration\Composite.Forms.FormBuilder.xml', + 'App_Data/Composite/Configuration\Composite.Media.ImageCrop.xml', + 'Frontend/Scripts/', + 'Frontend/Styles/ -- !(VisualEditor.common.css)', + 'Frontend/Images/', + 'Frontend/Composite/', + 'bin/Composite.Generated.dll', ] const rimraf = require('rimraf'); const fs = require('fs'); +const globals = require(process.cwd()+'/Website/test/e2e/globals'); -const basepath = process.cwd(); +var basepath = globals.siteLocation || process.cwd()+'/Website'; function copyFile(source, target) { return new Promise(function(resolve, reject) { @@ -167,7 +166,7 @@ function delay() { function deleteWebConfig() { return new Promise( function (resolve, reject) { - rimraf(basepath + '/Website/Web.config', {}, function (err) { + rimraf(basepath + '/Web.config', {}, function (err) { if (err) { reject(err); } else { @@ -178,6 +177,7 @@ function deleteWebConfig() { ); } module.exports = function reset(callback) { + console.log('resetting site in '+basepath); deleteWebConfig().then(function () { return delay() }).then(function () { @@ -195,10 +195,10 @@ module.exports = function reset(callback) { })])} ) .then(function () { return Promise.all([ - copyFile(basepath + '/Website/DebugBuild.Web.config', - basepath + '/Website/Web.config'), - copyFile(basepath + '/Website/App_Data/Composite/DebugBuild.Composite.config', - basepath + '/Website/App_Data/Composite/Composite.config') + copyFile(basepath + '/DebugBuild.Web.config', + basepath + '/Web.config'), + copyFile(basepath + '/App_Data/Composite/DebugBuild.Composite.config', + basepath + '/App_Data/Composite/Composite.config') ]); }) .then(function () { From 770bc2a7407273509ad9ae6601a0da722f8f25bf Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 15 Mar 2017 17:24:01 +0100 Subject: [PATCH 069/135] fix reset --- Website/test/e2e/reset.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Website/test/e2e/reset.js b/Website/test/e2e/reset.js index ca711cb6ea..2cf725eb98 100644 --- a/Website/test/e2e/reset.js +++ b/Website/test/e2e/reset.js @@ -144,6 +144,7 @@ const fs = require('fs'); const globals = require(process.cwd()+'/Website/test/e2e/globals'); var basepath = globals.siteLocation || process.cwd()+'/Website'; +var sourcepath = process.cwd()+'/Website'; function copyFile(source, target) { return new Promise(function(resolve, reject) { @@ -195,9 +196,9 @@ module.exports = function reset(callback) { })])} ) .then(function () { return Promise.all([ - copyFile(basepath + '/DebugBuild.Web.config', + copyFile(sourcepath + '/ReleaseBuild.Web.config', basepath + '/Web.config'), - copyFile(basepath + '/App_Data/Composite/DebugBuild.Composite.config', + copyFile(sourcepath + '/App_Data/Composite/ReleaseBuild.Composite.config', basepath + '/App_Data/Composite/Composite.config') ]); }) From fd164688aee77e6700c0518c61952f67bb125780 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Thu, 16 Mar 2017 11:45:18 +0100 Subject: [PATCH 070/135] move testing starter sites and packages into separate nightwatch environment --- nightwatch.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nightwatch.json b/nightwatch.json index 256722e46e..c15072786d 100644 --- a/nightwatch.json +++ b/nightwatch.json @@ -29,7 +29,9 @@ "silent": true, "end_session_on_fail": true, "skip_testcases_on_fail": false, - "exclude" : ["Website/test/e2e/suite/010_setupPackages/installSQLPackage.js"], + "exclude" : [ "Website/test/e2e/suite/010_setupPackages/installSQLPackage.js", + "Website/test/e2e/suite/packages", + "Website/test/e2e/suite/zzz_starterSites"], "globals": { "connectionString": "" }, @@ -57,6 +59,10 @@ "Website/test/e2e/suite/zzz_starterSites"] }, + "starter": { + "exclude" : ["Website/test/e2e/suite/010_setupPackages/installSQLPackage.js"] + }, + "firefox" : { "desiredCapabilities": { "browserName": "firefox", From b081eabc263b0c59cb4d07ffb3d25f61c206d70b Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 16 Mar 2017 13:28:52 +0100 Subject: [PATCH 071/135] Workflows that are persisted on shutdown are now persisted on idle as well --- .../FunctionTesterWorkflow.cs | 4 ++-- .../AddTypeToWhiteListWorkflow.cs | 4 +--- .../RemoveTypeFromWhiteListWorkflow.cs | 4 +--- .../Workflow/FilePersistenceService.cs | 23 ++++++++++++++----- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/FunctionTesterWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/FunctionTesterWorkflow.cs index c4d52c9bc4..c9f12b232f 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/FunctionTesterWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/FunctionTesterWorkflow.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -26,7 +26,7 @@ namespace Composite.Workflows.Plugins.Elements.ElementProviders.AllFunctionsElementProvider { - [AllowPersistingWorkflow(WorkflowPersistingType.Shutdown)] + [AllowPersistingWorkflow(WorkflowPersistingType.Idle)] public sealed partial class FunctionTesterWorkflow : Composite.C1Console.Workflow.Activities.FormsWorkflow { public FunctionTesterWorkflow() diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/AddTypeToWhiteListWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/AddTypeToWhiteListWorkflow.cs index 2fd758e1a3..92d027a2ee 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/AddTypeToWhiteListWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/AddTypeToWhiteListWorkflow.cs @@ -1,13 +1,11 @@ -using System; +ï»żusing System; using Composite.C1Console.Actions; using Composite.Data; using Composite.Data.Types; -using Composite.C1Console.Workflow; namespace Composite.Plugins.Elements.ElementProviders.GeneratedDataTypesElementProvider { - [AllowPersistingWorkflow(WorkflowPersistingType.Shutdown)] public sealed partial class AddTypeToWhiteListWorkflow : Composite.C1Console.Workflow.Activities.FormsWorkflow { public AddTypeToWhiteListWorkflow() diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/RemoveTypeFromWhiteListWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/RemoveTypeFromWhiteListWorkflow.cs index 4eec6127f0..71a87e86c6 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/RemoveTypeFromWhiteListWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/GeneratedDataTypesElementProvider/RemoveTypeFromWhiteListWorkflow.cs @@ -1,13 +1,11 @@ -using System; +ï»żusing System; using Composite.C1Console.Actions; using Composite.Data; using Composite.Data.Types; -using Composite.C1Console.Workflow; namespace Composite.Plugins.Elements.ElementProviders.GeneratedDataTypesElementProvider { - [AllowPersistingWorkflow(WorkflowPersistingType.Shutdown)] public sealed partial class RemoveTypeFromWhiteListWorkflow : Composite.C1Console.Workflow.Activities.FormsWorkflow { public RemoveTypeFromWhiteListWorkflow() diff --git a/Composite/C1Console/Workflow/FilePersistenceService.cs b/Composite/C1Console/Workflow/FilePersistenceService.cs index 91b52a3e6a..c1341ec0cb 100644 --- a/Composite/C1Console/Workflow/FilePersistenceService.cs +++ b/Composite/C1Console/Workflow/FilePersistenceService.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -125,25 +125,36 @@ protected override Activity LoadWorkflowInstanceState(Guid instanceId) protected override void SaveCompletedContextActivity(Activity activity) { - Guid contextGuid = (Guid)activity.GetValue(Activity.ActivityContextGuidProperty); - SerializeActivity(activity, contextGuid); + SaveWorkflowInstanceState(activity); } protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock) { - Guid contextGuid = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty); - SerializeActivity(rootActivity, contextGuid); + SaveWorkflowInstanceState(rootActivity); } protected override bool UnloadOnIdle(Activity activity) { - return GetPersistingType(activity) == WorkflowPersistingType.Idle; + var persistingType = GetPersistingType(activity); + + if (persistingType == WorkflowPersistingType.Shutdown) + { + SaveWorkflowInstanceState(activity); + } + + return persistingType == WorkflowPersistingType.Idle; } + private void SaveWorkflowInstanceState(Activity activity) + { + Guid workflowId = (Guid)activity.GetValue(Activity.ActivityContextGuidProperty); + SerializeActivity(activity, workflowId); + } + protected override void UnlockWorkflowInstanceState(Activity rootActivity) { From df7a8c16de2c0e9442773d72a135c9ef3618281b Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 17 Mar 2017 13:57:34 +0100 Subject: [PATCH 072/135] Performance optimizations in relation to deleting multiple pages in the console --- .../PageElementProvider/DeletePageWorkflow.cs | 13 ++-- Composite/C1Console/Trees/TreeFacadeImpl.cs | 12 ++-- Composite/Core/Linq/Extensions.cs | 4 +- Composite/Data/DataReferenceFacade.cs | 68 ++++++++++--------- Composite/Data/PageMetaDataFacade.cs | 13 ++-- 5 files changed, 58 insertions(+), 52 deletions(-) diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/PageElementProvider/DeletePageWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/PageElementProvider/DeletePageWorkflow.cs index 35d894bd94..691b1d58b0 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/PageElementProvider/DeletePageWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/PageElementProvider/DeletePageWorkflow.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -65,14 +65,13 @@ private void HasDataReferences(object sender, ConditionalEventArgs e) var brokenReferences = new List(); foreach (var data in dataToDelete) { - var references = DataReferenceFacade.GetNotOptionalReferences(data); + var references = DataReferenceFacade.GetReferences(data, false, + (type, fp) => !fp.IsOptionalReference + && type != typeof(IPagePlaceholderContent) + && fp.SourcePropertyInfo.DeclaringType != typeof(IPageRelatedData)); + foreach (var reference in references) { - if (reference is IPagePlaceholderContent) - { - continue; - } - DataSourceId dataSourceId = reference.DataSourceId; if (dataToDelete.Any(elem => elem.DataSourceId.Equals(dataSourceId)) || brokenReferences.Any(brokenRef => brokenRef.DataSourceId.Equals(dataSourceId))) diff --git a/Composite/C1Console/Trees/TreeFacadeImpl.cs b/Composite/C1Console/Trees/TreeFacadeImpl.cs index 9d94b7e9e3..b18ab0334e 100644 --- a/Composite/C1Console/Trees/TreeFacadeImpl.cs +++ b/Composite/C1Console/Trees/TreeFacadeImpl.cs @@ -627,12 +627,12 @@ private static void OnDataItemDeleted(object sender, DataEventArgs dataEventArgs PropertyInfo propertyInfo = interfaceType.GetKeyProperties()[0]; string keyValue = ValueTypeConverter.Convert(propertyInfo.GetValue(dataEventArgs.Data, null)); - IEnumerable attachmentPoints = - from d in DataFacade.GetData() - where - d.InterfaceType == TypeManager.SerializeType(interfaceType) && - d.KeyValue == keyValue - select d; + var serializedInterfaceType = TypeManager.SerializeType(interfaceType); + + var attachmentPoints = + DataFacade.GetData() + .Where(ap => ap.KeyValue == keyValue + && ap.InterfaceType == serializedInterfaceType); DataFacade.Delete(attachmentPoints); } diff --git a/Composite/Core/Linq/Extensions.cs b/Composite/Core/Linq/Extensions.cs index fd3f3d2927..945b02d170 100644 --- a/Composite/Core/Linq/Extensions.cs +++ b/Composite/Core/Linq/Extensions.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -116,7 +116,7 @@ public static T SingleOrException(this IEnumerable query, string exception /// Exception format for multiple rows found /// Format arguments /// - [StringFormatMethod("formatArgs")] + [StringFormatMethod("exceptionOnMultipleResults")] public static T SingleOrDefaultOrException(this IEnumerable query, string exceptionOnMultipleResults, params object[] formatArgs) { var result = query.ToList(); diff --git a/Composite/Data/DataReferenceFacade.cs b/Composite/Data/DataReferenceFacade.cs index 8b0e019ec5..c607a9e523 100644 --- a/Composite/Data/DataReferenceFacade.cs +++ b/Composite/Data/DataReferenceFacade.cs @@ -41,9 +41,13 @@ public static List GetRefereeTypes(this Type referencedType) internal static bool TryValidateDeleteSuccess(this IData dataToDelete) { - var referees = GetNotOptionalRefereesRecursively(dataToDelete); + var foundDataset = new Dictionary>(); + + GetRefereesRecursively(dataToDelete, true, + (type, foreignKey) => !foreignKey.IsOptionalReference + && (!foreignKey.AllowCascadeDeletes || DataReferenceRegistry.GetRefereeTypes(type).Count > 0), foundDataset); - return referees.All(referee => referee.Item2.AllowCascadeDeletes); + return foundDataset.All(kvp => kvp.Value.Item2.AllowCascadeDeletes); } @@ -301,14 +305,23 @@ public static List GetNotOptionalReferences(T data) where T : IData /// public static List GetNotOptionalReferences(T data, bool allScopes) where T : IData { - return GetNotOptionalReferencesInt(data, allScopes).Select(t => t.Item1).ToList(); + return GetReferencesInt(data, allScopes, (type, fp) => !fp.IsOptionalReference) + .Select(t => t.Item1).ToList(); + } + + /// + internal static List GetReferences(IData data, bool allScopes, Func foreignKeyFilter) + { + return GetReferencesInt(data, allScopes, foreignKeyFilter) + .Select(t => t.Item1).ToList(); } /// - internal static IList> GetNotOptionalReferencesInt(T data, bool allScopes) where T : IData + internal static IList> GetReferencesInt( + IData data, bool allScopes, Func propertyFilter) { - Verify.ArgumentNotNull(data, "data"); + Verify.ArgumentNotNull(data, nameof(data)); var result = new List>(); @@ -317,10 +330,9 @@ internal static IList> GetNotOptionalReference foreach (var referencedType in referencedTypes) { - foreach (var foreignKeyProperty in GetForeignKeyProperties(referencedType, dataType)) { - if (foreignKeyProperty.IsOptionalReference) + if (!propertyFilter(referencedType, foreignKeyProperty)) { continue; } @@ -556,35 +568,23 @@ public static List GetReferees(this IData referencedData, bool allScopes) /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static List GetReferees(this IData referencedData, Type refereeType, IEnumerable foreignKeyPropertys, bool allScopes) + public static List GetReferees(this IData referencedData, Type refereeType, IEnumerable foreignKeyProperties, bool allScopes) { Verify.ArgumentNotNull(referencedData, "referencedData"); - return GetReferees(referencedData, false, refereeType, foreignKeyPropertys, allScopes); - } - - - - internal static IEnumerable> GetNotOptionalRefereesRecursively(this IData referencedData) - { - Verify.ArgumentNotNull(referencedData, "referencedData"); - - var foundDataset = new Dictionary>(); - - GetNotOptionalRefereesRecursively(referencedData, true, foundDataset); - - return foundDataset.Values; + return GetReferees(referencedData, false, refereeType, foreignKeyProperties, allScopes); } - internal static IEnumerable> GetNotOptionalRefereesRecursively(this IData referencedData, bool allScopes) + internal static IEnumerable> GetNotOptionalRefereesRecursively( + this IData referencedData, bool allScopes = true) { Verify.ArgumentNotNull(referencedData, "referencedData"); var foundDataset = new Dictionary>(); - GetNotOptionalRefereesRecursively(referencedData, allScopes, foundDataset); + GetRefereesRecursively(referencedData, allScopes, (t, f) => !f.IsOptionalReference, foundDataset); return foundDataset.Values; } @@ -624,12 +624,14 @@ public static IData GetReferenced(this IData refereeData, string foreignKeyPrope - private static void GetNotOptionalRefereesRecursively(IData referencedData, bool allScopes, Dictionary> foundDataset) + private static void GetRefereesRecursively(IData referencedData, bool allScopes, + Func foreignKeyPredicate, + Dictionary> foundDataset) { - Verify.ArgumentNotNull(referencedData, "foundDataset"); - Verify.ArgumentNotNull(foundDataset, "referencedData"); + Verify.ArgumentNotNull(referencedData, nameof(foundDataset)); + Verify.ArgumentNotNull(foundDataset, nameof(referencedData)); - IList> referees = GetNotOptionalReferencesInt(referencedData, allScopes); + IList> referees = GetReferencesInt(referencedData, allScopes, foreignKeyPredicate); foreach (var data in referees) { @@ -637,7 +639,7 @@ private static void GetNotOptionalRefereesRecursively(IData referencedData, bool { foundDataset.Add(data.Item1.DataSourceId, data); - GetNotOptionalRefereesRecursively(data.Item1, allScopes, foundDataset); + GetRefereesRecursively(data.Item1, allScopes, foreignKeyPredicate, foundDataset); } } } @@ -648,15 +650,15 @@ private static List GetReferees(IData referencedData, IQueryable dataset, { List result = new List(); - foreach (ForeignPropertyInfo foreignKeyProperyInfo in foreignKeyProperyInfos) + foreach (ForeignPropertyInfo foreignKeyPropertyInfo in foreignKeyProperyInfos) { - if (!referencedData.DataSourceId.InterfaceType.IsAssignableFrom(foreignKeyProperyInfo.TargetType)) + if (!referencedData.DataSourceId.InterfaceType.IsAssignableFrom(foreignKeyPropertyInfo.TargetType)) { continue; } - object sourceKeyValue = foreignKeyProperyInfo.TargetKeyPropertyInfo.GetValue(referencedData, null); + object sourceKeyValue = foreignKeyPropertyInfo.TargetKeyPropertyInfo.GetValue(referencedData, null); - result.AddRange(GetReferences(dataset, foreignKeyProperyInfo, sourceKeyValue, returnOnFirstFound).Cast()); + result.AddRange(GetReferences(dataset, foreignKeyPropertyInfo, sourceKeyValue, returnOnFirstFound).Cast()); if (returnOnFirstFound && result.Count > 0) { break; diff --git a/Composite/Data/PageMetaDataFacade.cs b/Composite/Data/PageMetaDataFacade.cs index a63dc6e733..b15e551e4d 100644 --- a/Composite/Data/PageMetaDataFacade.cs +++ b/Composite/Data/PageMetaDataFacade.cs @@ -379,12 +379,17 @@ public static IData GetMetaData(Guid pageId, Guid pageVersionId, string definiti parameterExpression ); - var whereExpression = ExpressionCreator.Where(DataFacade.GetData(metaDataType).Expression, lambdaExpression); + using (var conn = new DataConnection()) + { + conn.DisableServices(); - IEnumerable dataset = ExpressionHelper.GetCastedObjects(metaDataType, whereExpression); + var whereExpression = ExpressionCreator.Where(DataFacade.GetData(metaDataType).Expression, lambdaExpression); - return dataset.SingleOrDefaultOrException("There're multiple meta data on a page. Page '{0}', definition name '{1}', meta type '{2}'", - pageId, definitionName, metaDataType.FullName); + IEnumerable dataset = ExpressionHelper.GetCastedObjects(metaDataType, whereExpression); + + return dataset.SingleOrDefaultOrException("There're multiple meta data on a page. Page '{0}', definition name '{1}', meta type '{2}'", + pageId, definitionName, metaDataType.FullName); + } } From c47bed89ce419eb9e98cd5eeac265644eec2e6aa Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 17 Mar 2017 16:43:46 +0100 Subject: [PATCH 073/135] Optimizing data deletion code so the data references are not calculated twice, refactoring --- Composite/Data/DataFacadeImpl.cs | 55 +++++++------- Composite/Data/DataReferenceFacade.cs | 72 ++++--------------- .../Data/Foundation/DataReferenceRegistry.cs | 11 +-- 3 files changed, 51 insertions(+), 87 deletions(-) diff --git a/Composite/Data/DataFacadeImpl.cs b/Composite/Data/DataFacadeImpl.cs index 3b01ed5faf..3c09c4a88f 100644 --- a/Composite/Data/DataFacadeImpl.cs +++ b/Composite/Data/DataFacadeImpl.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -477,19 +477,17 @@ private void Delete(IEnumerable dataset, bool suppressEventing, CascadeDel if (cascadeDeleteType != CascadeDeleteType.Disable) { - foreach (IData element in dataset) + foreach (IData data in dataset) { - Verify.ArgumentCondition(element != null, nameof(dataset), "dataset may not contain nulls"); + Verify.ArgumentCondition(data != null, nameof(dataset), "dataset may not contain nulls"); - if (!element.IsDataReferred()) continue; - - Type interfaceType = element.DataSourceId.InterfaceType; + Type interfaceType = data.DataSourceId.InterfaceType; // Not deleting references if the data is versioned and not all of the // versions of the element are to be deleted - if (element is IVersioned) + if (data is IVersioned && interfaceType.GetKeyProperties().Count == 1) { - var key = element.GetUniqueKey(); + var key = data.GetUniqueKey(); var versions = DataFacade.TryGetDataVersionsByUniqueKey(interfaceType, key).ToList(); if (versions.Count > 1 @@ -500,29 +498,36 @@ private void Delete(IEnumerable dataset, bool suppressEventing, CascadeDel } } - Verify.IsTrue(cascadeDeleteType != CascadeDeleteType.Disallow, "One of the given datas is referenced by one or more datas"); + using (new DataScope(data.DataSourceId.DataScopeIdentifier)) + { + var allReferences = DataReferenceFacade.GetRefereesInt(data, referencesFromAllScopes, (a, b) => true); - element.RemoveOptionalReferences(); + if (allReferences.Count == 0) continue; - IEnumerable referees; - using (new DataScope(element.DataSourceId.DataScopeIdentifier)) - { - // For some weird reason, this line does not work.... /MRJ - // IEnumerable referees = dataset.GetRefereesRecursively(); - referees = element.GetReferees(referencesFromAllScopes) - .Where(reference => !dataPendingDeletion.Contains(reference.DataSourceId)) - .Evaluate(); - } + Verify.IsTrue(cascadeDeleteType != CascadeDeleteType.Disallow, "One of the given datas is referenced by one or more datas"); - foreach (IData referee in referees) - { - if (!referee.CascadeDeleteAllowed(interfaceType)) + var optionalReferences = allReferences.Where(kvp => kvp.Item2.IsOptionalReference); + var notOptionalReferences = allReferences.Where(kvp => !kvp.Item2.IsOptionalReference + && !dataPendingDeletion.Contains(kvp.Item1.DataSourceId)).Evaluate(); + + foreach (var reference in optionalReferences) { - throw new InvalidOperationException("One of the given datas is referenced by one or more datas that does not allow cascade delete"); + var referee = reference.Item1; + reference.Item2.SourcePropertyInfo.SetValue(referee, null, null); + DataFacade.Update(referee, false, true, false); + } + + foreach (var refereeInfo in notOptionalReferences) + { + if (!refereeInfo.Item2.AllowCascadeDeletes) + { + throw new InvalidOperationException("One of the given data items is referenced by one or more data items that do not allow cascade delete."); + } } - } - Delete(referees, suppressEventing, cascadeDeleteType, referencesFromAllScopes); + var toDelete = notOptionalReferences.Select(_ => _.Item1); + Delete(toDelete, suppressEventing, cascadeDeleteType, referencesFromAllScopes); + } } } diff --git a/Composite/Data/DataReferenceFacade.cs b/Composite/Data/DataReferenceFacade.cs index c607a9e523..2d5f63e335 100644 --- a/Composite/Data/DataReferenceFacade.cs +++ b/Composite/Data/DataReferenceFacade.cs @@ -34,7 +34,7 @@ public static List GetRefereeTypes(this Type referencedType) { Verify.ArgumentNotNull(referencedType, "referencedType"); - return DataReferenceRegistry.GetRefereeTypes(referencedType); + return DataReferenceRegistry.GetRefereeTypes(referencedType).ToList(); } @@ -305,20 +305,20 @@ public static List GetNotOptionalReferences(T data) where T : IData /// public static List GetNotOptionalReferences(T data, bool allScopes) where T : IData { - return GetReferencesInt(data, allScopes, (type, fp) => !fp.IsOptionalReference) + return GetRefereesInt(data, allScopes, (type, fp) => !fp.IsOptionalReference) .Select(t => t.Item1).ToList(); } /// internal static List GetReferences(IData data, bool allScopes, Func foreignKeyFilter) { - return GetReferencesInt(data, allScopes, foreignKeyFilter) + return GetRefereesInt(data, allScopes, foreignKeyFilter) .Select(t => t.Item1).ToList(); } /// - internal static IList> GetReferencesInt( + internal static IList> GetRefereesInt( IData data, bool allScopes, Func propertyFilter) { Verify.ArgumentNotNull(data, nameof(data)); @@ -350,40 +350,6 @@ internal static IList> GetReferencesInt( } - - internal static void RemoveOptionalReferences(this T data) where T : IData - { - Verify.ArgumentNotNull(data, "data"); - - // TODO: check logic for working with different data scopes - - //bool isLocalized = data is IVersionControlled; - Type dataType = data.DataSourceId.InterfaceType; - var referencedTypes = DataReferenceRegistry.GetRefereeTypes(dataType); - - foreach (var referencedType in referencedTypes) - { - - foreach (var foregnKeyProperty in GetForeignKeyProperties(referencedType, dataType)) - { - if(!foregnKeyProperty.IsOptionalReference) - { - continue; - } - - var references = GetReferees(data, referencedType, new[] { foregnKeyProperty.SourcePropertyInfo }, false).ToList(); - - foreach (var refenecedData in references) - { - foregnKeyProperty.SourcePropertyInfo.SetValue(refenecedData, null, null); - DataFacade.Update(refenecedData, false, true, false); - } - } - } - } - - - /// public static bool TryGetReferenceType(this PropertyInfo propertyInfo, out Type typeBeingReferenced) { @@ -477,12 +443,8 @@ internal static bool CascadeDeleteAllowed(this IData data) { Verify.ArgumentNotNull(data, "data"); - ForeignPropertyInfo foreignPropertyInfo = - (from pi in DataReferenceRegistry.GetForeignKeyProperties(data.DataSourceId.InterfaceType) - where pi.AllowCascadeDeletes == false - select pi).FirstOrDefault(); - - return foreignPropertyInfo == null; + return DataReferenceRegistry.GetForeignKeyProperties(data.DataSourceId.InterfaceType) + .All(_ => _.AllowCascadeDeletes); } @@ -492,12 +454,8 @@ internal static bool CascadeDeleteAllowed(this IData data, Type referencedType) Verify.ArgumentNotNull(data, "data"); Verify.ArgumentNotNull(referencedType, "referencedType"); - ForeignPropertyInfo foreignPropertyInfo = - (from pi in GetForeignKeyProperties(data.DataSourceId.InterfaceType, referencedType) - where pi.AllowCascadeDeletes == false - select pi).FirstOrDefault(); - - return foreignPropertyInfo == null; + return GetForeignKeyProperties(data.DataSourceId.InterfaceType, referencedType) + .All(_ => _.AllowCascadeDeletes); } @@ -631,7 +589,7 @@ private static void GetRefereesRecursively(IData referencedData, bool allScopes, Verify.ArgumentNotNull(referencedData, nameof(foundDataset)); Verify.ArgumentNotNull(foundDataset, nameof(referencedData)); - IList> referees = GetReferencesInt(referencedData, allScopes, foreignKeyPredicate); + IList> referees = GetRefereesInt(referencedData, allScopes, foreignKeyPredicate); foreach (var data in referees) { @@ -682,7 +640,7 @@ private static List GetReferees(IData referencedData, bool returnOnFirstF { if (!DataReferenceRegistry.GetRefereeTypes(referencedData.DataSourceId.InterfaceType).Contains(refereeType)) { - throw new ArgumentException(string.Format("The referencedData of type '{0}' is not referenced by the given refereeType '{1}'", referencedData.DataSourceId.InterfaceType, refereeType)); + throw new ArgumentException($"The referencedData of type '{referencedData.DataSourceId.InterfaceType}' is not referenced by the given refereeType '{refereeType}'"); } refereeTypes = new List { refereeType }; @@ -692,7 +650,7 @@ private static List GetReferees(IData referencedData, bool returnOnFirstF foreach (Type refType in refereeTypes) { - List foreignKeyProperties = DataReferenceRegistry.GetForeignKeyProperties(refType); + var foreignKeyProperties = DataReferenceRegistry.GetForeignKeyProperties(refType); if (propertiesToSearchBy != null) { @@ -711,9 +669,9 @@ from pi in propertiesToSearchBy { IQueryable dataset = DataFacade.GetData(refType); List refs = GetReferees(referencedData, dataset, foreignKeyProperties, returnOnFirstFound); - referees.AddRange(refs.KeyDistinct()); // KeyDistinct is used here if a type has more than one refernce to a nother time + referees.AddRange(refs.KeyDistinct()); // KeyDistinct is used here if a type has more than one reference to a nother time - if ((returnOnFirstFound) && (referees.Count > 0)) + if (returnOnFirstFound && referees.Count > 0) { return referees; } @@ -724,9 +682,9 @@ from pi in propertiesToSearchBy { IQueryable dataset = DataFacade.GetData(refType); List refs = GetReferees(referencedData, dataset, foreignKeyProperties, returnOnFirstFound); - referees.AddRange(refs.KeyDistinct()); // KeyDistinct is used here if a type has more than one refernce to a nother time + referees.AddRange(refs.KeyDistinct()); // KeyDistinct is used here if a type has more than one reference to a nother time - if ((returnOnFirstFound) && (referees.Count > 0)) + if (returnOnFirstFound && referees.Count > 0) { return referees; } diff --git a/Composite/Data/Foundation/DataReferenceRegistry.cs b/Composite/Data/Foundation/DataReferenceRegistry.cs index a4b2f65139..c9a6750a32 100644 --- a/Composite/Data/Foundation/DataReferenceRegistry.cs +++ b/Composite/Data/Foundation/DataReferenceRegistry.cs @@ -26,12 +26,13 @@ static DataReferenceRegistry() - public static List GetRefereeTypes(Type referencedType) + public static IReadOnlyCollection GetRefereeTypes(Type referencedType) { Verify.ArgumentNotNull(referencedType, "referencedType"); List refereeTypes = new List(); + // TODO: rewrite using concurrent dictionaries using (GlobalInitializerFacade.CoreIsInitializedScope) { foreach (var key in _referencedToReferees.Keys) @@ -49,10 +50,10 @@ public static List GetRefereeTypes(Type referencedType) [Obsolete("Use 'GetForeignKeyProperties' instead")] public static List GetForeignKeyPropertyInfos(Type refereeType) { - return GetForeignKeyProperties(refereeType); + return GetForeignKeyProperties(refereeType).ToList(); } - public static List GetForeignKeyProperties(Type refereeType) + public static IReadOnlyCollection GetForeignKeyProperties(Type refereeType) { Verify.ArgumentNotNull(refereeType, "refereeType"); @@ -62,11 +63,11 @@ public static List GetForeignKeyProperties(Type refereeType { if (!_foreignKeyProperties.TryGetValue(refereeType, out foreignKeyProperties)) { - return new List(); + return Array.Empty(); } } - return new List(foreignKeyProperties); + return foreignKeyProperties; } From cb04a4e8b7df952daea4749c3c98d74de3f6287a Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 17 Mar 2017 16:44:52 +0100 Subject: [PATCH 074/135] Optimizing page deletion performance --- Composite/Data/Types/PageServices.cs | 63 ++++++++++++++++------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/Composite/Data/Types/PageServices.cs b/Composite/Data/Types/PageServices.cs index 2f69f82a29..a2208a6e9f 100644 --- a/Composite/Data/Types/PageServices.cs +++ b/Composite/Data/Types/PageServices.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -383,21 +383,25 @@ public static IEnumerable GetSubChildren(this IPage parentPage) } } - - /// /// This method will delete the pagestructure corresponding to the given page if this /// page is the last page. /// /// The page that is about to be deleted. public static void DeletePageStructure(this IPage page) + { + DeletePageStructure(page, true); + } + + + internal static void DeletePageStructure(this IPage page, bool updateSiblingsOrder) { if (ExistsInOtherLocale(page)) { return; } - IPageStructure structureInfo = DataFacade.GetData(f => f.Id == page.Id).SingleOrDefault(); + var structureInfo = DataFacade.GetData(false).SingleOrDefault(f => f.Id == page.Id); if (structureInfo == null) { return; @@ -406,6 +410,8 @@ public static void DeletePageStructure(this IPage page) int localOrdering = structureInfo.LocalOrdering; DataFacade.Delete(structureInfo); + if (!updateSiblingsOrder) return; + List siblings = DataFacade.GetData( f => f.ParentId == structureInfo.ParentId && f.LocalOrdering >= localOrdering).ToList(); @@ -417,10 +423,10 @@ public static void DeletePageStructure(this IPage page) return; } - for (int i = 0; i < siblings.Count; i++) + foreach (IPageStructure sibling in siblings) { - siblings[i].LocalOrdering--; - DataFacade.Update(siblings[i]); + sibling.LocalOrdering--; + DataFacade.Update(sibling); } } @@ -502,34 +508,39 @@ public static void DeletePage(IPage page) { using (var transactionScope = TransactionsFacade.CreateNewScope()) { - List cultures = DataLocalizationFacade.ActiveLocalizationCultures.ToList(); - cultures.Remove(page.DataSourceId.LocaleScope); + using (var conn = new DataConnection()) + { + conn.DisableServices(); - List pagesToDelete = page.GetSubChildren().ToList(); + var cultures = DataLocalizationFacade.ActiveLocalizationCultures.ToList(); + cultures.Remove(page.DataSourceId.LocaleScope); - foreach (IPage childPage in pagesToDelete) - { - if (!ExistInOtherLocale(cultures, childPage)) + List pagesToDelete = page.GetSubChildren().ToList(); + + foreach (IPage childPage in pagesToDelete) { - RemoveAllFolderAndMetaDataDefinitions(childPage); + if (!ExistInOtherLocale(cultures, childPage)) + { + RemoveAllFolderAndMetaDataDefinitions(childPage); + } + + childPage.DeletePageStructure(false); + ProcessControllerFacade.FullDelete(childPage); } - childPage.DeletePageStructure(); - ProcessControllerFacade.FullDelete(childPage); - } - - if (!ExistInOtherLocale(cultures, page)) - { - RemoveAllFolderAndMetaDataDefinitions(page); - } + if (!ExistInOtherLocale(cultures, page)) + { + RemoveAllFolderAndMetaDataDefinitions(page); + } - page.DeletePageStructure(); + page.DeletePageStructure(); - Guid pageId = page.Id; - var pageVersions = DataFacade.GetData(p => p.Id == pageId).ToList(); + Guid pageId = page.Id; + var pageVersions = DataFacade.GetData(p => p.Id == pageId).ToList(); - ProcessControllerFacade.FullDelete(pageVersions); + ProcessControllerFacade.FullDelete(pageVersions); + } transactionScope.Complete(); } From 80e3d840698338696a8058706aa5ee2788dce1c7 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 20 Mar 2017 12:13:19 +0100 Subject: [PATCH 075/135] DataCachingFacade - refactoring, optimization - not clearing data/localization scopes that hasn't changed --- Composite/Data/Caching/DataCachingFacade.cs | 71 +++++++++++++-------- Composite/Data/DataFacadeImpl.cs | 30 ++++----- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/Composite/Data/Caching/DataCachingFacade.cs b/Composite/Data/Caching/DataCachingFacade.cs index 9d674311f8..96953f950e 100644 --- a/Composite/Data/Caching/DataCachingFacade.cs +++ b/Composite/Data/Caching/DataCachingFacade.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections; +ï»żusing System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; @@ -13,8 +12,8 @@ using Composite.Core.Configuration; using TypeData = System.Collections.Concurrent.ConcurrentDictionary< - Composite.Data.DataScopeIdentifier, - System.Collections.Concurrent.ConcurrentDictionary>; + System.Tuple, + Composite.Data.Caching.DataCachingFacade.CachedTable>; namespace Composite.Data.Caching { @@ -26,10 +25,10 @@ public static class DataCachingFacade private static readonly string CacheName = "DataAccess"; private static readonly ConcurrentDictionary _cachedData = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary _disabledTypes = new ConcurrentDictionary(); private static bool _isEnabled = true; private static int _maximumSize = -1; - private static Hashtable _disabledTypes = new Hashtable(); private static MethodInfo _queryableTakeMathodInfo; @@ -41,7 +40,7 @@ static DataCachingFacade() { if (!args.DataEventsFired) { - ClearCache(args.DataType, args.PublicationScope); + ClearCache(args.DataType, args.PublicationScope, args.Locale); } }; } @@ -114,16 +113,15 @@ internal static IQueryable GetDataFromCache(Func> getQueryFu { Verify.That(_isEnabled, "The cache is disabled."); - DataScopeIdentifier dataScopeIdentifier = DataScopeManager.MapByType(typeof(T)); - CultureInfo localizationScope = LocalizationScopeManager.MapByType(typeof(T)); + var dataScopeIdentifier = DataScopeManager.MapByType(typeof(T)); + var localizationScope = LocalizationScopeManager.MapByType(typeof(T)); var typeData = _cachedData.GetOrAdd(typeof(T), t => new TypeData()); - var dataScopeData = typeData.GetOrAdd(dataScopeIdentifier, scope => new ConcurrentDictionary()); - + var cacheKey = new Tuple(dataScopeIdentifier, localizationScope); CachedTable cachedTable; - if (!dataScopeData.TryGetValue(localizationScope, out cachedTable)) + if (!typeData.TryGetValue(cacheKey, out cachedTable)) { IQueryable wholeTable = getQueryFunc(); @@ -151,7 +149,7 @@ internal static IQueryable GetDataFromCache(Func> getQueryFu cachedTable = new CachedTable(wholeTable.Evaluate().AsQueryable()); } - dataScopeData[localizationScope] = cachedTable; + typeData[cacheKey] = cachedTable; } var typedData = cachedTable.Queryable as IQueryable; @@ -198,10 +196,21 @@ public static void ClearCache(Type interfaceType) /// The publication scope to flush public static void ClearCache(Type interfaceType, PublicationScope publicationScope) { - ClearCache(interfaceType,DataScopeIdentifier.FromPublicationScope(publicationScope)); + ClearCache(interfaceType, DataScopeIdentifier.FromPublicationScope(publicationScope)); } + /// + /// Flush cached data for a data type in the specified data scope. + /// + /// The type of data to flush from the cache + /// The publication scope to flush + /// The localization scope to flush + public static void ClearCache(Type interfaceType, PublicationScope publicationScope, CultureInfo localizationScope) + { + ClearCache(interfaceType, DataScopeIdentifier.FromPublicationScope(publicationScope), localizationScope); + } + /// /// Flush cached data for a data type in the specified data scope. /// @@ -212,16 +221,32 @@ public static void ClearCache(Type interfaceType, DataScopeIdentifier dataScopeI TypeData typeData; if(!_cachedData.TryGetValue(interfaceType, out typeData)) return; - if (dataScopeIdentifier == null) + dataScopeIdentifier = dataScopeIdentifier ?? DataScopeManager.MapByType(interfaceType); + + var toRemove = typeData.Keys.Where(key => key.Item1 == dataScopeIdentifier).ToList(); + + foreach (var key in toRemove) { - dataScopeIdentifier = DataScopeManager.MapByType(interfaceType); + CachedTable value; + typeData.TryRemove(key, out value); } - - ConcurrentDictionary data; - typeData.TryRemove(dataScopeIdentifier, out data); } + internal static void ClearCache(Type interfaceType, DataScopeIdentifier dataScopeIdentifier, CultureInfo localizationScope) + { + TypeData typeData; + if (!_cachedData.TryGetValue(interfaceType, out typeData)) return; + + dataScopeIdentifier = dataScopeIdentifier ?? DataScopeManager.MapByType(interfaceType); + localizationScope = localizationScope ?? LocalizationScopeManager.MapByType(interfaceType); + + var key = new Tuple(dataScopeIdentifier, localizationScope); + + CachedTable value; + typeData.TryRemove(key, out value); + } + /// /// This method is also called by the DataFacade @@ -229,7 +254,7 @@ public static void ClearCache(Type interfaceType, DataScopeIdentifier dataScopeI internal static void Flush() { _cachedData.Clear(); - _disabledTypes = new Hashtable(); + _disabledTypes.Clear(); } @@ -272,13 +297,7 @@ private static void OnFlushEvent(FlushEventArgs args) private static void DisableCachingForType(Type type) { - lock (_disabledTypes) - { - if (!_disabledTypes.ContainsKey(type)) - { - _disabledTypes.Add(type, string.Empty); - } - } + _disabledTypes.TryAdd(type, 0); TypeData data; _cachedData.TryRemove(type, out data); diff --git a/Composite/Data/DataFacadeImpl.cs b/Composite/Data/DataFacadeImpl.cs index 3c09c4a88f..bde52d8286 100644 --- a/Composite/Data/DataFacadeImpl.cs +++ b/Composite/Data/DataFacadeImpl.cs @@ -353,7 +353,7 @@ public List AddNew(IEnumerable datas, bool allowStoreCreation, bool sup { if (!DataTypeTypesManager.IsAllowedDataTypeAssembly(typeof(T))) { - string message = string.Format("The data interface '{0}' is not located in an assembly in the website Bin folder. Please move it to that location", typeof(T)); + string message = $"The data interface '{typeof(T)}' is not located in an assembly in the website Bin folder. Please move it to that location"; Log.LogError(LogTitle, message); throw new InvalidOperationException(message); } @@ -364,13 +364,11 @@ public List AddNew(IEnumerable datas, bool allowStoreCreation, bool sup if (writeableProviders.Count == 0) { - Log.LogVerbose(LogTitle, string.Format("Type data interface '{0}' is marked auto updateble and is not supported by any providers. Adding it to the default dynamic type data provider", typeof(T))); + Log.LogVerbose(LogTitle, $"Type data interface '{typeof(T)}' is marked auto updateble and is not supported by any providers. Adding it to the default dynamic type data provider"); - List result; DynamicTypeManager.EnsureCreateStore(typeof(T)); - result = AddNew(datas, false, suppressEventing, performForeignKeyIntegrityCheck, performValidation, null); - return result; + return AddNew(datas, false, suppressEventing, performForeignKeyIntegrityCheck, performValidation, null); } } } @@ -380,7 +378,7 @@ public List AddNew(IEnumerable datas, bool allowStoreCreation, bool sup return AddNew_AddingMethod(writeableProviders[0], datas, suppressEventing, performForeignKeyIntegrityCheck, performValidation); } - throw new InvalidOperationException(string.Format("{0} writeable data providers exists for data '{1}'.", writeableProviders.Count, typeof(T))); + throw new InvalidOperationException($"{writeableProviders.Count} writeable data providers exists for data '{typeof(T)}'."); } @@ -395,17 +393,17 @@ private static List AddNew_AddingMethod(string providerName, IEnumerable writeableProviders = DataProviderRegistry.GetWriteableDataProviderNamesByInterfaceType(typeof(T)); - if (writeableProviders.Contains(providerName) == false) + if (!writeableProviders.Contains(providerName)) { - Log.LogVerbose(LogTitle, string.Format("Type data interface '{0}' is marked auto updateble and is not supported by the provider '{1}', adding it", typeof(T), providerName)); + Log.LogVerbose(LogTitle, $"Type data interface '{typeof(T)}' is marked auto updateable and is not supported by the provider '{providerName}', adding it"); DynamicTypeManager.EnsureCreateStore(typeof(T), providerName); } writeableProviders = DataProviderRegistry.GetWriteableDataProviderNamesByInterfaceType(typeof(T)); - if (writeableProviders.Contains(providerName) == false) + if (!writeableProviders.Contains(providerName)) { - throw new InvalidOperationException(string.Format("The writeable data providers '{0}' does not support the interface '{1}'.", providerName, typeof(T))); + throw new InvalidOperationException($"The writeable data providers '{providerName}' does not support the interface '{typeof(T)}'."); } @@ -423,7 +421,7 @@ private static List AddNew_AddingMethod(string providerName, IEnumerable AddNew_AddingMethod(string providerName, IEnumerable addedDataset = DataProviderPluginFacade.AddNew(providerName, dataset); - if (DataCachingFacade.IsTypeCacheable(typeof(T))) - { - DataCachingFacade.ClearCache(typeof(T)); - } + DataCachingFacade.ClearCache(typeof(T), DataScopeManager.MapByType(typeof(T)), LocalizationScopeManager.MapByType(typeof(T))); - if (suppressEventing == false) + if (!suppressEventing) { foreach (T data in addedDataset) { @@ -542,7 +537,8 @@ private void Delete(IEnumerable dataset, bool suppressEventing, CascadeDel if (DataCachingFacade.IsTypeCacheable(interfaceTypePair.Key)) { - DataCachingFacade.ClearCache(interfaceTypePair.Key, interfaceTypePair.Value.First().DataSourceId.DataScopeIdentifier); + var dataSourceId = interfaceTypePair.Value.First().DataSourceId; + DataCachingFacade.ClearCache(interfaceTypePair.Key, dataSourceId.DataScopeIdentifier, dataSourceId.LocaleScope); } } } From 11c431f413317303d664ad3ab98ffa82e01bf3cc Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 20 Mar 2017 14:28:43 +0100 Subject: [PATCH 076/135] DataSourceId refactoring --- Composite/Data/DataScopeIdentifier.cs | 8 +- Composite/Data/DataSourceId.cs | 111 +++++--------------------- 2 files changed, 26 insertions(+), 93 deletions(-) diff --git a/Composite/Data/DataScopeIdentifier.cs b/Composite/Data/DataScopeIdentifier.cs index 607fa0fbd5..bf98c42043 100644 --- a/Composite/Data/DataScopeIdentifier.cs +++ b/Composite/Data/DataScopeIdentifier.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Diagnostics; @@ -58,10 +58,10 @@ public static DataScopeIdentifier Deserialize(string serializedData) switch (serializedData) { - case "public": + case PublicName: return DataScopeIdentifier.Public; - case "administrated": + case AdministratedName: return DataScopeIdentifier.Administrated; default: @@ -73,7 +73,7 @@ public static DataScopeIdentifier Deserialize(string serializedData) /// public PublicationScope ToPublicationScope() { - return Name == "public" ? PublicationScope.Published : PublicationScope.Unpublished; + return Name == PublicName ? PublicationScope.Published : PublicationScope.Unpublished; } diff --git a/Composite/Data/DataSourceId.cs b/Composite/Data/DataSourceId.cs index 18d13077c8..56087da730 100644 --- a/Composite/Data/DataSourceId.cs +++ b/Composite/Data/DataSourceId.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Globalization; using Composite.Core.Serialization; @@ -14,9 +14,6 @@ namespace Composite.Data /// public sealed class DataSourceId { - private IDataId _dataId; - private string _providerName; - private Type _interfaceType; private DataScopeIdentifier _dataScopeIdentifier; private CultureInfo _localeScope; private string _serializedData; @@ -33,8 +30,8 @@ public DataSourceId(IDataId dataId, string providerName, Type interfaceType) this.DataId = dataId; - _providerName = providerName; - _interfaceType = interfaceType; + ProviderName = providerName; + InterfaceType = interfaceType; _dataScopeIdentifier = DataScopeManager.MapByType(interfaceType); _localeScope = LocalizationScopeManager.MapByType(interfaceType); this.ExistsInStore = true; @@ -55,8 +52,8 @@ public DataSourceId(IDataId dataId, string providerName, Type interfaceType, Dat if (localeScope == null) throw new ArgumentNullException("localeScope"); this.DataId = dataId; - _providerName = providerName; - _interfaceType = interfaceType; + ProviderName = providerName; + InterfaceType = interfaceType; _dataScopeIdentifier = dataScope; _localeScope = localeScope; this.ExistsInStore = true; @@ -78,42 +75,19 @@ internal DataSourceId(Type interfaceType) /// /// Object which the data provider can use to uniquely identify the 'table record' in its own store matching a data element. /// - public IDataId DataId - { - get - { - _dataId = EnsureDataIdType(_dataId); - - return _dataId; - } - internal set - { - _dataId = value; - } - } - + public IDataId DataId { get; } /// /// Name of the data provider responsible for the data element. /// - public string ProviderName - { - get { return _providerName; } - internal set { _providerName = value; } - } - + public string ProviderName { get; } /// - /// The interface used for the data element. This is expected to be inpmelenting IData. + /// The interface used for the data element. This is expected to be implementing IData. /// - public Type InterfaceType - { - get { return _interfaceType; } - internal set { _interfaceType = value; } - } - + public Type InterfaceType { get; } /// @@ -130,11 +104,7 @@ public DataScopeIdentifier DataScopeIdentifier /// /// The publication scope (published or unpublished) from which the data element originate. /// - public PublicationScope PublicationScope - { - get { return _dataScopeIdentifier.Name == DataScopeIdentifier.PublicName ? Data.PublicationScope.Published : Data.PublicationScope.Unpublished; } - } - + public PublicationScope PublicationScope => _dataScopeIdentifier.ToPublicationScope(); /// @@ -154,7 +124,6 @@ public CultureInfo LocaleScope public bool ExistsInStore { get; - internal set; } @@ -165,9 +134,7 @@ public bool ExistsInStore /// Serialized as string public string Serialize() { - IDataId dataId = EnsureDataIdType(_dataId); - - if (_serializedData == null || dataId != _dataId) + if (_serializedData == null) { string s = SerializationFacade.Serialize(this.DataId); @@ -175,12 +142,12 @@ public string Serialize() StringConversionServices.SerializeKeyValuePair(sb, "_dataId_", s); StringConversionServices.SerializeKeyValuePair(sb, "_dataIdType_", TypeManager.SerializeType(this.DataId.GetType())); - if (_providerName != DataProviderRegistry.DefaultDynamicTypeDataProviderName) + if (ProviderName != DataProviderRegistry.DefaultDynamicTypeDataProviderName) { - StringConversionServices.SerializeKeyValuePair(sb, "_providerName_", _providerName); + StringConversionServices.SerializeKeyValuePair(sb, "_providerName_", ProviderName); } - StringConversionServices.SerializeKeyValuePair(sb, "_interfaceType_", TypeManager.SerializeType(_interfaceType)); + StringConversionServices.SerializeKeyValuePair(sb, "_interfaceType_", TypeManager.SerializeType(InterfaceType)); StringConversionServices.SerializeKeyValuePair(sb, "_dataScope_", DataScopeIdentifier.Serialize()); StringConversionServices.SerializeKeyValuePair(sb, "_localeScope_", LocaleScope.Name); @@ -243,15 +210,9 @@ private static bool Deserialize(string serializedDataSourceId, out DataSourceId string serializedDataId = StringConversionServices.DeserializeValueString(dic["_dataId_"]); string dataIdTypeName = StringConversionServices.DeserializeValueString(dic["_dataIdType_"]); - string providerName; - if (dic.ContainsKey("_providerName_")) - { - providerName = StringConversionServices.DeserializeValueString(dic["_providerName_"]); - } - else - { - providerName = DataProviderRegistry.DefaultDynamicTypeDataProviderName; - } + string providerName = dic.ContainsKey("_providerName_") + ? StringConversionServices.DeserializeValueString(dic["_providerName_"]) + : DataProviderRegistry.DefaultDynamicTypeDataProviderName; string interfaceTypeName = StringConversionServices.DeserializeValueString(dic["_interfaceType_"]); string dataScope = StringConversionServices.DeserializeValueString(dic["_dataScope_"]); @@ -300,11 +261,7 @@ private static string FixSerializedDataId(string serializedDataId, Type interfac /// - public override string ToString() - { - return Serialize(); - } - + public override string ToString() => Serialize(); /// @@ -322,33 +279,20 @@ public override bool Equals(object obj) /// public bool Equals(DataSourceId dataSourceId) { - if (dataSourceId == null) return false; - - return dataSourceId.ToString() == ToString(); + return dataSourceId != null && dataSourceId.ToString() == ToString(); } /// - public override int GetHashCode() - { - return ToString().GetHashCode(); - } - + public override int GetHashCode() => ToString().GetHashCode(); internal void SetTag(string id, object value) { InitializeTagInformation(); - if (_tagInformation.ContainsKey(id)) - { - _tagInformation[id] = value; - } - else - { - _tagInformation.Add(id, value); - } + _tagInformation[id] = value; } @@ -359,10 +303,7 @@ internal void RemoveTag(string id) InitializeTagInformation(); - if (_tagInformation.ContainsKey(id)) - { - _tagInformation.Remove(id); - } + _tagInformation.Remove(id); } @@ -389,13 +330,5 @@ private void InitializeTagInformation() _tagInformation = new Dictionary(); } } - - - - private static IDataId EnsureDataIdType(IDataId dataId) - { - // After the new build manager this should always be the right type - return dataId; - } } } From 26fb4f887288440db9277fb245e21a0339a8c841 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 20 Mar 2017 16:24:01 +0100 Subject: [PATCH 077/135] Optimizing sql data provider caching - not re-reading the whole table to populate the cache when records are deleted --- Composite/Composite.csproj | 1 + Composite/Data/Caching/CachedTable.cs | 71 +++++++++++++++++ Composite/Data/Caching/CachingQueryable.cs | 43 ++-------- Composite/Data/Caching/DataCachingFacade.cs | 79 +++++++++++-------- Composite/Data/DataFacadeImpl.cs | 3 +- .../XmlDataProvider/Foundation/FileRecord.cs | 2 +- .../XmlDataProvider/XmlDataProvider_CRUD.cs | 4 +- 7 files changed, 128 insertions(+), 75 deletions(-) create mode 100644 Composite/Data/Caching/CachedTable.cs diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 5e3a836734..6fdbd7caca 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -253,6 +253,7 @@ + diff --git a/Composite/Data/Caching/CachedTable.cs b/Composite/Data/Caching/CachedTable.cs new file mode 100644 index 0000000000..72929cb189 --- /dev/null +++ b/Composite/Data/Caching/CachedTable.cs @@ -0,0 +1,71 @@ +ï»żusing System.Collections.Generic; +using System.Linq; + +namespace Composite.Data.Caching +{ + /// + /// Cached table + /// + internal abstract class CachedTable + { + /// + /// The queryable data + /// + public abstract IQueryable Queryable { get; } + + internal abstract void Remove(IEnumerable dataset); + + /// + /// Row by key table + /// + public abstract IReadOnlyDictionary> RowsByKey { get; } + } + + internal class CachedTable : CachedTable + { + private IReadOnlyCollection _items; + private IReadOnlyDictionary> _rowsByKey; + + public CachedTable(IReadOnlyCollection items) + { + _items = items; + } + + public override IQueryable Queryable => _items.AsQueryable(); + + internal override void Remove(IEnumerable dataset) + { + var toRemove = new HashSet(dataset.Select(_ => _.DataSourceId)); + + lock (this) + { + var existingRows = _items; + _items = existingRows.Where(data => !toRemove.Contains((data as IData).DataSourceId)).ToList(); + _rowsByKey = null; // Can be optimized as well + } + } + + public override IReadOnlyDictionary> RowsByKey + { + get + { + var result = _rowsByKey; + if (result != null) return result; + + lock (this) + { + result = _rowsByKey; + if (result != null) return result; + + var keyPropertyInfo = typeof(T).GetKeyProperties().Single(); + + result = _items + .GroupBy(data => keyPropertyInfo.GetValue(data, null)) + .ToDictionary(group => group.Key, group => group.ToArray() as IEnumerable); + + return _rowsByKey = result; + } + } + } + } +} diff --git a/Composite/Data/Caching/CachingQueryable.cs b/Composite/Data/Caching/CachingQueryable.cs index 8f94fba8c6..d9cf6cc4a7 100644 --- a/Composite/Data/Caching/CachingQueryable.cs +++ b/Composite/Data/Caching/CachingQueryable.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -57,7 +57,7 @@ internal sealed class CachingQueryable : ICachedQuery, IOrderedQueryable, private readonly CachingEnumerable _wrappedEnumerable; private readonly Func _getQueryFunc; - private volatile DataCachingFacade.CachedTable _cachedTable; + private volatile CachedTable _cachedTable; private static readonly MethodInfo _wrappingMethodInfo; private static readonly MethodInfo _listWrappingMethodInfo; @@ -82,7 +82,7 @@ private static IEnumerable WrapData(IEnumerable input) wher return input.Select(DataWrappingFacade.Wrap); } - public CachingQueryable(DataCachingFacade.CachedTable cachedTable, Func originalQueryGetter) + public CachingQueryable(CachedTable cachedTable, Func originalQueryGetter) { _cachedTable = cachedTable; @@ -234,7 +234,7 @@ public IEnumerable GetCachedVersionValuesByKey(object key) private IEnumerable GetFromCacheFiltered(object key) { - var cachedTable = GetRowsByKeyTable(); + var cachedTable = GetCachedTable().RowsByKey; IEnumerable cachedRows; if (!cachedTable.TryGetValue(key, out cachedRows)) @@ -257,45 +257,14 @@ private IEnumerable GetFromCacheFiltered(object key) } - Dictionary> GetRowsByKeyTable() - { - var cachedTable = GetCachedTable(); - - var result = cachedTable.RowsByKey; - if (result != null) - { - return result; - } - - lock (cachedTable) - { - result = cachedTable.RowsByKey; - if (result != null) - { - return result; - } - PropertyInfo keyPropertyInfo = typeof(T).GetKeyProperties().Single(); - - result = BuildEnumerable() - .GroupBy(data => keyPropertyInfo.GetValue(data, null)) - .ToDictionary(group => group.Key, group => group.ToArray() as IEnumerable); - - return cachedTable.RowsByKey = result; - } - } - - - private DataCachingFacade.CachedTable GetCachedTable() + private CachedTable GetCachedTable() { if (_cachedTable == null) { lock (this) { - if (_cachedTable == null) - { - _cachedTable = new DataCachingFacade.CachedTable(GetOriginalQuery()); - } + _cachedTable = _cachedTable ?? new CachedTable(GetOriginalQuery().Cast().ToList()); } } diff --git a/Composite/Data/Caching/DataCachingFacade.cs b/Composite/Data/Caching/DataCachingFacade.cs index 96953f950e..550fc63034 100644 --- a/Composite/Data/Caching/DataCachingFacade.cs +++ b/Composite/Data/Caching/DataCachingFacade.cs @@ -4,16 +4,17 @@ using System.Globalization; using System.Linq; using System.Reflection; -using Composite.Core.Linq; using Composite.Data.DynamicTypes; using Composite.Data.Foundation; using Composite.Data.Foundation.PluginFacades; using Composite.C1Console.Events; using Composite.Core.Configuration; +using ScopeKey = System.Tuple; + using TypeData = System.Collections.Concurrent.ConcurrentDictionary< System.Tuple, - Composite.Data.Caching.DataCachingFacade.CachedTable>; + Composite.Data.Caching.CachedTable>; namespace Composite.Data.Caching { @@ -46,30 +47,6 @@ static DataCachingFacade() } - /// - /// Cached table - /// - public class CachedTable - { - /// - /// Initializes a new instance of the class. - /// - /// The queryable. - public CachedTable(IQueryable queryable) - { - Queryable = queryable; - } - - /// - /// The queryable data - /// - public IQueryable Queryable; - - /// - /// Row by key table - /// - public Dictionary> RowsByKey; - } /// /// Gets a value indicating if data caching is enabled @@ -134,19 +111,18 @@ internal static IQueryable GetDataFromCache(Func> getQueryFu if(_maximumSize != -1) { - List cuttedTable = TakeElements(wholeTable, _maximumSize + 1); + List cuttedTable = TakeElements(wholeTable, _maximumSize + 1).Cast().ToList(); if(cuttedTable.Count > _maximumSize) { DisableCachingForType(typeof (T)); return Verify.ResultNotNull(wholeTable); } - cachedTable = new CachedTable(cuttedTable.Cast().AsQueryable()); - + cachedTable = new CachedTable(cuttedTable); } else { - cachedTable = new CachedTable(wholeTable.Evaluate().AsQueryable()); + cachedTable = new CachedTable(wholeTable.ToList()); } typeData[cacheKey] = cachedTable; @@ -233,6 +209,45 @@ public static void ClearCache(Type interfaceType, DataScopeIdentifier dataScopeI } + /// + /// Removes the specified data collection from the cache. + /// The items should belong to the same interface type and the same data scope. + /// + /// + internal static void RemoveFromCache(IReadOnlyCollection dataset) + { + if (dataset.Count == 0) return; + + var groupedData = from data in dataset + let ds = data.DataSourceId + group data by new + { + ds.InterfaceType, + ds.DataScopeIdentifier, + ds.LocaleScope + }; + + foreach (var group in groupedData) + { + TypeData typeData; + if (!_cachedData.TryGetValue(group.Key.InterfaceType, out typeData)) + { + continue; + } + + var scopeKey = new ScopeKey(group.Key.DataScopeIdentifier, group.Key.LocaleScope); + CachedTable cachedTable; + if (!typeData.TryGetValue(scopeKey, out cachedTable)) + { + continue; + } + + cachedTable.Remove(group); + } + + // TODO: clear cache on transaction rollback? + } + internal static void ClearCache(Type interfaceType, DataScopeIdentifier dataScopeIdentifier, CultureInfo localizationScope) { TypeData typeData; @@ -268,13 +283,13 @@ private static void ReadSettings() - private static List TakeElements(IQueryable queryable, int count) + private static IQueryable TakeElements(IQueryable queryable, int count) { MethodInfo method = GetQueryableTakeMethodInfo(queryable.ElementType); var resultTable = (IQueryable) method.Invoke(null, new object[] {queryable, count}); - return resultTable.ToDataList(); + return resultTable; } private static MethodInfo GetQueryableTakeMethodInfo(Type type) diff --git a/Composite/Data/DataFacadeImpl.cs b/Composite/Data/DataFacadeImpl.cs index bde52d8286..c4f31aa1e0 100644 --- a/Composite/Data/DataFacadeImpl.cs +++ b/Composite/Data/DataFacadeImpl.cs @@ -537,8 +537,7 @@ private void Delete(IEnumerable dataset, bool suppressEventing, CascadeDel if (DataCachingFacade.IsTypeCacheable(interfaceTypePair.Key)) { - var dataSourceId = interfaceTypePair.Value.First().DataSourceId; - DataCachingFacade.ClearCache(interfaceTypePair.Key, dataSourceId.DataScopeIdentifier, dataSourceId.LocaleScope); + DataCachingFacade.RemoveFromCache(interfaceTypePair.Value); } } } diff --git a/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/FileRecord.cs b/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/FileRecord.cs index 65fd5e19ac..4266a0836b 100644 --- a/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/FileRecord.cs +++ b/Composite/Plugins/Data/DataProviders/XmlDataProvider/Foundation/FileRecord.cs @@ -25,7 +25,7 @@ internal FileRecord() public ICollection ReadOnlyElementsList; public DateTime LastModified; public DateTime FileModificationDate; - public DataCachingFacade.CachedTable CachedTable; + public CachedTable CachedTable; public bool Dirty = false; // Determines whether the inner XElement list is dirty diff --git a/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs b/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs index cccb685cfa..89d9b382f9 100644 --- a/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs +++ b/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs @@ -44,9 +44,7 @@ public IQueryable GetData() var list = new List(elements.Count); list.AddRange(elements.Select(fun)); - var queryable = list.AsQueryable(); - - fileRecord.CachedTable = new DataCachingFacade.CachedTable(queryable); + fileRecord.CachedTable = new CachedTable(list); } return new CachingQueryable(fileRecord.CachedTable, () => fileRecord.CachedTable.Queryable); From a866e9d846a7d31912066af65634790040807114 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Tue, 21 Mar 2017 11:53:58 +0100 Subject: [PATCH 078/135] fix copy config files in nightwatch --- Website/test/e2e/reset.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Website/test/e2e/reset.js b/Website/test/e2e/reset.js index 2cf725eb98..0b0f1a9a2c 100644 --- a/Website/test/e2e/reset.js +++ b/Website/test/e2e/reset.js @@ -147,16 +147,18 @@ var basepath = globals.siteLocation || process.cwd()+'/Website'; var sourcepath = process.cwd()+'/Website'; function copyFile(source, target) { + var id = Math.ceil(10000 * Math.random()); + var tmpFileLoc = basepath + '/tmp' + id; return new Promise(function(resolve, reject) { var reader = fs.createReadStream(source); reader.on('error', reject); - var id = Math.ceil(10000 * Math.random()); - var writer = fs.createWriteStream('tmp' + id); + + var writer = fs.createWriteStream(tmpFileLoc); writer.on('error', reject); writer.on('finish', function () { resolve(id); }); reader.pipe(writer); }).then(function (id) { - fs.renameSync('tmp' + id, target); + fs.renameSync(tmpFileLoc, target); }); } function delay() { From 4e01f2da092d1e42d68899379e737e32d57d04c3 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Tue, 21 Mar 2017 17:11:43 +0100 Subject: [PATCH 079/135] move roslyn inmemory compiler code to separate nuget --- .../AspNet/Roslyn/AssemblyMetadataCache.cs | 90 ---- Composite/AspNet/Roslyn/CSharpCodeProvider.cs | 25 - .../Roslyn/CSharpCompilationArguments.cs | 175 ------- Composite/AspNet/Roslyn/CSharpCompiler.cs | 94 ---- .../Roslyn/CommonCompilationArguments.cs | 123 ----- Composite/AspNet/Roslyn/CommonCompiler.cs | 486 ------------------ Composite/AspNet/Roslyn/CompilationUtil.cs | 68 --- Composite/AspNet/Roslyn/Res.Designer.cs | 135 ----- Composite/AspNet/Roslyn/Res.resx | 144 ------ Composite/Composite.csproj | 20 - Composite/packages.config | 4 - Website/DebugBuild.Web.config | 5 +- Website/ReleaseBuild.Web.config | 5 +- Website/WebSite.csproj | 18 + Website/packages.config | 6 + 15 files changed, 26 insertions(+), 1372 deletions(-) delete mode 100644 Composite/AspNet/Roslyn/AssemblyMetadataCache.cs delete mode 100644 Composite/AspNet/Roslyn/CSharpCodeProvider.cs delete mode 100644 Composite/AspNet/Roslyn/CSharpCompilationArguments.cs delete mode 100644 Composite/AspNet/Roslyn/CSharpCompiler.cs delete mode 100644 Composite/AspNet/Roslyn/CommonCompilationArguments.cs delete mode 100644 Composite/AspNet/Roslyn/CommonCompiler.cs delete mode 100644 Composite/AspNet/Roslyn/CompilationUtil.cs delete mode 100644 Composite/AspNet/Roslyn/Res.Designer.cs delete mode 100644 Composite/AspNet/Roslyn/Res.resx diff --git a/Composite/AspNet/Roslyn/AssemblyMetadataCache.cs b/Composite/AspNet/Roslyn/AssemblyMetadataCache.cs deleted file mode 100644 index ea53fc1d94..0000000000 --- a/Composite/AspNet/Roslyn/AssemblyMetadataCache.cs +++ /dev/null @@ -1,90 +0,0 @@ -ï»żusing Microsoft.CodeAnalysis; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; - -namespace Composite.AspNet.Roslyn -{ - internal class AssemblyMetadataCache - { - private const long MaxInactiveTicksAllowed = 1200000000L; - - private const long MillisecondsInOneMinutes = 60000L; - - private static AssemblyMetadataCache instance = new AssemblyMetadataCache(); - - private ConcurrentDictionary dictionary; - - private DateTime lastActiveTime; - - private volatile Timer timer; - - private object lockObject; - - private AssemblyMetadataCache() - { - this.dictionary = new ConcurrentDictionary(); - this.lockObject = new object(); - this.Activate(); - } - - public static AssemblyMetadataCache GetInstance() - { - return AssemblyMetadataCache.instance; - } - - public AssemblyMetadata GetOrAdd(string key, Func func) - { - this.Activate(); - this.StartTimer(); - return this.dictionary.GetOrAdd(key, func); - } - - private void Activate() - { - this.lastActiveTime = DateTime.Now; - } - - private void StartTimer() - { - if (this.timer == null) - { - lock (this.lockObject) - { - if (this.timer == null) - { - this.timer = new Timer(new TimerCallback(this.ClearIfInactive), null, MillisecondsInOneMinutes, MillisecondsInOneMinutes); - } - } - } - } - - private bool IsActive() - { - return DateTime.Now.Ticks - this.lastActiveTime.Ticks > MaxInactiveTicksAllowed; - } - - private void ClearIfInactive(object state) - { - if (!this.IsActive()) - { - Timer timer = this.timer; - if (Interlocked.CompareExchange(ref this.timer, null, timer) == timer && timer != null) - { - timer.Dispose(); - } - ICollection keys = this.dictionary.Keys; - foreach (string current in keys) - { - AssemblyMetadata assemblyMetadata; - this.dictionary.TryRemove(current, out assemblyMetadata); - if (assemblyMetadata != null) - { - assemblyMetadata.Dispose(); - } - } - } - } - } -} diff --git a/Composite/AspNet/Roslyn/CSharpCodeProvider.cs b/Composite/AspNet/Roslyn/CSharpCodeProvider.cs deleted file mode 100644 index 9f24b378cc..0000000000 --- a/Composite/AspNet/Roslyn/CSharpCodeProvider.cs +++ /dev/null @@ -1,25 +0,0 @@ -ï»żusing System; -using System.CodeDom.Compiler; - -namespace Composite.AspNet.Roslyn -{ - /// - public sealed class CSharpCodeProvider : Microsoft.CSharp.CSharpCodeProvider - { - - //public CSharpCodeProvider() : this(null) - //{ - //} - - //internal CSharpCodeProvider(ICompilerSettings compilerSettings = null) - //{ - //} - - /// - [Obsolete("Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.")] - public override ICodeCompiler CreateCompiler() - { - return new CSharpCompiler(this); - } - } -} diff --git a/Composite/AspNet/Roslyn/CSharpCompilationArguments.cs b/Composite/AspNet/Roslyn/CSharpCompilationArguments.cs deleted file mode 100644 index eb6b127c97..0000000000 --- a/Composite/AspNet/Roslyn/CSharpCompilationArguments.cs +++ /dev/null @@ -1,175 +0,0 @@ -ï»żusing Microsoft.CodeAnalysis.CSharp; -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; - -namespace Composite.AspNet.Roslyn -{ - internal class CSharpCompilationArguments : CommonCompilationArguments - { - internal CSharpCompilationArguments(CompilerParameters parameters, TextWriter outputWriter) : this(CSharpCompilationArguments.CorrectedParamaters(parameters), true, outputWriter) - { - } - - private CSharpCompilationArguments(CompilerParameters parameters, bool corrected, TextWriter outputWriter) : base(parameters, CSharpCompilationArguments.BuildCommandLineArguments(parameters, outputWriter)) - { - } - - private static CompilerParameters CorrectedParamaters(CompilerParameters parameters) - { - if (parameters.OutputAssembly == null) - { - string fileName = Path.GetFileName(parameters.TempFiles.BasePath); - string str = parameters.GenerateExecutable ? ".exe" : ".dll"; - parameters.OutputAssembly = "OutputAssembly_" + fileName + str; - } - Type typeFromHandle = typeof(CSharpCodeProvider); - CommonCompilationArguments.FixTreatWarningsAsErrors(parameters, typeFromHandle); - return parameters; - } - - private static CSharpCommandLineArguments BuildCommandLineArguments(CompilerParameters parameters, TextWriter outputWriter) - { - IEnumerable enumerable = CSharpCompilationArguments.BuildCommandLineArgArray(parameters); - outputWriter.Write(Res.Compilation_Arguments); - foreach (string current in enumerable) - { - outputWriter.Write(current + " "); - } - outputWriter.WriteLine(); - enumerable = enumerable.Concat(new string[] - { - "SuppressNoSourceFileSpecifiedWarning" - }); - string currentDirectory = Environment.CurrentDirectory; - string environmentVariable = Environment.GetEnvironmentVariable("LIB"); - CSharpCommandLineParser @default = CSharpCommandLineParser.Default; - return @default.Parse(enumerable, currentDirectory, environmentVariable); - } - - private static IEnumerable BuildCommandLineArgArray(CompilerParameters parameters) - { - string text = CSharpCompilationArguments.BuildCommandLineArgString(parameters); - char[] array = text.ToCharArray(); - bool flag = false; - for (int i = 0; i < array.Length; i++) - { - if (array[i] == '"') - { - flag = !flag; - } - if (!flag && array[i] == ' ') - { - array[i] = '\n'; - } - } - IEnumerable lines = new string(array).Split('\n'); - return lines.Where(str => !string.IsNullOrWhiteSpace(str)); - } - - private static string BuildCommandLineArgString(CompilerParameters parameters) - { - StringBuilder stringBuilder = new StringBuilder(); - if (parameters.GenerateExecutable) - { - stringBuilder.Append("/t:exe "); - if (parameters.MainClass != null && parameters.MainClass.Length > 0) - { - stringBuilder.Append("/main:"); - stringBuilder.Append(parameters.MainClass); - stringBuilder.Append(" "); - } - } - else - { - stringBuilder.Append("/t:library "); - } - stringBuilder.Append("/utf8output "); - string location = typeof(object).Assembly.Location; - string text = parameters.CoreAssemblyFileName; - if (string.IsNullOrWhiteSpace(text)) - { - text = location; - } - if (!string.IsNullOrWhiteSpace(text)) - { - stringBuilder.Append("/nostdlib+ "); - stringBuilder.Append("/R:\"").Append(text.Trim()).Append("\" "); - } - string text2 = null; - try - { - Assembly assembly = Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); - text2 = assembly.Location; - } - catch - { - } - if (text2 != null) - { - stringBuilder.Append($"/R:\"{text2}\" "); - } - foreach (string current in parameters.ReferencedAssemblies) - { - stringBuilder.Append("/R:"); - stringBuilder.Append("\""); - stringBuilder.Append(current); - stringBuilder.Append("\""); - stringBuilder.Append(" "); - } - stringBuilder.Append("/out:"); - stringBuilder.Append("\""); - stringBuilder.Append(parameters.OutputAssembly); - stringBuilder.Append("\""); - stringBuilder.Append(" "); - if (parameters.IncludeDebugInformation) - { - stringBuilder.Append("/D:DEBUG "); - stringBuilder.Append("/debug+ "); - stringBuilder.Append("/optimize- "); - } - else - { - stringBuilder.Append("/debug- "); - stringBuilder.Append("/optimize+ "); - } - if (parameters.Win32Resource != null) - { - stringBuilder.Append("/win32res:\"" + parameters.Win32Resource + "\" "); - } - foreach (string current2 in parameters.EmbeddedResources) - { - stringBuilder.Append("/res:\""); - stringBuilder.Append(current2); - stringBuilder.Append("\" "); - } - foreach (string current3 in parameters.LinkedResources) - { - stringBuilder.Append("/linkres:\""); - stringBuilder.Append(current3); - stringBuilder.Append("\" "); - } - if (parameters.TreatWarningsAsErrors) - { - stringBuilder.Append("/warnaserror+ "); - } - else - { - stringBuilder.Append("/warnaserror- "); - } - if (parameters.WarningLevel >= 0) - { - stringBuilder.Append("/w:" + parameters.WarningLevel + " "); - } - if (parameters.CompilerOptions != null) - { - stringBuilder.Append(parameters.CompilerOptions + " "); - } - return stringBuilder.ToString(); - } - } -} diff --git a/Composite/AspNet/Roslyn/CSharpCompiler.cs b/Composite/AspNet/Roslyn/CSharpCompiler.cs deleted file mode 100644 index aafaea6aa0..0000000000 --- a/Composite/AspNet/Roslyn/CSharpCompiler.cs +++ /dev/null @@ -1,94 +0,0 @@ -ï»żusing Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CSharp; -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Composite.AspNet.Roslyn -{ - internal class CSharpCompiler : CommonCompiler - { - public CSharpCompiler(CSharpCodeProvider oldProvider) : base(oldProvider) - { - } - - internal override SyntaxTree ParseText(string text) - { - return CSharpSyntaxTree.ParseText(text); - } - - internal override SyntaxTree ParseFile(string filename) - { - var text = File.ReadAllText(filename); - return ParseText(text); - } - - internal override CommonCompilationArguments ArgumentsFromParameters(CompilerParameters parameters, TextWriter outputWriter) - { - return new CSharpCompilationArguments(parameters, outputWriter); - } - - internal override Microsoft.CodeAnalysis.Compilation CreateCompilation(CommonCompilationArguments arguments, IEnumerable syntaxTrees) - { - var provider = new DesktopStrongNameProvider(arguments.CmdArguments.KeyFileSearchPaths); - var cSharpCompilationOptions = ((CSharpCommandLineArguments)arguments.CmdArguments) - .CompilationOptions - .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) - .WithStrongNameProvider(provider); - - return CSharpCompilation.Create(arguments.OutputFileName, - syntaxTrees - .Where(tree => tree != null), - arguments.MetadataReferences, cSharpCompilationOptions); - } - - internal override CompilerError CompilerErrorFromDiagnostic(Diagnostic diagnostic, TextWriter consoleOutput) - { - string value = CSharpDiagnosticFormatter.Instance.Format(diagnostic, null); - consoleOutput.WriteLine(value); - var compilerError = new CompilerError - { - IsWarning = diagnostic.Severity == DiagnosticSeverity.Warning && !diagnostic.IsWarningAsError, - ErrorNumber = diagnostic.Id, - ErrorText = this.GetErrorNumber(diagnostic) - }; - switch (diagnostic.Location.Kind) - { - case LocationKind.SourceFile: - case LocationKind.XmlFile: - { - FileLinePositionSpan lineSpan = diagnostic.Location.GetLineSpan(); - FileLinePositionSpan mappedLineSpan = diagnostic.Location.GetMappedLineSpan(); - if (lineSpan.IsValid && mappedLineSpan.IsValid) - { - if (!mappedLineSpan.HasMappedPath) - { - compilerError.FileName = lineSpan.Path; - compilerError.Line = lineSpan.Span.Start.Line + 1; - compilerError.Column = lineSpan.Span.Start.Character + 1; - } - else - { - compilerError.FileName = mappedLineSpan.Path; - compilerError.Line = mappedLineSpan.Span.Start.Line + 1; - compilerError.Column = mappedLineSpan.Span.Start.Character + 1; - } - } - break; - } - case LocationKind.MetadataFile: - compilerError.FileName = diagnostic.Location.MetadataModule.Name; - break; - } - return compilerError; - } - - internal string GetErrorNumber(Diagnostic diagnostic) - { - return $"{(diagnostic.IsWarningAsError ? "Warning as Error: " : "")}{diagnostic.GetMessage(null)}"; - } - } -} \ No newline at end of file diff --git a/Composite/AspNet/Roslyn/CommonCompilationArguments.cs b/Composite/AspNet/Roslyn/CommonCompilationArguments.cs deleted file mode 100644 index 2863958904..0000000000 --- a/Composite/AspNet/Roslyn/CommonCompilationArguments.cs +++ /dev/null @@ -1,123 +0,0 @@ -ï»żusing Microsoft.CodeAnalysis; -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Runtime.CompilerServices; - -namespace Composite.AspNet.Roslyn -{ - internal abstract class CommonCompilationArguments - { - private CommandLineArguments cmdArguments; - - private string outputFileName; - - private string outputFileDirectory; - - internal string FinalOutputPath; - - internal string FinalPdbFilePath; - - internal string Win32ResourceFile; - - internal CommandLineArguments CmdArguments => this.cmdArguments; - - internal List MetadataReferences - { - get; - set; - } - - internal string OutputFileName => this.outputFileName; - - internal string OutputFileDirectory => this.outputFileDirectory; - - internal CommonCompilationArguments(CompilerParameters parameters, CommandLineArguments cmdArguments) - { - this.cmdArguments = cmdArguments; - this.MetadataReferences = new List(); - ImmutableArray.Enumerator enumerator = this.CmdArguments.MetadataReferences.GetEnumerator(); - while (enumerator.MoveNext()) - { - CommandLineReference current = enumerator.Current; - string reference = current.Reference; - string text = this.ResolveReference(this.CmdArguments, reference); - if (text == null) - { - throw new ArgumentException(string.Format(Res.Cannot_Resolve_Reference, reference)); - } - var cache = AssemblyMetadataCache.GetInstance(); - - var assemblyMetadata = cache.GetOrAdd(text, AssemblyMetadata.CreateFromFile); - this.MetadataReferences.Add(assemblyMetadata.GetReference()); - } - this.ParseOutputFile(parameters.OutputAssembly, this.CmdArguments.BaseDirectory, out this.outputFileName, out this.outputFileDirectory); - this.FinalOutputPath = Path.Combine(this.OutputFileDirectory, this.OutputFileName); - if (parameters.IncludeDebugInformation) - { - this.FinalPdbFilePath = (this.CmdArguments.PdbPath ?? Path.ChangeExtension(this.FinalOutputPath, ".pdb")); - } - string win32ResourceFile = this.CmdArguments.Win32ResourceFile; - if (!string.IsNullOrWhiteSpace(win32ResourceFile)) - { - this.Win32ResourceFile = Path.Combine(this.CmdArguments.BaseDirectory, win32ResourceFile); - } - } - - //private MetadataReference CreateMetaDataReference(AssemblyMetadata assemblyMetadata) - //{ - // // Obsolete: new MetadataImageReference(assemblyMetadata, null, default(ImmutableArray), false, null, null) - - // var properties = new MetadataReferenceProperties(); - // DocumentationProvider documentationProvider = null; - // string filePath = null; - // string display = null; - - // var type = typeof (MetadataReference).Assembly.GetType("Microsoft.CodeAnalysis.MetadataImageReference"); - // var constructor = type.GetConstructors(BindingFlags.NonPublic).First(); - // return (MetadataReference) constructor.Invoke(new object[] {assemblyMetadata, properties, documentationProvider, filePath, display}); - //} - - private string ResolveReference(CommandLineArguments arguments, string reference) - { - string path = Path.Combine(arguments.BaseDirectory, reference); - if (File.Exists(path)) - { - return Path.GetFullPath(path); - } - ImmutableArray.Enumerator enumerator = arguments.ReferencePaths.GetEnumerator(); - while (enumerator.MoveNext()) - { - string current = enumerator.Current; - path = Path.Combine(current, reference); - if (File.Exists(path)) - { - return Path.GetFullPath(path); - } - } - return null; - } - - internal void ParseOutputFile(string value, string baseDirectory, out string outputFileName, out string outputDirectory) - { - outputFileName = null; - outputDirectory = null; - string arg = null; - string unquoted = CompilationUtil.RemoveAllQuotes(value); - CompilationUtil.ParseAndNormalizeFile(unquoted, baseDirectory, out outputFileName, out outputDirectory, out arg); - if (outputFileName == null) - { - outputFileName = null; - outputDirectory = baseDirectory; - throw new InvalidDataException(string.Format(Res.Cannot_Resolve_Path, arg)); - } - } - - internal static void FixTreatWarningsAsErrors(CompilerParameters parameters, Type codeDomProviderType) - { - parameters.TreatWarningsAsErrors = false; - } - } -} diff --git a/Composite/AspNet/Roslyn/CommonCompiler.cs b/Composite/AspNet/Roslyn/CommonCompiler.cs deleted file mode 100644 index c608001fb2..0000000000 --- a/Composite/AspNet/Roslyn/CommonCompiler.cs +++ /dev/null @@ -1,486 +0,0 @@ -ï»żusing Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Emit; -using System; -using System.CodeDom; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Security; -using System.Security.Permissions; -using System.Text; -using System.Threading; - -namespace Composite.AspNet.Roslyn -{ - internal abstract class CommonCompiler : ICodeCompiler - { - private const int Failed = 1; - - private const int Succeeded = 0; - - protected readonly CodeDomProvider _oldProvider; - - private readonly HashSet reportedDiagnostics = new HashSet(); - - private static readonly string CompilerErrorMessageFormat = "{0}({1},{2}): error {3}: {4}"; - - public CommonCompiler(CodeDomProvider oldProvider) - { - this._oldProvider = oldProvider; - } - - internal abstract SyntaxTree ParseText(string text); - - internal abstract SyntaxTree ParseFile(string file); - - internal abstract Compilation CreateCompilation(CommonCompilationArguments arguments, IEnumerable syntaxTrees); - - internal Compilation CreateCompilation(CommonCompilationArguments arguments, IEnumerable syntaxTrees, TextWriter outputWriter) - { - Compilation result; - try - { - result = this.CreateCompilation(arguments, syntaxTrees); - } - catch (Exception ex) - { - if (outputWriter != null) - { - outputWriter.WriteLine(CommonCompiler.GetErrorOutput(null, string.Format(Res.Internal_Compiler_Error, ex.Message))); - } - result = null; - } - return result; - } - - internal abstract CommonCompilationArguments ArgumentsFromParameters(CompilerParameters parameters, TextWriter outputWriter); - - internal CommonCompilationArguments ArgumentsFromParametersNoThrow(CompilerParameters parameters, TextWriter outputWriter) - { - CommonCompilationArguments result; - try - { - result = this.ArgumentsFromParameters(parameters, outputWriter); - } - catch (Exception ex) - { - if (outputWriter != null) - { - outputWriter.WriteLine(CommonCompiler.GetErrorOutput(null, string.Format(Res.Internal_Compiler_Error, ex.Message))); - } - result = null; - } - return result; - } - - public CompilerResults CompileAssemblyFromDom(CompilerParameters parameters, CodeCompileUnit compilationUnit) - { - return this.CompileAssemblyFromDomBatch(parameters, new CodeCompileUnit[] - { - compilationUnit - }); - } - - public CompilerResults CompileAssemblyFromDomBatch(CompilerParameters parameters, CodeCompileUnit[] compilationUnits) - { - Func func = null; - CompilerResults result; - try - { - if (func == null) - { - func = c => - { - var stringWriter = new StringWriter(); - this._oldProvider.GenerateCodeFromCompileUnit(c, stringWriter, new CodeGeneratorOptions()); - return this.ParseText(stringWriter.ToString()); - }; - } - IEnumerable syntaxTrees = compilationUnits.Select(func); - result = this.Compile(parameters, syntaxTrees); - } - finally - { - parameters.TempFiles.Delete(); - } - return result; - } - - public CompilerResults CompileAssemblyFromFile(CompilerParameters parameters, string fileName) - { - return this.CompileAssemblyFromFileBatch(parameters, new string[] - { - fileName - }); - } - - public CompilerResults CompileAssemblyFromFileBatch(CompilerParameters parameters, string[] fileNames) - { - Func func = null; - CompilerResults result; - try - { - if (func == null) - { - func = ParseFile; - } - result = this.Compile(parameters, fileNames.Select(func)); - } - finally - { - parameters.TempFiles.Delete(); - } - return result; - } - - public CompilerResults CompileAssemblyFromSource(CompilerParameters parameters, string source) - { - return this.CompileAssemblyFromSourceBatch(parameters, new string[] - { - source - }); - } - - public CompilerResults CompileAssemblyFromSourceBatch(CompilerParameters parameters, string[] sources) - { - Func func = null; - CompilerResults result; - try - { - if (func == null) - { - func = ParseText; - } - result = this.Compile(parameters, sources.Select(func)); - } - finally - { - parameters.TempFiles.Delete(); - } - return result; - } - - internal CompilerResults Compile(CompilerParameters parameters, IEnumerable syntaxTrees) - { - CompilerResults result; - using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) - { - CompilerResults compilerResults = this.Compile(parameters, syntaxTrees, stringWriter); - using (StringReader stringReader = new StringReader(stringWriter.ToString())) - { - string[] array = CommonCompiler.ReadAllLines(stringReader, Encoding.UTF8); - string[] array2 = array; - for (int i = 0; i < array2.Length; i++) - { - string value = array2[i]; - compilerResults.Output.Add(value); - } - } - result = compilerResults; - } - return result; - } - - internal CompilerResults Compile(CompilerParameters parameters, IEnumerable syntaxTrees, TextWriter outputWriter) - { - CompilerResults compilerResults = new CompilerResults(parameters.TempFiles); - compilerResults.NativeCompilerReturnValue = 1; - CommonCompilationArguments commonCompilationArguments = this.ArgumentsFromParametersNoThrow(parameters, outputWriter); - if (commonCompilationArguments == null) - { - return compilerResults; - } - if (commonCompilationArguments.CmdArguments.DisplayLogo) - { - this.PrintLogo(outputWriter); - } - if (commonCompilationArguments.CmdArguments.DisplayHelp) - { - this.PrintHelp(outputWriter); - return null; - } - if (this.ErrorInDiagnostics(commonCompilationArguments.CmdArguments.Errors, compilerResults, outputWriter)) - { - return compilerResults; - } - Compilation compilation = this.CreateCompilation(commonCompilationArguments, syntaxTrees, outputWriter); - if (compilation == null - || this.ErrorInDiagnostics(compilation.GetParseDiagnostics(default(CancellationToken)), compilerResults, outputWriter) - || this.ErrorInDiagnostics(compilation.GetDeclarationDiagnostics(default(CancellationToken)), compilerResults, outputWriter)) - { - return compilerResults; - } - SecurityPermission securityPermission = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); - securityPermission.Assert(); - try - { - compilerResults.Evidence = parameters.Evidence; - } - finally - { - CodeAccessPermission.RevertAssert(); - } - bool flag = false; - MemoryStream outputStream = new MemoryStream(); - MemoryStream pdbStream = null; - if (commonCompilationArguments.FinalPdbFilePath != null) - { - pdbStream = new MemoryStream(); - } - CompilerResults result; - using (outputStream) - { - using (pdbStream) - { - try - { - FileStream documentationStream = null; - string documentationPath = commonCompilationArguments.CmdArguments.DocumentationPath; - if (documentationPath != null) - { - documentationStream = OpenFile(documentationPath, outputWriter, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read | FileShare.Write | FileShare.Delete); - if (documentationStream == null) - { - result = compilerResults; - return result; - } - documentationStream.SetLength(0L); - } - Stream win32resourceFileStream = null; - if (!string.IsNullOrWhiteSpace(commonCompilationArguments.Win32ResourceFile)) - { - win32resourceFileStream = OpenFile(commonCompilationArguments.Win32ResourceFile, outputWriter, FileMode.Open, FileAccess.ReadWrite, FileShare.None); - } - EmitResult emitResult; - using (win32resourceFileStream) - { - using (documentationStream) - { - //// Obsolete - //emitResult = compilation.Emit(outputStream, - // commonCompilationArguments.OutputFileName, - // commonCompilationArguments.FinalPdbFilePath, - // pdbStream, documentationStream, default(CancellationToken), - // win32resourceFileStream, commonCompilationArguments.CmdArguments.ManifestResources); - - //var emitOptions = new EmitOptions(); - - emitResult = compilation.Emit(outputStream, - pdbStream, - null, - win32resourceFileStream, - commonCompilationArguments.CmdArguments.ManifestResources, - null, - null); - } - } - if (this.ErrorInDiagnostics(emitResult.Diagnostics, compilerResults, outputWriter)) - { - result = compilerResults; - } - else - { - if (!parameters.GenerateInMemory) - { - if (!CommonCompiler.WriteMemoryStreamToFile(outputStream, commonCompilationArguments.FinalOutputPath, outputWriter)) - { - flag = true; - result = compilerResults; - return result; - } - if (commonCompilationArguments.FinalPdbFilePath != null && !CommonCompiler.WriteMemoryStreamToFile(pdbStream, commonCompilationArguments.FinalPdbFilePath, outputWriter)) - { - flag = true; - result = compilerResults; - return result; - } - compilerResults.PathToAssembly = parameters.OutputAssembly; - } - else - { - byte[] rawAssembly = outputStream.ToArray(); - byte[] rawSymbolStore = null; - if (pdbStream != null) - { - try - { - rawSymbolStore = pdbStream.ToArray(); - } - catch - { - } - } - SecurityPermission securityPermission2 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); - securityPermission2.Assert(); - try - { - compilerResults.CompiledAssembly = Assembly.Load(rawAssembly, rawSymbolStore, parameters.Evidence); - } - finally - { - CodeAccessPermission.RevertAssert(); - } - compilerResults.CompiledAssembly = Assembly.Load(rawAssembly, rawSymbolStore); - } - compilerResults.NativeCompilerReturnValue = 0; - result = compilerResults; - } - } - finally - { - if (flag) - { - if (commonCompilationArguments.FinalOutputPath != null) - { - CommonCompiler.TryDeleteFile(commonCompilationArguments.FinalOutputPath); - } - if (commonCompilationArguments.FinalPdbFilePath != null) - { - CommonCompiler.TryDeleteFile(commonCompilationArguments.FinalPdbFilePath); - } - } - } - } - } - return result; - } - - private static bool WriteMemoryStreamToFile(MemoryStream memoryStream, string filename, TextWriter outputWriter) - { - bool result; - using (FileStream fileStream = CommonCompiler.CreateFile(filename, outputWriter)) - { - if (fileStream == null) - { - result = false; - } - else - { - memoryStream.Position = 0L; - memoryStream.CopyTo(fileStream); - result = true; - } - } - return result; - } - - internal static string[] ReadAllLines(StringReader stringReader, Encoding encoding) - { - List list = new List(); - string item; - while ((item = stringReader.ReadLine()) != null) - { - list.Add(item); - } - return list.ToArray(); - } - - internal void PrintHelp(TextWriter outputWriter) - { - throw new NotImplementedException(); - } - - internal void PrintLogo(TextWriter outputWriter) - { - outputWriter.WriteLine(Res.Product_Name); - outputWriter.WriteLine(Res.Copyright); - outputWriter.WriteLine(); - } - - internal bool ErrorInDiagnostics(IEnumerable diagnostics, CompilerResults results, TextWriter consoleOutput) - { - bool result = false; - foreach (Diagnostic current in diagnostics) - { - if (!this.reportedDiagnostics.Contains(current) - && current.Severity != DiagnosticSeverity.Info - && current.Severity != DiagnosticSeverity.Hidden) - { - this.reportedDiagnostics.Add(current); - if (current.Severity == DiagnosticSeverity.Error || current.IsWarningAsError) - { - result = true; - results.NativeCompilerReturnValue = 1; - } - CompilerError compilerError = this.CompilerErrorFromDiagnostic(current, consoleOutput); - if (compilerError != null) - { - results.Errors.Add(compilerError); - } - } - } - return result; - } - - internal abstract CompilerError CompilerErrorFromDiagnostic(Diagnostic diagnostic, TextWriter consoleOutput); - - internal static string GetErrorOutput(string errorNumber, string errorText) - { - return CommonCompiler.GetErrorOutput(null, 0, 0, errorNumber, errorText); - } - - internal static string GetErrorOutput(string filename = null, int line = 0, int column = 0, string errorNumber = null, string errorText = null) - { - return string.Format(CommonCompiler.CompilerErrorMessageFormat, new object[] - { - filename, - line, - column, - errorNumber, - errorText - }); - } - - internal static FileStream OpenFile(string filePath, TextWriter outputWriter, FileMode mode = FileMode.Open, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.None) - { - FileStream result; - try - { - result = File.Open(filePath, mode, access, share); - } - catch (Exception ex) - { - outputWriter?.WriteLine(GetErrorOutput(null, string.Format(Res.Compiler_Failed_To_Open_File, filePath, ex.Message))); - result = null; - } - return result; - } - - internal static FileStream CreateFile(string filePath, TextWriter outputWriter) - { - FileStream result; - try - { - result = File.Create(filePath, 1024); - } - catch (Exception ex) - { - outputWriter?.WriteLine(CommonCompiler.GetErrorOutput(null, string.Format(Res.Compiler_Failed_To_Create_File, filePath, ex.Message))); - result = null; - } - return result; - } - - internal static bool TryDeleteFile(string filePath) - { - bool result; - try - { - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - result = true; - } - catch - { - result = false; - } - return result; - } - } -} diff --git a/Composite/AspNet/Roslyn/CompilationUtil.cs b/Composite/AspNet/Roslyn/CompilationUtil.cs deleted file mode 100644 index e12953cd36..0000000000 --- a/Composite/AspNet/Roslyn/CompilationUtil.cs +++ /dev/null @@ -1,68 +0,0 @@ -ï»żusing System; -using System.IO; - -namespace Composite.AspNet.Roslyn -{ - internal static class CompilationUtil - { - internal static string RemoveAllQuotes(string arg) - { - return arg?.Replace("\"", ""); - } - - internal static string RemoveTrailingSpacesAndDots(string path) - { - if (path == null) - { - return path; - } - int length = path.Length; - int i = length - 1; - while (i >= 0) - { - char c = path[i]; - if (!char.IsWhiteSpace(c) && c != '.') - { - if (i != length - 1) - { - return path.Substring(0, i + 1); - } - return path; - } - - i--; - } - return string.Empty; - } - - internal static void ParseAndNormalizeFile(string unquoted, string baseDirectory, out string outputFileName, out string outputDirectory, out string invalidPath) - { - outputFileName = null; - outputDirectory = null; - invalidPath = unquoted; - string text = Path.Combine(baseDirectory, unquoted); - if (text != null) - { - try - { - text = Path.GetFullPath(text); - invalidPath = text; - outputFileName = Path.GetFileName(text); - outputDirectory = Path.GetDirectoryName(text); - } - catch (Exception) - { - text = null; - } - if (outputFileName != null) - { - outputFileName = CompilationUtil.RemoveTrailingSpacesAndDots(outputFileName); - } - } - if (text == null) - { - outputFileName = null; - } - } - } -} diff --git a/Composite/AspNet/Roslyn/Res.Designer.cs b/Composite/AspNet/Roslyn/Res.Designer.cs deleted file mode 100644 index 4cd46bf909..0000000000 --- a/Composite/AspNet/Roslyn/Res.Designer.cs +++ /dev/null @@ -1,135 +0,0 @@ -ï»ż//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Composite.AspNet.Roslyn { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Res { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Res() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Composite.AspNet.Roslyn.Res", typeof(Res).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to File name '{0}' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long.. - /// - internal static string Cannot_Resolve_Path { - get { - return ResourceManager.GetString("Cannot_Resolve_Path", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Assembly reference '{0}' is invalid and cannot be resolved.. - /// - internal static string Cannot_Resolve_Reference { - get { - return ResourceManager.GetString("Cannot_Resolve_Reference", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Compilation parameters:. - /// - internal static string Compilation_Arguments { - get { - return ResourceManager.GetString("Compilation_Arguments", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot create file: {0}. The error message is {1}. - /// - internal static string Compiler_Failed_To_Create_File { - get { - return ResourceManager.GetString("Compiler_Failed_To_Create_File", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot open file: {0}. The error message is {1}. - /// - internal static string Compiler_Failed_To_Open_File { - get { - return ResourceManager.GetString("Compiler_Failed_To_Open_File", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Copyright (C) Microsoft Corporation. All rights reserved.. - /// - internal static string Copyright { - get { - return ResourceManager.GetString("Copyright", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Internal Compiler Error: {0}. - /// - internal static string Internal_Compiler_Error { - get { - return ResourceManager.GetString("Internal_Compiler_Error", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CodeDOM Providers for .NET Compiler Platform (“Roslyn”). - /// - internal static string Product_Name { - get { - return ResourceManager.GetString("Product_Name", resourceCulture); - } - } - } -} diff --git a/Composite/AspNet/Roslyn/Res.resx b/Composite/AspNet/Roslyn/Res.resx deleted file mode 100644 index 9c272a4987..0000000000 --- a/Composite/AspNet/Roslyn/Res.resx +++ /dev/null @@ -1,144 +0,0 @@ -ï»ż - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - File name '{0}' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long. - - - Assembly reference '{0}' is invalid and cannot be resolved. - - - Compilation parameters: - - - Cannot create file: {0}. The error message is {1} - - - Cannot open file: {0}. The error message is {1} - - - Copyright (C) Microsoft Corporation. All rights reserved. - - - Internal Compiler Error: {0} - - - CodeDOM Providers for .NET Compiler Platform (“Roslyn”) - - \ No newline at end of file diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index b0cd4f923c..30b98a0a5c 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -259,20 +259,6 @@ - - - - - - Component - - - - - True - True - Res.resx - @@ -2683,12 +2669,6 @@ true - - - ResXFileCodeGenerator - Res.Designer.cs - - diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index 86a698bea8..49d5a54aaf 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -58,10 +58,7 @@ - - - - + diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index 3679e3db43..a3858ca595 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -59,6 +59,14 @@ False ..\bin\Composite.XmlSerializers.dll + + False + ..\Packages\Microsoft.CodeAnalysis.Common.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll + + + False + ..\Packages\Microsoft.CodeAnalysis.CSharp.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll + False ..\bin\Microsoft.Practices.EnterpriseLibrary.Common.dll @@ -75,6 +83,9 @@ ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll True + + ..\Packages\Orckestra.AspNet.Roslyn.1.0.0\lib\net461\Orckestra.AspNet.Roslyn.dll + False @@ -100,6 +111,10 @@ ..\packages\System.Reactive.Linq.3.0.0\lib\net46\System.Reactive.Linq.dll True + + False + ..\Packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll @@ -154,6 +169,9 @@ + + ..\Packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + False ..\bin\TidyNet.dll diff --git a/Website/packages.config b/Website/packages.config index 40f60160d8..ab89ad475e 100644 --- a/Website/packages.config +++ b/Website/packages.config @@ -14,4 +14,10 @@ + + + + + + \ No newline at end of file From a851d27b0b2a30aadea05d4619b00bb5c19aa238 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Tue, 21 Mar 2017 17:22:29 +0100 Subject: [PATCH 080/135] add search package "stuff" to reset.js --- Website/test/e2e/reset.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Website/test/e2e/reset.js b/Website/test/e2e/reset.js index 0b0f1a9a2c..1360b147e6 100644 --- a/Website/test/e2e/reset.js +++ b/Website/test/e2e/reset.js @@ -91,6 +91,7 @@ const removePaths = [ 'App_Data/Composite/TreeDefinitions/Composite.Community.Blog.Settings.xmll', 'App_Data/Composite/DynamicTypeForms/Composite/Community/Blog/Authors.xml', 'App_Data/Composite/DynamicTypeForms/Composite/Community/Blog/Entries.xml', + 'App_Data/Search/', 'Bin/CompositeC1Contrib.RazorFunctions.dll', 'Bin/Microsoft.Web.*.dll', 'Bin/Composite.Community.Extranet.dll', @@ -98,6 +99,10 @@ const removePaths = [ 'Bin/Composite.Community.Newsletter.SubjectBased.dll', 'Bin/Composite.Community.Newsletter.DataTypeBased.dll', 'Bin/Composite.Community.Newsletter.FunctionBased.dll', + 'Bin/Common.Logging*.dll', + 'Bin/BoboBrowse.Net.dll', + 'Bin/C5.dll', + 'Bin/Orckestra.Search*.dll', 'Newsletter.ashx', 'App_Data/Composite/TreeDefinitions/Composite.Community.Newsletter.SubjectBased.xml', 'App_Data/NewsletterType/', From 7917aade521f586f4ddf787c1140f5d178ea5bd1 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 22 Mar 2017 10:26:29 +0100 Subject: [PATCH 081/135] remove xml.readerwriter from website project references --- Website/WebSite.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index a3858ca595..a8d0ae03df 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -169,9 +169,6 @@ - - ..\Packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll - False ..\bin\TidyNet.dll From b029fdbc4581e16c0c2e07d5dbfffda8b24240a3 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 22 Mar 2017 10:33:02 +0100 Subject: [PATCH 082/135] MimeTypeInfo - refactoring --- Composite/Core/IO/MimeTypeInfo.cs | 199 +++++------------- .../DefaultMediaUrlProvider.cs | 2 +- 2 files changed, 49 insertions(+), 152 deletions(-) diff --git a/Composite/Core/IO/MimeTypeInfo.cs b/Composite/Core/IO/MimeTypeInfo.cs index 24f64fc14c..7b74bdd872 100644 --- a/Composite/Core/IO/MimeTypeInfo.cs +++ b/Composite/Core/IO/MimeTypeInfo.cs @@ -8,14 +8,13 @@ using System.Web.Hosting; using System.Xml.Linq; using Composite.C1Console.Forms.CoreUiControls; -using Composite.Core.Extensions; using Composite.Core.ResourceSystem; using Composite.Core.ResourceSystem.Icons; namespace Composite.Core.IO { - /// + /// /// /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] @@ -34,7 +33,7 @@ public static class MimeTypeInfo MimeTypeInfo.Resx, MimeTypeInfo.MasterPage, MimeTypeInfo.CsHtml, MimeTypeInfo.Svg }; // file types we don't expect IIS to block - private static readonly HashSet _iisServableTypes = new HashSet(); + private static readonly HashSet _iisServeableTypes = new HashSet(); private static ResourceHandle GetIconHandle(string name) { @@ -42,179 +41,91 @@ private static ResourceHandle GetIconHandle(string name) } /// - public static string Jpeg - { - get { return "image/jpeg";} - } + public static string Default => "application/octet-stream"; /// - public static string Default - { - get { return "application/octet-stream"; } - } + public static string Jpeg => "image/jpeg"; /// - public static string Gif - { - get { return "image/gif"; } - } + public static string Gif => "image/gif"; /// - public static string Bmp - { - get { return "image/bmp"; } - } + public static string Bmp => "image/bmp"; /// - public static string Png - { - get { return "image/png"; } - } + public static string Png => "image/png"; /// - public static string Tiff - { - get { return "image/tiff"; } - } + public static string Tiff => "image/tiff"; /// - public static string Css - { - get { return "text/css"; } - } + public static string Css => "text/css"; /// - public static string Sass - { - get { return "text/x-sass"; } - } - + public static string Sass => "text/x-sass"; /// - public static string Js - { - get { return "text/js"; } - } + public static string Js => "text/js"; /// - public static string Xml - { - get { return "text/xml"; } - } + public static string Xml => "text/xml"; /// - public static string Text - { - get { return "text/plain"; } - } + public static string Text => "text/plain"; /// - public static string Html - { - get { return "text/html"; } - } + public static string Html => "text/html"; /// - public static string Flash - { - get { return "application/x-shockwave-flash"; } - } + public static string Flash => "application/x-shockwave-flash"; /// - public static string QuickTime - { - get { return "video/quicktime"; } - } + public static string QuickTime => "video/quicktime"; /// - public static string Wmv - { - get { return "video/x-ms-wmv"; } - } + public static string Wmv => "video/x-ms-wmv"; /// - public static string Asf - { - get { return "video/x-ms-asf"; } - } + public static string Asf => "video/x-ms-asf"; /// - public static string Avi - { - get { return "video/x-msvideo"; } - } + public static string Avi => "video/x-msvideo"; /// - public static string Flv - { - get { return "video/x-flv"; } - } + public static string Flv => "video/x-flv"; /// - public static string Director - { - get { return "application/x-director"; } - } + public static string Director => "application/x-director"; /// - public static string CSharp - { - get { return "text/x-csharp"; } - } + public static string CSharp => "text/x-csharp"; /// - public static string CsHtml - { - get { return "application/x-cshtml"; } - } + public static string CsHtml => "application/x-cshtml"; /// - public static string Svg - { - get { return "image/svg+xml"; } - } + public static string Svg => "image/svg+xml"; /// - public static string Ascx - { - get { return "application/x-ascx"; } - } + public static string Ascx => "application/x-ascx"; /// - public static string Aspx - { - get { return "application/x-aspx"; } - } + public static string Aspx => "application/x-aspx"; /// - public static string Asax - { - get { return "application/x-asax"; } - } + public static string Asax => "application/x-asax"; /// - public static string Ashx - { - get { return "application/x-ashx"; } - } + public static string Ashx => "application/x-ashx"; /// - public static string Asmx - { - get { return "application/x-asmx"; } - } + public static string Asmx => "application/x-asmx"; /// - public static string Resx - { - get { return "application/x-resx"; } - } + public static string Resx => "application/x-resx"; /// - public static string MasterPage - { - get { return "application/x-master-page"; } - } + public static string MasterPage => "application/x-master-page"; /// @@ -333,7 +244,7 @@ private static void RegisterMimeType(string canonicalMimeTypeName, string[] exte if (iisServable) { - _iisServableTypes.Add(canonicalMimeTypeName); + _iisServeableTypes.Add(canonicalMimeTypeName); } } @@ -391,7 +302,7 @@ private static void LoadExtensionMappingsFromWebConfig() } else { - _iisServableTypes.Add(mimeType); + _iisServeableTypes.Add(mimeType); } } } @@ -419,12 +330,7 @@ public static string GetCanonical(string mimeType) /// public static ResourceHandle GetResourceHandleFromMimeType(string mimeType) { - if (mimeType == null) - { - return GetIconHandle("mimetype-unknown"); - } - - if (_mimeTypeToResourceName.ContainsKey(mimeType)) + if (mimeType != null && _mimeTypeToResourceName.ContainsKey(mimeType)) { return GetIconHandle(_mimeTypeToResourceName[mimeType]); } @@ -463,16 +369,15 @@ public static string GetMimeType(UploadedFile uploadedFile) { string fileName = System.IO.Path.GetFileName(uploadedFile.FileName); - string mimeTypeFromExtension = MimeTypeInfo.GetCanonicalFromExtension(System.IO.Path.GetExtension(fileName)); + string mimeTypeFromExtension = GetCanonicalFromExtension(System.IO.Path.GetExtension(fileName)); if (mimeTypeFromExtension != MimeTypeInfo.Default) { - Log.LogInformation(LogTitle, "Uploading file '{0}'. MIME type from extension: '{1}'" - .FormatWith(fileName, mimeTypeFromExtension)); + Log.LogInformation(LogTitle, $"Uploading file '{fileName}'. MIME type from extension: '{mimeTypeFromExtension}'"); return mimeTypeFromExtension; } - string mimeTypeFromBrowser = MimeTypeInfo.GetCanonical(uploadedFile.ContentType); + string mimeTypeFromBrowser = GetCanonical(uploadedFile.ContentType); // Default MIME type for Chrome is "application/xml" // Default MIME type for IE is "text/plain" @@ -480,15 +385,14 @@ public static string GetMimeType(UploadedFile uploadedFile) if (mimeTypeFromBrowser != "application/xml" && mimeTypeFromBrowser != "text/plain") { - Log.LogInformation(LogTitle, "Uploading file '{0}'. Browser provided MIME type: '{1}'. Canonical MIME type: '{2}'" - .FormatWith(fileName, uploadedFile.ContentType ?? string.Empty, mimeTypeFromBrowser)); - + Log.LogInformation(LogTitle, $"Uploading file '{fileName}'. " + + $"Browser provided MIME type: '{uploadedFile.ContentType}'. " + + $"Canonical MIME type: '{mimeTypeFromBrowser}'"); return mimeTypeFromBrowser; } - - Log.LogInformation(LogTitle, "Uploading file '{0}'. Applying default MIME type '{1}'" - .FormatWith(fileName, MimeTypeInfo.Default)); + + Log.LogInformation(LogTitle, $"Uploading file '{fileName}'. Applying default MIME type '{Default}'"); return MimeTypeInfo.Default; } @@ -512,9 +416,9 @@ internal static bool IsTextFile(string mimeType) /// /// The extension. /// - /// true if the extension is 'IIS servable'; otherwise, false. + /// true if the extension is 'IIS serveable'; otherwise, false. /// - internal static bool IsIisServable(string extension) + internal static bool IsIisServeable(string extension) { extension = extension.ToLowerInvariant(); @@ -523,18 +427,11 @@ internal static bool IsIisServable(string extension) extension = extension.Substring(1); } - bool servable; - if (_iisServableExtensions.TryGetValue(extension, out servable)) + return _iisServableExtensions.GetOrAdd(extension, ext => { - return servable; - } - - string mimeType = GetCanonicalFromExtension(extension); - servable = _iisServableTypes.Contains(mimeType); - - _iisServableExtensions.TryAdd(extension, servable); - - return servable; + string mimeType = GetCanonicalFromExtension(extension); + return _iisServeableTypes.Contains(mimeType); + }); } } } diff --git a/Composite/Plugins/Routing/MediaUrlProviders/DefaultMediaUrlProvider.cs b/Composite/Plugins/Routing/MediaUrlProviders/DefaultMediaUrlProvider.cs index 9dc1b209c3..c98fc7a3f4 100644 --- a/Composite/Plugins/Routing/MediaUrlProviders/DefaultMediaUrlProvider.cs +++ b/Composite/Plugins/Routing/MediaUrlProviders/DefaultMediaUrlProvider.cs @@ -108,7 +108,7 @@ private static string RemoveForbiddenCharactersAndNormalize(string path) string legalFilePath = RemoveFilePathIllegalCharacters(path); string extension = Path.GetExtension(legalFilePath); - if (!MimeTypeInfo.IsIisServable(extension)) + if (!MimeTypeInfo.IsIisServeable(extension)) { path = path.Replace('.', '_'); } From 024427bb4d4edf04fada0567f8cc28b2c2c14a0c Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 22 Mar 2017 13:07:40 +0100 Subject: [PATCH 083/135] bug fix: cannot remove locale in sql --- .../Foundation/SqlDataProviderStoreManipulator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs b/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs index cbe836735f..e544be056f 100644 --- a/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs +++ b/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs @@ -814,7 +814,8 @@ internal string GetColumnInfo(string tableName, string columnName, { string defaultInfo = string.Empty; string fieldName = fieldDescriptor.Name; - bool isKeyField = dataTypeDescriptor.KeyPropertyNames.Contains(fieldName); + bool isKeyField = dataTypeDescriptor.KeyPropertyNames.Contains(fieldName) + || fieldDescriptor.ForeignKeyReferenceTypeName != null; if (TranslatesIntoDefaultConstraint(fieldDescriptor.DefaultValue)) { From ca1db6c8142011be932d43c310778a4e4487458e Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Wed, 22 Mar 2017 13:35:28 +0100 Subject: [PATCH 084/135] Fix #422 - checkbox will reset to initial state when other form widgets on same form does postback --- .../BoolSelectors/CheckBox.ascx | 96 +++++++++---------- 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/Website/Composite/controls/FormsControls/FormUiControlTemplates/BoolSelectors/CheckBox.ascx b/Website/Composite/controls/FormsControls/FormUiControlTemplates/BoolSelectors/CheckBox.ascx index ca01dc29c8..f34434fb81 100644 --- a/Website/Composite/controls/FormsControls/FormUiControlTemplates/BoolSelectors/CheckBox.ascx +++ b/Website/Composite/controls/FormsControls/FormUiControlTemplates/BoolSelectors/CheckBox.ascx @@ -2,72 +2,68 @@ <%@ Import Namespace="Composite.Plugins.Forms.WebChannel.UiControlFactories" %> /> From a1c64f7eb379a32b79dd72c4304b2908fb675eaf Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 22 Mar 2017 16:09:28 +0100 Subject: [PATCH 085/135] fix localization for component tags + add localization to component title and description --- .../Plugins/Components/ComponentTags/TagManager.cs | 13 +------------ .../FileBasedComponentProvider.cs | 5 +++-- .../Composite/Configuration/ComponentTags.xml | 2 +- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Composite/Plugins/Components/ComponentTags/TagManager.cs b/Composite/Plugins/Components/ComponentTags/TagManager.cs index 76fd1752b3..c8b333c544 100644 --- a/Composite/Plugins/Components/ComponentTags/TagManager.cs +++ b/Composite/Plugins/Components/ComponentTags/TagManager.cs @@ -47,18 +47,7 @@ public string GetTagTitle(string tag) { if (_tagToTitleMap.ContainsKey(tag)) { - string localeTag; - var isTagHasLocale = StringResourceSystemFacade.TryGetString("Composite.Plugins.Components", - _tagToTitleMap[tag].Replace("{","").Replace("}",""), - out localeTag); - if (isTagHasLocale) - { - return localeTag; - } - else - { - return _tagToTitleMap[tag]; - } + return StringResourceSystemFacade.ParseString(_tagToTitleMap[tag]); } return tag; diff --git a/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs b/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs index e152ccca68..4cef11679e 100644 --- a/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs +++ b/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs @@ -14,6 +14,7 @@ using Composite.C1Console.RichContent.ContainerClasses; using Composite.Core; using Composite.Core.IO; +using Composite.Core.ResourceSystem; using Composite.Core.Xml; using Composite.Plugins.Components.ComponentTags; @@ -104,10 +105,10 @@ private Component GetComponentsFromFile(string componentFile) var hashedXmlBytes = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(xmlBytes); var id = new Guid(hashedXmlBytes); - var title = xElement.GetAttributeValue(Namespaces.Components + Title) ?? + var title = StringResourceSystemFacade.ParseString(xElement.GetAttributeValue(Namespaces.Components + Title)) ?? Path.GetFileNameWithoutExtension(componentFile); - var description = xElement.GetAttributeValue(Namespaces.Components + Description) ?? ""; + var description = StringResourceSystemFacade.ParseString(xElement.GetAttributeValue(Namespaces.Components + Description)) ?? ""; var groupingTagsRaw = xElement.GetAttributeValue(Namespaces.Components + Tags) ?? GuessGroupingTagsBasedOnPath(componentFile); diff --git a/Website/App_Data/Composite/Configuration/ComponentTags.xml b/Website/App_Data/Composite/Configuration/ComponentTags.xml index c2ccbb8327..433185aa09 100644 --- a/Website/App_Data/Composite/Configuration/ComponentTags.xml +++ b/Website/App_Data/Composite/Configuration/ComponentTags.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file From 10de47f912a519f1ae906bcb34b77ddf5d2c3f91 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 22 Mar 2017 16:14:08 +0100 Subject: [PATCH 086/135] Adding ISearchDocumentBuilderExtension class to make it possible to extend the data that is indexed. --- Composite/Composite.csproj | 1 + .../ISearchDocumentBuilderExtension.cs | 18 +++++ .../Search/Crawling/SearchDocumentBuilder.cs | 65 ++++++++++++++++--- .../BuiltInTypesDocumentSourceProvider.cs | 17 +++-- .../DocumentSources/CmsPageDocumentSource.cs | 28 ++++---- .../DocumentSources/DataTypeDocumentSource.cs | 12 ++-- .../MediaLibraryDocumentSource.cs | 9 ++- Composite/Search/SearchFacade.cs | 14 +++- 8 files changed, 124 insertions(+), 40 deletions(-) create mode 100644 Composite/Search/Crawling/ISearchDocumentBuilderExtension.cs diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 6fdbd7caca..041370885f 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -256,6 +256,7 @@ + diff --git a/Composite/Search/Crawling/ISearchDocumentBuilderExtension.cs b/Composite/Search/Crawling/ISearchDocumentBuilderExtension.cs new file mode 100644 index 0000000000..58a8e0a6e7 --- /dev/null +++ b/Composite/Search/Crawling/ISearchDocumentBuilderExtension.cs @@ -0,0 +1,18 @@ +ï»żusing Composite.Data; + +namespace Composite.Search.Crawling +{ + /// + /// Allows extending the default SearchDocumentBuilder class, + /// making it possible to index additional new text fragments/field values. + /// + public interface ISearchDocumentBuilderExtension + { + /// + /// Populates the search document builder with the new data. + /// + /// + /// + void Populate(SearchDocumentBuilder searchDocumentBuilder, IData data); + } +} diff --git a/Composite/Search/Crawling/SearchDocumentBuilder.cs b/Composite/Search/Crawling/SearchDocumentBuilder.cs index a9a166e4c6..e6908a2a1d 100644 --- a/Composite/Search/Crawling/SearchDocumentBuilder.cs +++ b/Composite/Search/Crawling/SearchDocumentBuilder.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using Composite.C1Console.Security; +using Composite.Core; +using Composite.Core.Extensions; using Composite.Core.Linq; using Composite.Data; @@ -18,21 +20,44 @@ public class SearchDocumentBuilder private readonly List> _fieldValues = new List>(); private readonly List> _facetFieldValues = new List>(); + private readonly IEnumerable _extensions; + + /// + /// Creates a new instance of . + /// + [Obsolete("Use an overload taking extensions as a parameter.")] + public SearchDocumentBuilder(): this(null) + { + } + + /// + /// Creates a new instance of . + /// + public SearchDocumentBuilder(IEnumerable extensions) + { + _extensions = extensions; + } + /// /// Collected text parts. /// - public IEnumerable TextParts => _textParts; + public ICollection TextParts => _textParts; /// /// Collected field values to be available in search results. /// - public IEnumerable> FieldPreviewValues => _fieldValues; + public ICollection> FieldPreviewValues => _fieldValues; /// /// Collected facet field values /// - public IEnumerable> FacetFieldValues => _facetFieldValues; + public ICollection> FacetFieldValues => _facetFieldValues; + + /// + /// The document url. Setting a not empty value makes the document searchable from the frontend. + /// + public string Url { get; set; } /// /// Sets the interface type, name of which will be used for populating the "Data Type" column in the search results. @@ -122,6 +147,32 @@ public void CrawlData(IData data, bool skipInheritedInterfaces = false) } } } + + _extensions?.ForEach(e => + { + try + { + e.Populate(this, data); + } + catch (Exception ex) + { + Log.LogError(nameof(SearchDocumentBuilder), ex); + } + }); + } + + /// + [Obsolete("Use an overload that does not take a Url parameter and use the Url property instead.")] + public SearchDocument BuildDocument( + string source, + string documentId, + string label, + string versionName, + EntityToken entityToken, + string url) + { + Url = Url ?? url; + return BuildDocument(source, documentId, label, versionName, entityToken); } /// @@ -132,15 +183,13 @@ public void CrawlData(IData data, bool skipInheritedInterfaces = false) /// The label of the item in the tree /// The version name of the item /// The entity token. - /// The document url. Setting a not empty value makes the document searchable from the frontend. /// public SearchDocument BuildDocument( string source, string documentId, string label, string versionName, - EntityToken entityToken, - string url) + EntityToken entityToken) { Verify.ArgumentNotNullOrEmpty(source, nameof(source)); Verify.ArgumentNotNullOrEmpty(documentId, nameof(documentId)); @@ -148,7 +197,7 @@ public SearchDocument BuildDocument( _fieldValues.Add(new KeyValuePair(DefaultDocumentFieldNames.Label, label)); - if (!string.IsNullOrWhiteSpace(url)) + if (!string.IsNullOrWhiteSpace(Url)) { _facetFieldValues.Add(new KeyValuePair(DefaultDocumentFieldNames.HasUrl, new[] { "1" })); } @@ -159,7 +208,7 @@ public SearchDocument BuildDocument( { ElementBundleName = versionName, FullText = _textParts, - Url = url, + Url = Url, FieldValues = _fieldValues .ExcludeDuplicateKeys(pair => pair.Key) .ToDictionary(pair => pair.Key, pair => pair.Value), diff --git a/Composite/Search/DocumentSources/BuiltInTypesDocumentSourceProvider.cs b/Composite/Search/DocumentSources/BuiltInTypesDocumentSourceProvider.cs index b9304d769b..a9aa0299d1 100644 --- a/Composite/Search/DocumentSources/BuiltInTypesDocumentSourceProvider.cs +++ b/Composite/Search/DocumentSources/BuiltInTypesDocumentSourceProvider.cs @@ -4,20 +4,19 @@ namespace Composite.Search.DocumentSources { internal class BuiltInTypesDocumentSourceProvider: ISearchDocumentSourceProvider { - private readonly List _documentSources; + private readonly ISearchDocumentSource[] _documentSources; - public BuiltInTypesDocumentSourceProvider() + public BuiltInTypesDocumentSourceProvider( + CmsPageDocumentSource cmsPageDocumentSource, + MediaLibraryDocumentSource mediaLibraryDocumentSource) { - _documentSources = new List + _documentSources = new ISearchDocumentSource[] { - new CmsPageDocumentSource(), - new MediaLibraryDocumentSource() + cmsPageDocumentSource, + mediaLibraryDocumentSource }; } - public IEnumerable GetDocumentSources() - { - return _documentSources; - } + public IEnumerable GetDocumentSources() => _documentSources; } } diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index 278b91d6bc..8b74de8ad9 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -22,8 +22,9 @@ internal class CmsPageDocumentSource : ISearchDocumentSource private readonly List _listeners = new List(); private readonly DataChangesIndexNotifier _changesIndexNotifier; private readonly Lazy> _customFields; + private readonly IEnumerable _docBuilderExtensions; - public CmsPageDocumentSource() + public CmsPageDocumentSource(IEnumerable extensions) { _customFields = new Lazy>(() => { @@ -37,6 +38,8 @@ public CmsPageDocumentSource() .Evaluate(); }); + _docBuilderExtensions = extensions; + _changesIndexNotifier = new DataChangesIndexNotifier( _listeners, typeof(IPage), data => @@ -110,17 +113,18 @@ private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary< bool isPublished = page.DataSourceId.PublicationScope == PublicationScope.Published; string documentId = GetDocumentId(page); - var documentBuilder = new SearchDocumentBuilder(); - - documentBuilder.SetDataType(typeof(IPage)); - documentBuilder.CrawlData(page); - - string url; + var docBuilder = new SearchDocumentBuilder(_docBuilderExtensions); + docBuilder.SetDataType(typeof(IPage)); using (new DataConnection(page.DataSourceId.PublicationScope, page.DataSourceId.LocaleScope)) { + if (isPublished) + { + docBuilder.Url = PageUrls.BuildUrl(page, UrlKind.Internal); + } + var placeholders = PageManager.GetPlaceholderContent(page.Id, page.VersionId); - placeholders.ForEach(pl => documentBuilder.CrawlData(pl, true)); + placeholders.ForEach(pl => docBuilder.CrawlData(pl, true)); List metaData; @@ -135,17 +139,17 @@ private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary< try { - metaData?.ForEach(pageMetaData => documentBuilder.CrawlData(pageMetaData)); + metaData?.ForEach(pageMetaData => docBuilder.CrawlData(pageMetaData)); } catch (Exception ex) { Log.LogWarning(LogTitle, ex); } - - url = isPublished ? PageUrls.BuildUrl(page, UrlKind.Internal) : null; } - return documentBuilder.BuildDocument(Name, documentId, label, null, entityToken, url); + docBuilder.CrawlData(page); + + return docBuilder.BuildDocument(Name, documentId, label, null, entityToken); } private EntityToken GetAdministratedEntityToken(IPage page) diff --git a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs index a2ba6cce60..f7e8bf3f52 100644 --- a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs +++ b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs @@ -95,17 +95,17 @@ private SearchDocument FromData(IData data) } var docBuilder = new SearchDocumentBuilder(); - docBuilder.CrawlData(data); docBuilder.SetDataType(_interfaceType); string documentId = GetDocumentId(data); - string url = null; - if (InternalUrls.DataTypeSupported(data.DataSourceId.InterfaceType) - && (!_isPublishable || (data.DataSourceId.PublicationScope == PublicationScope.Published))) + if (InternalUrls.DataTypeSupported(_interfaceType) + && (!_isPublishable || data.DataSourceId.PublicationScope == PublicationScope.Published)) { - url = InternalUrls.TryBuildInternalUrl(data.ToDataReference()); + docBuilder.Url = InternalUrls.TryBuildInternalUrl(data.ToDataReference()); } + docBuilder.CrawlData(data); + var entityToken = GetConsoleEntityToken(data); if (entityToken == null) { @@ -113,7 +113,7 @@ private SearchDocument FromData(IData data) return null; } - return docBuilder.BuildDocument(Name, documentId, label, null, entityToken, url); + return docBuilder.BuildDocument(Name, documentId, label, null, entityToken); } private EntityToken GetConsoleEntityToken(IData data) diff --git a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs index 4fbc0d03d7..7502ffc2a0 100644 --- a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs +++ b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs @@ -15,12 +15,15 @@ internal class MediaLibraryDocumentSource : ISearchDocumentSource private readonly Lazy> _customFields; private readonly DataChangesIndexNotifier _changesIndexNotifier; + private readonly IEnumerable _docBuilderExtensions; - public MediaLibraryDocumentSource() + public MediaLibraryDocumentSource(IEnumerable extensions) { _customFields = new Lazy>(() => DataTypeSearchReflectionHelper.GetDocumentFields(typeof(IMediaFile)).Evaluate()); + _docBuilderExtensions = extensions; + _changesIndexNotifier = new DataChangesIndexNotifier( _listeners, typeof(IMediaFile), data => FromMediaFile((IMediaFile)data), @@ -59,12 +62,12 @@ private SearchDocument FromMediaFile(IMediaFile mediaFile) string documentId = mediaFile.Id.ToString(); - var docBuilder = new SearchDocumentBuilder(); + var docBuilder = new SearchDocumentBuilder(_docBuilderExtensions); docBuilder.SetDataType(typeof(IMediaFile)); docBuilder.CrawlData(mediaFile); - return docBuilder.BuildDocument(Name, documentId, label, null, mediaFile.GetDataEntityToken(), null); + return docBuilder.BuildDocument(Name, documentId, label, null, mediaFile.GetDataEntityToken()); } } } diff --git a/Composite/Search/SearchFacade.cs b/Composite/Search/SearchFacade.cs index ea0e143aa0..e84533e7b1 100644 --- a/Composite/Search/SearchFacade.cs +++ b/Composite/Search/SearchFacade.cs @@ -48,8 +48,18 @@ public static async Task SearchConsoleAsync( internal static void AddDefaultSearchDocumentSourceProviders(this IServiceCollection services) { - services.AddSingleton(new BuiltInTypesDocumentSourceProvider()); - services.AddSingleton(new DataTypesDocumentSourceProvider()); + services.AddSingleton(); + services.AddSingleton(); + + services.Add(new ServiceDescriptor( + typeof(ISearchDocumentSourceProvider), + typeof(BuiltInTypesDocumentSourceProvider), + ServiceLifetime.Singleton)); + + services.Add(new ServiceDescriptor( + typeof(ISearchDocumentSourceProvider), + typeof(DataTypesDocumentSourceProvider), + ServiceLifetime.Singleton)); services.AddScoped(); } From 403663710ece155e623cf562d5ea312172694108 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Wed, 22 Mar 2017 16:16:16 +0100 Subject: [PATCH 087/135] add localization to component file tags --- .../FileBasedComponentProvider/FileBasedComponentProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs b/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs index 4cef11679e..857b247198 100644 --- a/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs +++ b/Composite/Plugins/Components/FileBasedComponentProvider/FileBasedComponentProvider.cs @@ -110,7 +110,7 @@ private Component GetComponentsFromFile(string componentFile) var description = StringResourceSystemFacade.ParseString(xElement.GetAttributeValue(Namespaces.Components + Description)) ?? ""; - var groupingTagsRaw = xElement.GetAttributeValue(Namespaces.Components + Tags) ?? + var groupingTagsRaw = StringResourceSystemFacade.ParseString(xElement.GetAttributeValue(Namespaces.Components + Tags)) ?? GuessGroupingTagsBasedOnPath(componentFile); List groupingTags = new List(); From bd5298f7a2fb1446e6cd0374f904b64747b09036 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Thu, 23 Mar 2017 11:41:49 +0100 Subject: [PATCH 088/135] nightwatch upload zip test fix --- Website/test/e2e/reset.js | 1 + .../e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js | 1 + 2 files changed, 2 insertions(+) diff --git a/Website/test/e2e/reset.js b/Website/test/e2e/reset.js index 1360b147e6..2293924edc 100644 --- a/Website/test/e2e/reset.js +++ b/Website/test/e2e/reset.js @@ -143,6 +143,7 @@ const removePaths = [ 'Frontend/Images/', 'Frontend/Composite/', 'bin/Composite.Generated.dll', + 'ZipTest/' ] const rimraf = require('rimraf'); const fs = require('fs'); diff --git a/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js b/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js index f0340faf98..8f3ec7ac63 100644 --- a/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js +++ b/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js @@ -24,6 +24,7 @@ module.exports = { .selectTreeNodeAction("ZipTest","Delete Folder") .clickDialogButton("OK") + .assertTreeNodeHasNoChild("/", "ZipTest") }, afterEach: function (browser, done) { done(); From b6b5f5c161a1fd2b413cdccb4819dcc55c1dc557 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 23 Mar 2017 12:53:59 +0100 Subject: [PATCH 089/135] Cleaning up references in Composite.csproj --- Composite/Composite.csproj | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 30b98a0a5c..b770f2026b 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -70,12 +70,6 @@ ..\packages\Castle.Core.3.3.1\lib\net45\Castle.Core.dll True - - ..\packages\Microsoft.CodeAnalysis.Common.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll - - - ..\packages\Microsoft.CodeAnalysis.CSharp.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll - ..\packages\Microsoft.Extensions.DependencyInjection.1.1.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll @@ -157,9 +151,6 @@ ..\packages\System.Reactive.Windows.Threading.3.0.0\lib\net45\System.Reactive.Windows.Threading.dll True - - ..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll - 3.0 @@ -175,7 +166,8 @@ - ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll + False + ..\Packages\System.ValueTuple.4.3.0\lib\portable-net40+sl4+win8+wp8\System.ValueTuple.dll From 4566002e5d44e2e8410db990d5f27f320fd6182a Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 23 Mar 2017 13:10:32 +0100 Subject: [PATCH 090/135] Using C# 7.0 --- Composite.Workflows/Composite.Workflows.csproj | 1 + Composite/Composite.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/Composite.Workflows/Composite.Workflows.csproj b/Composite.Workflows/Composite.Workflows.csproj index c2d519c2fa..ccb14bf104 100644 --- a/Composite.Workflows/Composite.Workflows.csproj +++ b/Composite.Workflows/Composite.Workflows.csproj @@ -49,6 +49,7 @@ AllRules.ruleset false 618 + 7 pdbonly diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index b770f2026b..7ac01bdd8d 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -51,6 +51,7 @@ AllRules.ruleset 618 false + 7 pdbonly From 8d07a0b4b3ad41061358b379c1f1868ba58ca0a4 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 23 Mar 2017 15:02:07 +0100 Subject: [PATCH 091/135] Workflows - loading externally added serialized workflow files --- .../Workflow/FilePersistenceService.cs | 75 +++++-- .../C1Console/Workflow/WorkflowFacadeImpl.cs | 184 ++++++++++-------- 2 files changed, 158 insertions(+), 101 deletions(-) diff --git a/Composite/C1Console/Workflow/FilePersistenceService.cs b/Composite/C1Console/Workflow/FilePersistenceService.cs index c1341ec0cb..6d204fe391 100644 --- a/Composite/C1Console/Workflow/FilePersistenceService.cs +++ b/Composite/C1Console/Workflow/FilePersistenceService.cs @@ -1,4 +1,5 @@ ï»żusing System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -22,6 +23,9 @@ internal class FileWorkflowPersistenceService : WorkflowPersistenceService private Guid[] _abortedWorkflows; private readonly object _syncRoot = new object(); + private C1FileSystemWatcher _fileWatcher; + + private readonly ConcurrentDictionary _createdWorkflows = new ConcurrentDictionary(); public FileWorkflowPersistenceService(string baseDirectory) { @@ -29,8 +33,6 @@ public FileWorkflowPersistenceService(string baseDirectory) this.PersistAll = false; } - - public bool PersistAll { get; set; } public IEnumerable GetAbortedWorkflows() @@ -42,22 +44,52 @@ public IEnumerable GetPersistedWorkflows() { foreach (string filePath in C1Directory.GetFiles(_baseDirectory, "*.bin")) { - string guidString = Path.GetFileNameWithoutExtension(filePath); + Guid workflowId; + if (TryParseWorkflowId(filePath, out workflowId)) + { + yield return workflowId; + } + } + } - Guid guid = Guid.Empty; + private bool TryParseWorkflowId(string filePath, out Guid workflowId) + { + string guidString = Path.GetFileNameWithoutExtension(filePath); + return Guid.TryParse(guidString ?? "", out workflowId); + } + + public void ListenToDynamicallyAddedWorkflows(Action onWorkflowFileAdded) + { + Verify.IsNull(_fileWatcher, "The method has already been invoked"); + + Action handleWorkflowAdded = name => + { try { - guid = new Guid(guidString); + Guid workflowId; + if (TryParseWorkflowId(name, out workflowId) + && !_createdWorkflows.ContainsKey(workflowId)) + { + onWorkflowFileAdded(workflowId); + } } - catch { } - - if (guid != Guid.Empty) + catch (Exception ex) { - yield return guid; + Log.LogError(LogTitle, ex); } - } - } + }; + + var fileWatcher = new C1FileSystemWatcher(_baseDirectory, "*.bin") + { + IncludeSubdirectories = false + }; + + fileWatcher.Created += (sender, args) => handleWorkflowAdded(args.Name); + fileWatcher.Renamed += (sender, args) => handleWorkflowAdded(args.Name); + fileWatcher.EnableRaisingEvents = true; + _fileWatcher = fileWatcher; + } public bool RemovePersistedWorkflow(Guid instanceId) @@ -78,6 +110,9 @@ public bool RemovePersistedWorkflow(Guid instanceId) } } + byte _; + _createdWorkflows.TryRemove(instanceId, out _); + return true; } @@ -189,6 +224,8 @@ private void SerializeActivity(Activity rootActivity, Guid id) IFormatter formatter = new BinaryFormatter(); formatter.SurrogateSelector = ActivitySurrogateSelector.Default; + _createdWorkflows[id] = 0; + using (var stream = new C1FileStream(filename, FileMode.OpenOrCreate)) { try @@ -212,10 +249,12 @@ private object DeserializeActivity(Activity rootActivity, Guid id) string filename = GetFileName(id); object result; - IFormatter formatter = new BinaryFormatter(); - formatter.SurrogateSelector = ActivitySurrogateSelector.Default; + var formatter = new BinaryFormatter + { + SurrogateSelector = ActivitySurrogateSelector.Default + }; - using (C1FileStream stream = new C1FileStream(filename, FileMode.Open)) + using (var stream = new C1FileStream(filename, FileMode.Open)) { result = Activity.Load(stream, rootActivity, formatter); stream.Close(); @@ -230,16 +269,14 @@ private void MarkWorkflowAsAborted(Guid id) { lock (_syncRoot) { - List newList = new List(_abortedWorkflows ?? new Guid[0]); - newList.Add(id); - - _abortedWorkflows = newList.ToArray(); + _abortedWorkflows = (_abortedWorkflows ?? Array.Empty()) + .Concat(new [] {id}).ToArray(); } } private string GetFileName(Guid id) { - return Path.Combine(this._baseDirectory, id.ToString() + ".bin"); + return Path.Combine(this._baseDirectory, $"{id}.bin"); } } } diff --git a/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs b/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs index b78a44950f..d00013e8bc 100644 --- a/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs +++ b/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs @@ -913,6 +913,8 @@ private void DoInitialize(int delayedTime) DeleteOldWorkflows(); + + _fileWorkflowPersistenceService.ListenToDynamicallyAddedWorkflows(OnNewWorkflowFileAdded); LoadPersistedWorkflows(); LoadPersistedFormData(); @@ -1129,30 +1131,36 @@ private void LoadPersistedWorkflows() { foreach (Guid instanceId in _fileWorkflowPersistenceService.GetPersistedWorkflows()) { - if (!_resourceLocker.Resources.WorkflowStatusDictionary.ContainsKey(instanceId) - || _resourceLocker.Resources.WorkflowStatusDictionary[instanceId] != WorkflowInstanceStatus.Running) + LoadPersistedWorkflow(instanceId); + } + } + + + private void LoadPersistedWorkflow(Guid instanceId) + { + WorkflowInstanceStatus status; + if (!_resourceLocker.Resources.WorkflowStatusDictionary.TryGetValue(instanceId, out status) + || status != WorkflowInstanceStatus.Running) + { + // This will make the runtime load the persisted workflow + WorkflowInstance workflowInstance = null; + try { - // This will make the runtime load the persisted workflow - WorkflowInstance workflowInstance = null; - try - { - workflowInstance = WorkflowRuntime.GetWorkflow(instanceId); - } - catch (InvalidOperationException) - { - _fileWorkflowPersistenceService.RemovePersistedWorkflow(instanceId); - } + workflowInstance = WorkflowRuntime.GetWorkflow(instanceId); + } + catch (InvalidOperationException) + { + _fileWorkflowPersistenceService.RemovePersistedWorkflow(instanceId); + } - if (workflowInstance != null - && !_resourceLocker.Resources.WorkflowPersistingTypeDictionary.ContainsKey(instanceId)) - { - Type workflowType = workflowInstance.GetWorkflowDefinition().GetType(); - SetWorkflowPersistingType(workflowType, instanceId); - } + if (workflowInstance != null + && !_resourceLocker.Resources.WorkflowPersistingTypeDictionary.ContainsKey(instanceId)) + { + Type workflowType = workflowInstance.GetWorkflowDefinition().GetType(); + SetWorkflowPersistingType(workflowType, instanceId); } } - } - + } private void LoadPersistedFormData() @@ -1161,40 +1169,59 @@ private void LoadPersistedFormData() { foreach (string filename in C1Directory.GetFiles(SerializedWorkflowsDirectory, "*.xml")) { - string guidString = Path.GetFileNameWithoutExtension(filename); - Guid id = Guid.Empty; + TryLoadPersistedFormData(filename); + } + } + } - try - { - id = new Guid(guidString); - XDocument doc = XDocumentUtils.Load(filename); - FormData formData = FormData.Deserialize(doc.Root); + private void TryLoadPersistedFormData(string filename) + { + string guidString = Path.GetFileNameWithoutExtension(filename); - if (!_resourceLocker.Resources.FormData.ContainsKey(id)) - { - _resourceLocker.Resources.FormData.Add(id, formData); + Guid id; + if (!Guid.TryParse(guidString ?? "", out id)) return; - FormsWorkflowBindingCache.Bindings.TryAdd(id, formData.Bindings); - } - } - catch (DataSerilizationException ex) - { - Log.LogWarning(LogTitle, "The workflow {0} contained one or more bindings where data was deleted or data type changed", id); - Log.LogWarning(LogTitle, ex); + try + { + var doc = XDocumentUtils.Load(filename); + var formData = FormData.Deserialize(doc.Root); - //AbortWorkflow(id); - } - catch (Exception ex) - { - if (id != Guid.Empty) - { - Log.LogCritical(LogTitle, "Could not deserialize form data for the workflow {0}", id); - Log.LogCritical(LogTitle, ex); - AbortWorkflow(id); - } - } + if (!_resourceLocker.Resources.FormData.ContainsKey(id)) + { + _resourceLocker.Resources.FormData.Add(id, formData); + + FormsWorkflowBindingCache.Bindings.TryAdd(id, formData.Bindings); } } + catch (DataSerilizationException ex) + { + Log.LogWarning(LogTitle, $"The workflow {id} contained one or more bindings where data was deleted or data type changed"); + Log.LogWarning(LogTitle, ex); + + //AbortWorkflow(id); + } + catch (Exception ex) + { + Log.LogCritical(LogTitle, $"Could not deserialize form data for the workflow {id}"); + Log.LogCritical(LogTitle, ex); + AbortWorkflow(id); + } + } + + private void OnNewWorkflowFileAdded(Guid instanceId) + { + Thread.Sleep(100); + + if (HostingEnvironment.ApplicationHost.ShutdownInitiated()) return; + Log.LogInformation(LogTitle, "New workflow detected: " + instanceId); + + LoadPersistedWorkflow(instanceId); + + string formDataFilename = GetFormDataFileName(instanceId); + if (C1File.Exists(formDataFilename)) + { + TryLoadPersistedFormData(formDataFilename); + } } @@ -1272,22 +1299,7 @@ private void PersistFormData(Guid instanceId) if (formData == null) return; - try - { - XElement element = formData.Serialize(); - - string filename = Path.Combine(SerializedWorkflowsDirectory, string.Format("{0}.xml", instanceId)); - - XDocument doc = new XDocument(element); - doc.SaveToFile(filename); - } - catch (Exception ex) - { - // Stop trying serializing this workflow - AbortWorkflow(instanceId); - - Log.LogCritical(LogTitle, ex); - } + PersistFormData(instanceId, formData); } @@ -1306,29 +1318,32 @@ private void PersistFormData() foreach (var kvp in formDataSetToBePersisted) { - Guid instanceid = kvp.Key; + PersistFormData(kvp.Key, kvp.Value); + } + } - try - { - XElement element = kvp.Value.Serialize(); - string filename = Path.Combine(SerializedWorkflowsDirectory, string.Format("{0}.xml", instanceid)); + private void PersistFormData(Guid instanceId, FormData formData) + { + try + { + XElement element = formData.Serialize(); - XDocument doc = new XDocument(element); - doc.SaveToFile(filename); + string filename = GetFormDataFileName(instanceId); - Log.LogVerbose(LogTitle, "FormData persisted for workflow id = " + instanceid); - } - catch (Exception ex) - { - // Stop trying serializing this workflow - AbortWorkflow(instanceid); + XDocument doc = new XDocument(element); + doc.SaveToFile(filename); - Log.LogCritical(LogTitle, ex); - } + Log.LogVerbose(LogTitle, "FormData persisted for workflow id = " + instanceId); } - } + catch (Exception ex) + { + // Stop trying serializing this workflow + AbortWorkflow(instanceId); + Log.LogCritical(LogTitle, ex); + } + } private void DeletePersistedWorkflow(Guid instanceId) @@ -1345,18 +1360,23 @@ private void DeletePersistedFormData(Guid instanceId) { using (GlobalInitializerFacade.CoreIsInitializedScope) { - string filename = Path.Combine(SerializedWorkflowsDirectory, string.Format("{0}.xml", instanceId)); + string filename = GetFormDataFileName(instanceId); if (C1File.Exists(filename)) { C1File.Delete(filename); - Log.LogVerbose(LogTitle, "Persisted FormData deleted for workflow id = {0}", instanceId); + Log.LogVerbose(LogTitle, $"Persisted FormData deleted for workflow id = {instanceId}"); } } } + private string GetFormDataFileName(Guid instanceId) + { + return Path.Combine(SerializedWorkflowsDirectory, $"{instanceId}.xml"); + } + private void DeleteOldWorkflows() { From 673c7d79d873a98930141eb01eea660d2ad384fa Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 24 Mar 2017 14:11:16 +0100 Subject: [PATCH 092/135] Giving a user friendly/localizable names to the MIME types in the search results; refactoring --- Composite/Composite.csproj | 7 +++-- Composite/Core/IO/MimeTypeInfo.cs | 6 ++++ .../DateTimeDataFieldProcessor.cs | 2 +- .../FileNameDataFieldProcessor.cs | 2 +- .../MimeTypeDataFieldProcessor.cs | 21 +++++++++++++ .../PublicationStatusDataFieldProcessor.cs | 2 +- .../DataTypeSearchReflectionHelper.cs | 7 +++++ .../localization/Composite.Search.en-us.xml | 2 +- .../localization/MimeTypes.en-us.xml | 30 +++++++++++++++++++ 9 files changed, 72 insertions(+), 7 deletions(-) rename Composite/Search/Crawling/{ => DataFieldProcessors}/DateTimeDataFieldProcessor.cs (93%) rename Composite/Search/Crawling/{ => DataFieldProcessors}/FileNameDataFieldProcessor.cs (89%) create mode 100644 Composite/Search/Crawling/DataFieldProcessors/MimeTypeDataFieldProcessor.cs rename Composite/Search/Crawling/{ => DataFieldProcessors}/PublicationStatusDataFieldProcessor.cs (94%) create mode 100644 Website/Composite/localization/MimeTypes.en-us.xml diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 95a2f35e73..be7fa93e0d 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -254,14 +254,15 @@ + + + + - - - diff --git a/Composite/Core/IO/MimeTypeInfo.cs b/Composite/Core/IO/MimeTypeInfo.cs index 7b74bdd872..b7a68a9e7a 100644 --- a/Composite/Core/IO/MimeTypeInfo.cs +++ b/Composite/Core/IO/MimeTypeInfo.cs @@ -8,6 +8,7 @@ using System.Web.Hosting; using System.Xml.Linq; using Composite.C1Console.Forms.CoreUiControls; +using Composite.Core.Localization; using Composite.Core.ResourceSystem; using Composite.Core.ResourceSystem.Icons; @@ -411,6 +412,11 @@ internal static bool IsTextFile(string mimeType) } + internal static string TryGetLocalizedName(string mimeType) + { + return StringResourceSystemFacade.GetString("MimeTypes", mimeType, false); + } + /// /// Indicates whether a file of a specific extension is expected to be allowed by IIS /// diff --git a/Composite/Search/Crawling/DateTimeDataFieldProcessor.cs b/Composite/Search/Crawling/DataFieldProcessors/DateTimeDataFieldProcessor.cs similarity index 93% rename from Composite/Search/Crawling/DateTimeDataFieldProcessor.cs rename to Composite/Search/Crawling/DataFieldProcessors/DateTimeDataFieldProcessor.cs index 2f718516a4..29b40e2735 100644 --- a/Composite/Search/Crawling/DateTimeDataFieldProcessor.cs +++ b/Composite/Search/Crawling/DataFieldProcessors/DateTimeDataFieldProcessor.cs @@ -2,7 +2,7 @@ using System.Globalization; using System.Reflection; -namespace Composite.Search.Crawling +namespace Composite.Search.Crawling.DataFieldProcessors { /// /// The default field processor for fields. diff --git a/Composite/Search/Crawling/FileNameDataFieldProcessor.cs b/Composite/Search/Crawling/DataFieldProcessors/FileNameDataFieldProcessor.cs similarity index 89% rename from Composite/Search/Crawling/FileNameDataFieldProcessor.cs rename to Composite/Search/Crawling/DataFieldProcessors/FileNameDataFieldProcessor.cs index d56da991b6..532c49ae88 100644 --- a/Composite/Search/Crawling/FileNameDataFieldProcessor.cs +++ b/Composite/Search/Crawling/DataFieldProcessors/FileNameDataFieldProcessor.cs @@ -1,7 +1,7 @@ ï»żusing System; using System.Collections.Generic; -namespace Composite.Search.Crawling +namespace Composite.Search.Crawling.DataFieldProcessors { internal class FileNameDataFieldProcessor: DefaultDataFieldProcessor { diff --git a/Composite/Search/Crawling/DataFieldProcessors/MimeTypeDataFieldProcessor.cs b/Composite/Search/Crawling/DataFieldProcessors/MimeTypeDataFieldProcessor.cs new file mode 100644 index 0000000000..8a84e0cbbe --- /dev/null +++ b/Composite/Search/Crawling/DataFieldProcessors/MimeTypeDataFieldProcessor.cs @@ -0,0 +1,21 @@ +ï»żusing System.Reflection; +using Composite.Core.IO; + +namespace Composite.Search.Crawling.DataFieldProcessors +{ + internal class MimeTypeDataFieldProcessor : DefaultDataFieldProcessor + { + protected override DocumentFieldPreview.ValuePreviewDelegate GetPreviewFunction(PropertyInfo propertyInfo) + { + return value => GetLocalizedLabel((string)value); + } + + protected override DocumentFieldFacet.FacetValuePreviewDelegate GetFacetValuePreviewFunction(PropertyInfo propertyInfo) + { + return GetLocalizedLabel; + } + + private string GetLocalizedLabel(string mimeType) + => MimeTypeInfo.TryGetLocalizedName(mimeType) ?? mimeType; + } +} diff --git a/Composite/Search/Crawling/PublicationStatusDataFieldProcessor.cs b/Composite/Search/Crawling/DataFieldProcessors/PublicationStatusDataFieldProcessor.cs similarity index 94% rename from Composite/Search/Crawling/PublicationStatusDataFieldProcessor.cs rename to Composite/Search/Crawling/DataFieldProcessors/PublicationStatusDataFieldProcessor.cs index cf9bc7ffea..c20db52ee8 100644 --- a/Composite/Search/Crawling/PublicationStatusDataFieldProcessor.cs +++ b/Composite/Search/Crawling/DataFieldProcessors/PublicationStatusDataFieldProcessor.cs @@ -3,7 +3,7 @@ using Composite.Data.ProcessControlled.ProcessControllers.GenericPublishProcessController; using Texts = Composite.Core.ResourceSystem.LocalizationFiles.Composite_Search.Untranslated; -namespace Composite.Search.Crawling +namespace Composite.Search.Crawling.DataFieldProcessors { internal class PublicationStatusDataFieldProcessor: DefaultDataFieldProcessor { diff --git a/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs b/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs index 6e06f20d01..ce57cf632f 100644 --- a/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs +++ b/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs @@ -8,6 +8,7 @@ using Composite.Data; using Composite.Data.ProcessControlled; using Composite.Data.Types; +using Composite.Search.Crawling.DataFieldProcessors; using SearchableFieldInfo = System.Collections.Generic.KeyValuePair; namespace Composite.Search.Crawling @@ -74,6 +75,12 @@ internal static IDataFieldProcessor GetDataFieldProcessor(PropertyInfo propertyI return new FileNameDataFieldProcessor(); } + if (propertyInfo.DeclaringType == typeof(IMediaFile) + && propertyInfo.Name == nameof(IMediaFile.MimeType)) + { + return new MimeTypeDataFieldProcessor(); + } + return new DefaultDataFieldProcessor(); }); } diff --git a/Website/Composite/localization/Composite.Search.en-us.xml b/Website/Composite/localization/Composite.Search.en-us.xml index 14a0bb2257..46f1ca51f8 100644 --- a/Website/Composite/localization/Composite.Search.en-us.xml +++ b/Website/Composite/localization/Composite.Search.en-us.xml @@ -16,5 +16,5 @@ - + diff --git a/Website/Composite/localization/MimeTypes.en-us.xml b/Website/Composite/localization/MimeTypes.en-us.xml new file mode 100644 index 0000000000..2486ad37f5 --- /dev/null +++ b/Website/Composite/localization/MimeTypes.en-us.xml @@ -0,0 +1,30 @@ +ï»ż + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 93f9abc5f64e18d48c77178cd9dba637b831e8ac Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Fri, 24 Mar 2017 16:55:42 +0100 Subject: [PATCH 093/135] sample refactoring with new c# features --- ...nctionAuxiliarySecurityAncestorProvider.cs | 3 +- .../PageElementProvider.cs | 28 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Composite/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/StandardFunctionAuxiliarySecurityAncestorProvider.cs b/Composite/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/StandardFunctionAuxiliarySecurityAncestorProvider.cs index 1fdf6d1f71..6575c7385c 100644 --- a/Composite/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/StandardFunctionAuxiliarySecurityAncestorProvider.cs +++ b/Composite/Plugins/Elements/ElementProviders/AllFunctionsElementProvider/StandardFunctionAuxiliarySecurityAncestorProvider.cs @@ -32,8 +32,7 @@ public Dictionary> GetParents(IEnumerable< EntityToken resultEntityToken = new BaseFunctionFolderElementEntityToken(id); - IEnumerable resultEntityTokens; - if (!result.TryGetValue(entityToken, out resultEntityTokens)) + if (!result.TryGetValue(entityToken, out IEnumerable resultEntityTokens)) { resultEntityTokens = new List(); result.Add(entityToken, resultEntityTokens); diff --git a/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs b/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs index d068a90063..d57505abf1 100644 --- a/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs +++ b/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Linq; using Composite.C1Console.Actions; @@ -268,14 +268,14 @@ var pageType in public IEnumerable GetChildren(EntityToken entityToken, SearchToken searchToken) { - if (entityToken is AssociatedDataElementProviderHelperEntityToken) + if (entityToken is AssociatedDataElementProviderHelperEntityToken associatedData) { - return _pageAssociatedHelper.GetChildren((AssociatedDataElementProviderHelperEntityToken)entityToken, false); + return _pageAssociatedHelper.GetChildren(associatedData, false); } - if (entityToken is DataGroupingProviderHelperEntityToken) + if (entityToken is DataGroupingProviderHelperEntityToken dataGrouping) { - return _pageAssociatedHelper.GetChildren((DataGroupingProviderHelperEntityToken)entityToken, false); + return _pageAssociatedHelper.GetChildren(dataGrouping, false); } using (new DataScope(DataScopeIdentifier.Administrated)) @@ -300,16 +300,16 @@ public IEnumerable GetForeignRoots(SearchToken searchToken) public IEnumerable GetForeignChildren(EntityToken entityToken, SearchToken searchToken) { - if (entityToken is DataEntityToken && ((DataEntityToken)entityToken).Data == null) return new Element[] { }; + if (entityToken is DataEntityToken dataEntityToken && dataEntityToken.Data == null) return Array.Empty(); - if (entityToken is AssociatedDataElementProviderHelperEntityToken) + if (entityToken is AssociatedDataElementProviderHelperEntityToken associatedData) { - return _pageAssociatedHelper.GetChildren((AssociatedDataElementProviderHelperEntityToken)entityToken, true); + return _pageAssociatedHelper.GetChildren(associatedData, true); } - if (entityToken is DataGroupingProviderHelperEntityToken) + if (entityToken is DataGroupingProviderHelperEntityToken dataGrouping) { - return _pageAssociatedHelper.GetChildren((DataGroupingProviderHelperEntityToken)entityToken, true); + return _pageAssociatedHelper.GetChildren(dataGrouping, true); } IEnumerable pages; @@ -443,9 +443,9 @@ private IEnumerable GetChildElements(EntityToken entityToken, IEnumerab return Guid.Empty; } - if (entityToken is DataEntityToken) + if (entityToken is DataEntityToken dataEntityToken) { - IPage parentPage = ((DataEntityToken)entityToken).Data as IPage; + IPage parentPage = dataEntityToken.Data as IPage; return parentPage?.Id; } @@ -546,9 +546,9 @@ public bool OnElementDraggedAndDropped(EntityToken draggedEntityToken, EntityTok { newParentPageId = Guid.Empty; } - else if (newParentEntityToken is DataEntityToken) + else if (newParentEntityToken is DataEntityToken dataEntityToken) { - IPage newParentPage = (IPage)((DataEntityToken)newParentEntityToken).Data; + IPage newParentPage = dataEntityToken.Data as IPage; newParentPageId = newParentPage.Id; } else From 4d877759960ef1da131c532fece0b487707b96d2 Mon Sep 17 00:00:00 2001 From: Morteza Kasravi Date: Mon, 27 Mar 2017 16:10:13 +0200 Subject: [PATCH 094/135] fix #339 actual bug: page rendering history was not cleared after store change --- Composite/Data/PageRenderingHistory.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Composite/Data/PageRenderingHistory.cs b/Composite/Data/PageRenderingHistory.cs index 53d39f525a..2e73cbfc84 100644 --- a/Composite/Data/PageRenderingHistory.cs +++ b/Composite/Data/PageRenderingHistory.cs @@ -34,6 +34,13 @@ static PageRenderingHistory() DataEvents.OnAfterUpdate += (sender, args) => PageUpdated((IPage) args.Data); DataEvents.OnDeleted += (sender, args) => PageUpdated((IPage)args.Data); + DataEvents.OnStoreChanged += (sender, args) => + { + if (!args.DataEventsFired) + { + _renderedPages.Clear(); + } + }; } private static string GetCacheKey(IPage page) From d75153dd6156bc2c721c3c303ce13ad965cdf421 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 27 Mar 2017 17:25:34 +0200 Subject: [PATCH 095/135] Making newly added dynamic types searchable by default --- .../DynamicTypes/Debug/DynamicTempTypeCreator.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Composite/Data/DynamicTypes/Debug/DynamicTempTypeCreator.cs b/Composite/Data/DynamicTypes/Debug/DynamicTempTypeCreator.cs index fbdd615b3d..2a949b261a 100644 --- a/Composite/Data/DynamicTypes/Debug/DynamicTempTypeCreator.cs +++ b/Composite/Data/DynamicTypes/Debug/DynamicTempTypeCreator.cs @@ -61,13 +61,7 @@ public string TypeTitle /// - public List DataFieldDescriptors - { - get - { - return _dataFieldDescriptors; - } - } + public List DataFieldDescriptors => _dataFieldDescriptors; private void Initialize() @@ -75,7 +69,7 @@ private void Initialize() int counter = 1; while (true) { - string typeName = string.Format("{0}{1}", _namePrefix, counter++); + string typeName = $"{_namePrefix}{counter++}"; if (!DataMetaDataFacade.GeneratedTypeDataTypeDescriptors.Any(d => d.Name == typeName)) { @@ -91,7 +85,7 @@ private void Initialize() { Position = 10, IsNullable = true, - DataUrlProfile = new DataUrlProfile() + DataUrlProfile = new DataUrlProfile { Format = DataUrlSegmentFormat.DateTime_Year, Order = 1 @@ -106,6 +100,10 @@ private void Initialize() { OrderPriority = 1, OrderDescending = false, + }, + SearchProfile = new SearchProfile + { + IndexText = true } }, new DataFieldDescriptor(Guid.NewGuid(), "MyIntField", StoreFieldType.Integer, typeof(int)) From 79f80ba8a3f9d58ee6ff5e431c3b6516bd0dee98 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 27 Mar 2017 17:35:27 +0200 Subject: [PATCH 096/135] ISearchDocumentSource - now includes continuation tokens to support continuous indexing that survives website restarts. --- .../Endpoint/ConsoleSearchRpcService.cs | 3 +- .../DocumentSources/CmsPageDocumentSource.cs | 43 ++++++- .../DocumentSources/DataTypeDocumentSource.cs | 105 +++++++++++++++--- .../MediaLibraryDocumentSource.cs | 15 ++- Composite/Search/ISearchDocumentSource.cs | 27 ++++- 5 files changed, 168 insertions(+), 25 deletions(-) diff --git a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs index 5ad0fa9bc4..ba054b5d03 100644 --- a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs +++ b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs @@ -185,7 +185,8 @@ private ConsoleSearchResultFacetField[] EmptyFacetsFromSelections( return (from selection in query.Selections where selection.Values.Length > 0 - let facetField = facetFields.First(ff => ff.Name == selection.FieldName) + let facetField = facetFields.Where(ff => ff.Name == selection.FieldName) + .FirstOrException($"Facet field '{selection.FieldName}' not found") select new ConsoleSearchResultFacetField { FieldName = MakeFieldNameJsFriendly(selection.FieldName), diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index 6315fc4e14..5c6b5269ac 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -60,15 +60,22 @@ public void Subscribe(IDocumentSourceListener sourceListener) _listeners.Add(sourceListener); } - public IEnumerable GetAllSearchDocuments(CultureInfo culture) + public IEnumerable GetSearchDocuments(CultureInfo culture, string continuationToken = null) { ICollection unpublishedPages; + var (lastPageId, lastPagesPublicationScope) = ParseContinuationToken(continuationToken); + using (var conn = new DataConnection(PublicationScope.Unpublished, culture)) { unpublishedPages = conn.Get().Evaluate(); } + unpublishedPages = unpublishedPages + .Where(p => p.Id.CompareTo(lastPageId) >= 0) + .OrderBy(p => p.Id) + .ToList(); + var publishedPages = new Dictionary, IPage>(); using (var conn = new DataConnection(PublicationScope.Published, culture)) { @@ -84,10 +91,15 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) var entityToken = unpublishedPage.GetDataEntityToken(); IPage publishedPage; - if (publishedPages.TryGetValue(new Tuple(unpublishedPage.Id, unpublishedPage.VersionId), + if (unpublishedPage.Id.CompareTo(lastPageId) > 0 + && publishedPages.TryGetValue(new Tuple(unpublishedPage.Id, unpublishedPage.VersionId), out publishedPage)) { - yield return FromPage(publishedPage, entityToken, publishedMetaData); + yield return new DocumentWithContinuationToken + { + Document = FromPage(publishedPage, entityToken, publishedMetaData), + ContinuationToken = GetContinuationToken(publishedPage) + }; if (unpublishedPage.PublicationStatus == GenericPublishProcessController.Published) { @@ -96,12 +108,35 @@ public IEnumerable GetAllSearchDocuments(CultureInfo culture) } } - yield return FromPage(unpublishedPage, entityToken, unpublishedMetaData); + if (unpublishedPage.Id.CompareTo(lastPageId) > 0 + || lastPagesPublicationScope == PublicationScope.Published) + { + yield return new DocumentWithContinuationToken + { + Document = FromPage(unpublishedPage, entityToken, unpublishedMetaData), + ContinuationToken = GetContinuationToken(unpublishedPage) + }; + } } } + private (Guid lastPage , PublicationScope publicationScope) ParseContinuationToken(string continuationToken) + { + if (continuationToken == null) + { + return (Guid.Empty, PublicationScope.Unpublished); + } + + var values = continuationToken.Split(':'); + return (Guid.Parse(values[0]), (PublicationScope) Enum.Parse(typeof(PublicationScope), values[1])); + } + + private string GetContinuationToken(IPage page) => $"{page.Id}:{page.DataSourceId.PublicationScope}"; + + public ICollection CustomFields => _customFields.Value; + private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary, List> allMetaData) { string label = page.MenuTitle; diff --git a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs index 37e522a6db..2227d32f84 100644 --- a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs +++ b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs @@ -5,8 +5,10 @@ using Composite.C1Console.Security; using Composite.Search.Crawling; using Composite.Core; +using Composite.Core.Extensions; using Composite.Core.Linq; using Composite.Core.Routing; +using Composite.Core.Types; using Composite.Core.WebClient; using Composite.Data; using Composite.Data.DynamicTypes; @@ -55,36 +57,111 @@ public void Subscribe(IDocumentSourceListener sourceListener) _listeners.Add(sourceListener); } - public IEnumerable GetAllSearchDocuments(CultureInfo culture) + public IEnumerable GetSearchDocuments(CultureInfo culture, string continuationToken = null) { - using (new DataConnection(PublicationScope.Published, culture)) - { - var dataSet = DataFacade.GetData(_interfaceType).Cast().Evaluate(); + var (continueFromScope, continueFromKey) = ParseCToken(continuationToken); - foreach (var document in dataSet.Select(d => FromData(d, culture)).Where(doc => doc != null)) + if (continueFromScope == PublicationScope.Published) + { + var documents = GetDocumentsFromScope(PublicationScope.Published, culture, continueFromKey); + foreach (var doc in documents) { - yield return document; + yield return doc; } } + if (typeof (IPublishControlled).IsAssignableFrom(_interfaceType)) { - using (new DataConnection(PublicationScope.Unpublished, culture)) + var documents = GetDocumentsFromScope(PublicationScope.Unpublished, culture, + continueFromScope == PublicationScope.Unpublished ? continueFromKey : null); + + foreach (var doc in documents) + { + yield return doc; + } + } + } + + private IEnumerable GetDocumentsFromScope( + PublicationScope publicationScope, + CultureInfo culture, + object continueFromKey) + { + using (new DataConnection(publicationScope, culture)) + { + var query = DataFacade.GetData(_interfaceType); + + query = FilterAndOrderByKey(query, continueFromKey); + + if (publicationScope == PublicationScope.Unpublished) { - var dataSet = DataFacade.GetData(_interfaceType) + query = query .Cast() - .Where(data => data.PublicationStatus != GenericPublishProcessController.Published) - .Evaluate(); + .Where(data => data.PublicationStatus != GenericPublishProcessController.Published); + } + var dataSet = query.Cast().Evaluate(); - foreach (var document in dataSet.Select(data => FromData(data, culture)) - .Where(doc => doc != null)) + foreach (var data in dataSet) + { + var document = FromData(data, culture); + if (document == null) continue; + + yield return new DocumentWithContinuationToken { - yield return document; - } + Document = document, + ContinuationToken = GetContinuationToken(data, PublicationScope.Unpublished) + }; } } } + private IQueryable FilterAndOrderByKey(IQueryable dataset, object continueFromKey) + { + var keyProperties = _interfaceType.GetKeyProperties(); + if (keyProperties.Count > 1 + || !keyProperties.All(property => typeof(IComparable).IsAssignableFrom(property.PropertyType))) + { + return dataset.Cast(); // Not supported + } + + var keyProperty = keyProperties.Single(); + + if (continueFromKey != null) + { + dataset = dataset.Cast() + .Where(data => (keyProperty.GetValue(data) as IComparable).CompareTo(continueFromKey) > 0) + .AsQueryable(); + } + + return dataset.OrderBy(_interfaceType, keyProperty.Name); + } + + private (PublicationScope continueFromScope, object continueFromKey) ParseCToken(string continuationToken) + { + if (continuationToken == null) + { + return (PublicationScope.Published, null); + } + + int separator = continuationToken.IndexOf(':'); + string keyStr = continuationToken.Substring(separator); + object key = ValueTypeConverter.Convert(keyStr, _interfaceType.GetKeyProperties().Single().PropertyType); + var scope = (PublicationScope) Enum.Parse(typeof(PublicationScope), continuationToken.Substring(0, separator-1)); + + return (scope, key); + } + + private string GetContinuationToken(IData data, PublicationScope publicationScope) + { + if (_interfaceType.GetKeyProperties().Count > 1) return null; // Not supported + + var key = data.GetUniqueKey(); + string keyStr = ValueTypeConverter.Convert(key); + return $"{publicationScope}:{keyStr}"; + } + + public ICollection CustomFields => _customFields.Value; private SearchDocument FromData(IData data, CultureInfo culture) diff --git a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs index 2361701fdd..c6b3148262 100644 --- a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs +++ b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs @@ -40,16 +40,25 @@ public void Subscribe(IDocumentSourceListener sourceListener) _listeners.Add(sourceListener); } - public IEnumerable GetAllSearchDocuments(CultureInfo culture) + public IEnumerable GetSearchDocuments(CultureInfo culture, string continuationToken = null) { IEnumerable mediaFiles; + Guid lastMediaFileId = continuationToken == null ? Guid.Empty : new Guid(continuationToken); + using (var conn = new DataConnection()) { - mediaFiles = conn.Get().Evaluate(); + mediaFiles = conn.Get() + .Where(m => m.Id.CompareTo(lastMediaFileId) > 0) + .OrderBy(m => m.Id) + .Evaluate(); } - return mediaFiles.Select(FromMediaFile); + return mediaFiles.Select(m => new DocumentWithContinuationToken + { + Document = FromMediaFile(m), + ContinuationToken = m.Id.ToString() + }); } private SearchDocument FromMediaFile(IMediaFile mediaFile) diff --git a/Composite/Search/ISearchDocumentSource.cs b/Composite/Search/ISearchDocumentSource.cs index d391a47903..baa4e5296d 100644 --- a/Composite/Search/ISearchDocumentSource.cs +++ b/Composite/Search/ISearchDocumentSource.cs @@ -14,11 +14,16 @@ public interface ISearchDocumentSource string Name { get; } /// - /// Gets all the search documents for the current source. + /// Returns search documents along with continuation tokens, so the indexing can be + /// can be continued after website restart. /// - /// + /// The culture for which the documents should be build. + /// Continuation token - contains pointer to the last + /// already indexed search documents, so the method will return all the following ones. /// - IEnumerable GetAllSearchDocuments(CultureInfo culture); + IEnumerable GetSearchDocuments( + CultureInfo culture, + string continuationToken = null); /// /// Gets the custom fields. @@ -31,4 +36,20 @@ public interface ISearchDocumentSource /// void Subscribe(IDocumentSourceListener sourceListener); } + + /// + /// Represents a tuple of a document and a continuation token + /// + public sealed class DocumentWithContinuationToken + { + /// + /// The current document. + /// + public SearchDocument Document { get; set; } + + /// + /// The continuation token for the document source. + /// + public string ContinuationToken { get; set; } + } } From c035bd4936532138ae4568fdb9b6b759a82472cf Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 28 Mar 2017 12:49:01 +0200 Subject: [PATCH 097/135] Search fixes --- .../DocumentSources/CmsPageDocumentSource.cs | 8 +++--- .../DocumentSources/DataTypeDocumentSource.cs | 25 +++++++++++-------- .../MediaLibraryDocumentSource.cs | 8 +++--- Composite/Search/ISearchDocumentSource.cs | 2 +- Website/WebSite.csproj | 1 + 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index 5c6b5269ac..13e56955de 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -21,12 +21,12 @@ internal class CmsPageDocumentSource : ISearchDocumentSource private readonly List _listeners = new List(); private readonly DataChangesIndexNotifier _changesIndexNotifier; - private readonly Lazy> _customFields; + private readonly Lazy> _customFields; private readonly IEnumerable _docBuilderExtensions; public CmsPageDocumentSource(IEnumerable extensions) { - _customFields = new Lazy>(() => + _customFields = new Lazy>(() => { var pageDocFields = DataTypeSearchReflectionHelper.GetDocumentFields(typeof (IPage)); var metaDataFields = PageMetaDataFacade.GetAllMetaDataTypes() @@ -35,7 +35,7 @@ public CmsPageDocumentSource(IEnumerable extens return pageDocFields .Concat(metaDataFields) .ExcludeDuplicateKeys(f => f.Name) - .Evaluate(); + .ToList(); }); _docBuilderExtensions = extensions; @@ -134,7 +134,7 @@ public IEnumerable GetSearchDocuments(CultureInfo private string GetContinuationToken(IPage page) => $"{page.Id}:{page.DataSourceId.PublicationScope}"; - public ICollection CustomFields => _customFields.Value; + public IReadOnlyCollection CustomFields => _customFields.Value; private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary, List> allMetaData) diff --git a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs index 2227d32f84..91cc2cb3cf 100644 --- a/Composite/Search/DocumentSources/DataTypeDocumentSource.cs +++ b/Composite/Search/DocumentSources/DataTypeDocumentSource.cs @@ -24,7 +24,7 @@ internal class DataTypeDocumentSource : ISearchDocumentSource private readonly List _listeners = new List(); private readonly Type _interfaceType; private readonly DataChangesIndexNotifier _changesIndexNotifier; - private readonly Lazy> _customFields; + private readonly Lazy> _customFields; private readonly bool _isPublishable; @@ -42,7 +42,7 @@ public DataTypeDocumentSource(Type interfaceType) _isPublishable = typeof (IPublishControlled).IsAssignableFrom(_interfaceType); - _customFields = new Lazy>(GetDocumentFields); + _customFields = new Lazy>(GetDocumentFields); _changesIndexNotifier = new DataChangesIndexNotifier( _listeners, _interfaceType, FromData, GetDocumentId); @@ -110,7 +110,7 @@ private IEnumerable GetDocumentsFromScope( yield return new DocumentWithContinuationToken { Document = document, - ContinuationToken = GetContinuationToken(data, PublicationScope.Unpublished) + ContinuationToken = GetContinuationToken(data, publicationScope) }; } } @@ -127,14 +127,17 @@ private IQueryable FilterAndOrderByKey(IQueryable dataset, object continueFromKe var keyProperty = keyProperties.Single(); + dataset = dataset.OrderBy(_interfaceType, keyProperty.Name); + if (continueFromKey != null) { dataset = dataset.Cast() + .ToList() .Where(data => (keyProperty.GetValue(data) as IComparable).CompareTo(continueFromKey) > 0) .AsQueryable(); } - return dataset.OrderBy(_interfaceType, keyProperty.Name); + return dataset; } private (PublicationScope continueFromScope, object continueFromKey) ParseCToken(string continuationToken) @@ -145,9 +148,11 @@ private IQueryable FilterAndOrderByKey(IQueryable dataset, object continueFromKe } int separator = continuationToken.IndexOf(':'); - string keyStr = continuationToken.Substring(separator); - object key = ValueTypeConverter.Convert(keyStr, _interfaceType.GetKeyProperties().Single().PropertyType); - var scope = (PublicationScope) Enum.Parse(typeof(PublicationScope), continuationToken.Substring(0, separator-1)); + string keyStr = continuationToken.Substring(separator + 1); + var keyPropertyType = _interfaceType.GetKeyProperties().Single().PropertyType; + + object key = ValueTypeConverter.Convert(keyStr, keyPropertyType); + var scope = (PublicationScope) Enum.Parse(typeof(PublicationScope), continuationToken.Substring(0, separator)); return (scope, key); } @@ -162,7 +167,7 @@ private string GetContinuationToken(IData data, PublicationScope publicationScop } - public ICollection CustomFields => _customFields.Value; + public IReadOnlyCollection CustomFields => _customFields.Value; private SearchDocument FromData(IData data, CultureInfo culture) { @@ -224,9 +229,9 @@ private string GetDocumentId(IData data) return uniqueKey + scopeSuffix; } - ICollection GetDocumentFields() + List GetDocumentFields() { - return DataTypeSearchReflectionHelper.GetDocumentFields(_interfaceType).Evaluate(); + return DataTypeSearchReflectionHelper.GetDocumentFields(_interfaceType).ToList(); } private static void OnStoreCreated(DataTypeDescriptor dataTypeDescriptor) diff --git a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs index c6b3148262..b52d93c46a 100644 --- a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs +++ b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs @@ -13,14 +13,14 @@ internal class MediaLibraryDocumentSource : ISearchDocumentSource { private readonly List _listeners = new List(); - private readonly Lazy> _customFields; + private readonly Lazy> _customFields; private readonly DataChangesIndexNotifier _changesIndexNotifier; private readonly IEnumerable _docBuilderExtensions; public MediaLibraryDocumentSource(IEnumerable extensions) { - _customFields = new Lazy>(() => - DataTypeSearchReflectionHelper.GetDocumentFields(typeof(IMediaFile)).Evaluate()); + _customFields = new Lazy>(() => + DataTypeSearchReflectionHelper.GetDocumentFields(typeof(IMediaFile)).ToList()); _docBuilderExtensions = extensions; @@ -33,7 +33,7 @@ public MediaLibraryDocumentSource(IEnumerable e public string Name => typeof(IMediaFile).FullName; - public ICollection CustomFields => _customFields.Value; + public IReadOnlyCollection CustomFields => _customFields.Value; public void Subscribe(IDocumentSourceListener sourceListener) { diff --git a/Composite/Search/ISearchDocumentSource.cs b/Composite/Search/ISearchDocumentSource.cs index baa4e5296d..d22b1fa259 100644 --- a/Composite/Search/ISearchDocumentSource.cs +++ b/Composite/Search/ISearchDocumentSource.cs @@ -28,7 +28,7 @@ IEnumerable GetSearchDocuments( /// /// Gets the custom fields. /// - ICollection CustomFields { get; } + IReadOnlyCollection CustomFields { get; } /// /// Subscribes the given search document sourceListener to the source. diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index a8d0ae03df..da3e9262ee 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -657,6 +657,7 @@ + Designer From daf4f3159fd0144ebd3334edd5e10cabc4157386 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 29 Mar 2017 11:43:46 +0200 Subject: [PATCH 098/135] Refactoring, fixing typos --- .../Security/EntityTokenSerializer.cs | 28 +++-- .../Extensions/IQueryableExtensionMethods.cs | 102 ++---------------- Composite/Data/DataEntityToken.cs | 8 +- 3 files changed, 25 insertions(+), 113 deletions(-) diff --git a/Composite/C1Console/Security/EntityTokenSerializer.cs b/Composite/C1Console/Security/EntityTokenSerializer.cs index 2cfa32b100..29c93a3d6b 100644 --- a/Composite/C1Console/Security/EntityTokenSerializer.cs +++ b/Composite/C1Console/Security/EntityTokenSerializer.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; +ï»żusing System; using System.Reflection; using System.Security; using System.Text; -using Composite.Core.Extensions; using Composite.Core.Serialization; using Composite.Core.Types; @@ -37,7 +35,7 @@ public static string Serialize(EntityToken entityToken, bool includeHashValue) if (serializedEntityToken == null) { - throw new InvalidCastException(string.Format("'{0}' Serialize returned null", entityToken.GetType())); + throw new InvalidCastException($"'{entityToken.GetType()}' Serialize returned null"); } StringConversionServices.SerializeKeyValuePair(sb, "entityToken", serializedEntityToken); @@ -53,25 +51,25 @@ public static string Serialize(EntityToken entityToken, bool includeHashValue) /// - public static EntityToken Deserialize(string serialziedEntityToken) + public static EntityToken Deserialize(string serializedEntityToken) { - return Deserialize(serialziedEntityToken, false); + return Deserialize(serializedEntityToken, false); } /// - public static EntityToken Deserialize(string serialziedEntityToken, bool includeHashValue) + public static EntityToken Deserialize(string serializedEntityToken, bool includeHashValue) { - if (string.IsNullOrEmpty(serialziedEntityToken)) throw new ArgumentNullException("serialziedEntityToken"); + if (string.IsNullOrEmpty(serializedEntityToken)) throw new ArgumentNullException(nameof(serializedEntityToken)); - Dictionary dic = StringConversionServices.ParseKeyValueCollection(serialziedEntityToken); + var dic = StringConversionServices.ParseKeyValueCollection(serializedEntityToken); if (!dic.ContainsKey("entityTokenType") || !dic.ContainsKey("entityToken") || (includeHashValue && !dic.ContainsKey("entityTokenHash"))) { - throw new ArgumentException("Failed to deserialize the value. Is has to be searized with EntityTokenSerializer.", "serialziedEntityToken"); + throw new ArgumentException("Failed to deserialize the value. Is has to be serialized with EntityTokenSerializer.", nameof(serializedEntityToken)); } string entityTokenTypeString = StringConversionServices.DeserializeValueString(dic["entityTokenType"]); @@ -93,7 +91,7 @@ public static EntityToken Deserialize(string serialziedEntityToken, bool include MethodInfo methodInfo = entityType.GetMethod("Deserialize", BindingFlags.Public | BindingFlags.Static); if (methodInfo == null) { - throw new InvalidOperationException(string.Format("The entity token {0} is missing a public static Deserialize method taking a string as parameter and returning an {1}", entityType, typeof(EntityToken))); + throw new InvalidOperationException($"The entity token {entityType} is missing a public static Deserialize method taking a string as parameter and returning an {typeof(EntityToken)}"); } @@ -104,12 +102,12 @@ public static EntityToken Deserialize(string serialziedEntityToken, bool include } catch (Exception ex) { - throw new EntityTokenSerializerException("Failed to deserialize entity token '{0}'".FormatWith(entityTokenString), ex); + throw new EntityTokenSerializerException($"Failed to deserialize entity token '{entityTokenString}'", ex); } if (entityToken == null) { - throw new EntityTokenSerializerException("Deserialization function returned null value. EntityToken: '{0}'".FormatWith(entityTokenString)); + throw new EntityTokenSerializerException($"Deserialization function returned null value. EntityToken: '{entityTokenString}'"); } return entityToken; @@ -118,10 +116,10 @@ public static EntityToken Deserialize(string serialziedEntityToken, bool include /// - public static T Deserialize(string serialziedEntityToken) + public static T Deserialize(string serializedEntityToken) where T : EntityToken { - return (T)Deserialize(serialziedEntityToken); + return (T)Deserialize(serializedEntityToken); } } } diff --git a/Composite/Core/Extensions/IQueryableExtensionMethods.cs b/Composite/Core/Extensions/IQueryableExtensionMethods.cs index d0d2831864..fd9941fdba 100644 --- a/Composite/Core/Extensions/IQueryableExtensionMethods.cs +++ b/Composite/Core/Extensions/IQueryableExtensionMethods.cs @@ -167,18 +167,18 @@ private static IOrderedQueryable ApplyOrder(IQueryable source, Type type, string Verify.IsNotNull(type, "type cannot be null"); string[] props = property.Split('.'); - Type paramenetType = type; - ParameterExpression arg = Expression.Parameter(paramenetType, "x"); + Type parameterType = type; + ParameterExpression arg = Expression.Parameter(parameterType, "x"); Expression expr = arg; foreach (string prop in props) { // use reflection (not ComponentModel) to mirror LINQ - PropertyInfo pi = paramenetType.GetPropertiesRecursively(f=>f.Name == prop).FirstOrDefault(); + PropertyInfo pi = parameterType.GetPropertiesRecursively(f=>f.Name == prop).FirstOrDefault(); Verify.IsNotNull(pi, "Could not find property '{0}' on type '{1}'", property, type); expr = Expression.Property(expr, pi); - paramenetType = pi.PropertyType; + parameterType = pi.PropertyType; } - Type delegateType = typeof(Func<,>).MakeGenericType(type, paramenetType); + Type delegateType = typeof(Func<,>).MakeGenericType(type, parameterType); LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); object result = typeof(Queryable).GetMethods().Single( @@ -186,99 +186,9 @@ private static IOrderedQueryable ApplyOrder(IQueryable source, Type type, string && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2) - .MakeGenericMethod(type, paramenetType) + .MakeGenericMethod(type, parameterType) .Invoke(null, new object[] { source, lambda }); return (IOrderedQueryable)result; } - - - - #region Obsolete - - //public static IQueryable TakeRandom(this IQueryable source, int elementsToTake) where T : class, IData - //{ - // Verify.ArgumentCondition(elementsToTake > 0 && elementsToTake <= 25, "elementsToTake", - // "Value should be between 1 and 25."); - - // int totalElementCount = source.Count(); - - // if (totalElementCount == 0) - // { - // return new T[0].AsQueryable(); - // } - - // if (totalElementCount < elementsToTake) - // { - // elementsToTake = totalElementCount; - // } - - - // var subqueries = new IQueryable[elementsToTake]; - - // int position = 0; - // foreach (int nextIndex in GetUniqueRandomSequence(0, totalElementCount - 1, elementsToTake)) - // { - // subqueries[position++] = source.Skip(nextIndex).Take(1); - // } - - // // Merging subqueries into a binary tree - // int queryCount = elementsToTake; - // while (queryCount > 1) - // { - // for (int i = 0; i < (queryCount + 1) / 2; i++) - // { - // subqueries[i] = (i * 2 < queryCount - 1) - // ? subqueries[i * 2].Concat(subqueries[i * 2 + 1]) - // : subqueries[i * 2]; - // } - // queryCount = (queryCount + 1) / 2; - // } - - // return subqueries[0]; - //} - - //private static IEnumerable GetUniqueRandomSequence(int minValue, int maxValue, int count) - //{ - // int range = maxValue - minValue + 1; - - // if (count > range) throw new InvalidOperationException("'count' exceed number of possible unique random values"); - - // var random = new Random(); - - // if((double)count / range >= 0.3) - // { - // var values = new int[range]; - // for(int i=0; i usedNumbers = new List(count); - // while (usedNumbers.Count < count) - // { - // int randomInt = random.Next(minValue, maxValue); - // if (usedNumbers.Contains(randomInt) == false) - // { - // usedNumbers.Add(randomInt); - // yield return randomInt; - // } - // } - //} - - #endregion Obsolete } } diff --git a/Composite/Data/DataEntityToken.cs b/Composite/Data/DataEntityToken.cs index 8d3aaa69af..a5745e0049 100644 --- a/Composite/Data/DataEntityToken.cs +++ b/Composite/Data/DataEntityToken.cs @@ -1,4 +1,4 @@ -using System; +ï»żusing System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -146,7 +146,11 @@ public IData Data { try { - DataSourceId dataSourceId = DataSourceId.Deserialize(this.SerializedDataSourceId); + DataSourceId dataSourceId; + if (!DataSourceId.TryDeserialize(this.SerializedDataSourceId, out dataSourceId)) + { + return null; + } _data = DataFacade.GetDataFromDataSourceId(dataSourceId); } From a48cdacb80731dc976a380bd9e09a2fba5609a26 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 29 Mar 2017 11:45:06 +0200 Subject: [PATCH 099/135] MimeTypeInfo - adding GetExtensionFromMimeType() --- Composite/Core/IO/MimeTypeInfo.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Composite/Core/IO/MimeTypeInfo.cs b/Composite/Core/IO/MimeTypeInfo.cs index b7a68a9e7a..3a31e36b22 100644 --- a/Composite/Core/IO/MimeTypeInfo.cs +++ b/Composite/Core/IO/MimeTypeInfo.cs @@ -26,7 +26,8 @@ public static class MimeTypeInfo private static readonly IDictionary _toCanonical = new Dictionary(); private static readonly IDictionary _extensionToCanonical = new Dictionary(); private static readonly IDictionary _mimeTypeToResourceName = new Dictionary(); - private static readonly ConcurrentDictionary _iisServableExtensions = new ConcurrentDictionary(); + private static readonly IDictionary _mimeTypeToExtension = new Dictionary(); + private static readonly ConcurrentDictionary _iisServeableExtensions = new ConcurrentDictionary(); private static List _textMimeTypes = new List { MimeTypeInfo.Css, MimeTypeInfo.Js, MimeTypeInfo.Xml, MimeTypeInfo.Text, MimeTypeInfo.Html, MimeTypeInfo.Sass, @@ -251,7 +252,9 @@ private static void RegisterMimeType(string canonicalMimeTypeName, string[] exte private static bool AddExtensionMapping(string extension, string mimeType) { - if(!_extensionToCanonical.ContainsKey(extension)) + _mimeTypeToExtension[mimeType] = extension; + + if (!_extensionToCanonical.ContainsKey(extension)) { _extensionToCanonical.Add(extension, mimeType); return true; @@ -339,6 +342,12 @@ public static ResourceHandle GetResourceHandleFromMimeType(string mimeType) } + /// + public static string GetExtensionFromMimeType(string mimeType) + { + return _mimeTypeToExtension.TryGetValue(mimeType, out string extension) ? extension : null; + } + /// public static string GetCanonicalFromExtension(string extension) @@ -433,7 +442,7 @@ internal static bool IsIisServeable(string extension) extension = extension.Substring(1); } - return _iisServableExtensions.GetOrAdd(extension, ext => + return _iisServeableExtensions.GetOrAdd(extension, ext => { string mimeType = GetCanonicalFromExtension(extension); return _iisServeableTypes.Contains(mimeType); From efe7f1c566d2ccaac789cb6787e8b1b4f5ee31b7 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 29 Mar 2017 13:29:53 +0200 Subject: [PATCH 100/135] SearchDocumentBuilder - not logging ThreadAbortExceptions --- Composite/Search/Crawling/SearchDocumentBuilder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Composite/Search/Crawling/SearchDocumentBuilder.cs b/Composite/Search/Crawling/SearchDocumentBuilder.cs index e6908a2a1d..5fd5087355 100644 --- a/Composite/Search/Crawling/SearchDocumentBuilder.cs +++ b/Composite/Search/Crawling/SearchDocumentBuilder.cs @@ -1,6 +1,7 @@ ï»żusing System; using System.Collections.Generic; using System.Linq; +using System.Threading; using Composite.C1Console.Security; using Composite.Core; using Composite.Core.Extensions; @@ -155,6 +156,7 @@ public void CrawlData(IData data, bool skipInheritedInterfaces = false) e.Populate(this, data); } catch (Exception ex) + when (!(ex is ThreadAbortException)) { Log.LogError(nameof(SearchDocumentBuilder), ex); } From c292357ba0e4e81af1e330cc73e9c7ebc53b03d9 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 29 Mar 2017 16:17:34 +0200 Subject: [PATCH 101/135] Fixing all .NET Standard dll-s being copied into the Website/Bin folder on compilation --- Composite/Composite.csproj | 4 ---- Composite/packages.config | 1 - Website/WebSite.csproj | 9 +++++---- Website/packages.config | 3 ++- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 28fc7f7fe7..c486cd13e8 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -161,10 +161,6 @@ 3.5 - - ..\packages\System.Threading.Tasks.Dataflow.4.6.0\lib\netstandard1.1\System.Threading.Tasks.Dataflow.dll - True - False diff --git a/Composite/packages.config b/Composite/packages.config index edbfaae680..eb202d024d 100644 --- a/Composite/packages.config +++ b/Composite/packages.config @@ -18,7 +18,6 @@ - diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index da3e9262ee..a9564eead2 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -121,10 +121,6 @@ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll - - False - ..\Composite\bin\Debug\System.Threading.Tasks.Dataflow.dll - @@ -2821,6 +2817,11 @@ copy "$(ProjectDir)\..\Packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll" "$(TargetDir)\System.Xml.ReaderWriter.dll" ) + if not exist "$(TargetDir)\System.Threading.Tasks.Dataflow.dll" ( + copy "$(ProjectDir)\..\Packages\System.Threading.Tasks.Dataflow.4.6.0\lib\netstandard1.1\System.Threading.Tasks.Dataflow.dll" "$(TargetDir)\System.Threading.Tasks.Dataflow.dll" + ) + + cd "$(ProjectDir)" .\node_modules\.bin\jspm install --quick diff --git a/Website/packages.config b/Website/packages.config index ab89ad475e..f907304b2e 100644 --- a/Website/packages.config +++ b/Website/packages.config @@ -11,7 +11,8 @@ - + + From 1bc58dc8c30edfefc904e00aa6532eda2c72657a Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 31 Mar 2017 13:45:44 +0200 Subject: [PATCH 102/135] Search: indexing output of cms functions --- .../Renderings/Page/RenderingReason.cs | 8 +- .../Template/PageTemplateFeatureFunction.cs | 10 +- .../Crawling/DefaultDataFieldProcessor.cs | 11 +- .../Search/Crawling/SearchDocumentBuilder.cs | 29 ++++- .../Search/Crawling/XhtmlCrawlingHelper.cs | 118 +++++++++++++++++- .../DocumentSources/CmsPageDocumentSource.cs | 4 +- 6 files changed, 157 insertions(+), 23 deletions(-) diff --git a/Composite/Core/WebClient/Renderings/Page/RenderingReason.cs b/Composite/Core/WebClient/Renderings/Page/RenderingReason.cs index 14d7a9d18f..93564325e7 100644 --- a/Composite/Core/WebClient/Renderings/Page/RenderingReason.cs +++ b/Composite/Core/WebClient/Renderings/Page/RenderingReason.cs @@ -18,12 +18,16 @@ public enum RenderingReason /// C1ConsoleBrowserPageView = 2, /// - /// A page is reneder from withing an "Edit page" workflow + /// A page is rendered from withing an "Edit page" workflow /// PreviewUnsavedChanges = 4, /// /// A page is rendered to generate an image to be used for function/template visualization /// - ScreenshotGeneration = 8 + ScreenshotGeneration = 8, + /// + /// A page is rendered to build a search index. + /// + BuildSearchIndex = 16 } } diff --git a/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Web/Html/Template/PageTemplateFeatureFunction.cs b/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Web/Html/Template/PageTemplateFeatureFunction.cs index 50d5eb3176..780210f122 100644 --- a/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Web/Html/Template/PageTemplateFeatureFunction.cs +++ b/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Web/Html/Template/PageTemplateFeatureFunction.cs @@ -1,6 +1,5 @@ ï»żusing System.Collections.Generic; -using System.Threading; -using System.Xml.Linq; +using Composite.Core.WebClient.Renderings.Page; using Composite.Core.Xml; using Composite.Functions; using Composite.Plugins.Functions.FunctionProviders.StandardFunctionProvider.Foundation; @@ -24,7 +23,7 @@ protected override IEnumerable StandardFunctio WidgetFunctionProvider featureNameSelector = StandardWidgetFunctions.DropDownList( this.GetType(), - "FeatureNames", + nameof(FeatureNames), false, true); @@ -46,6 +45,11 @@ public static IEnumerable FeatureNames() public override object Execute(ParameterList parameters, FunctionContextContainer context) { + if (PageRenderer.RenderingReason == RenderingReason.BuildSearchIndex) + { + return null; + } + string featureName = parameters.GetParameter("FeatureName"); return PageTemplateFeatureFacade.GetPageTemplateFeature(featureName); diff --git a/Composite/Search/Crawling/DefaultDataFieldProcessor.cs b/Composite/Search/Crawling/DefaultDataFieldProcessor.cs index 4e9d19eb9d..01684f8551 100644 --- a/Composite/Search/Crawling/DefaultDataFieldProcessor.cs +++ b/Composite/Search/Crawling/DefaultDataFieldProcessor.cs @@ -19,17 +19,10 @@ public class DefaultDataFieldProcessor: IDataFieldProcessor /// public virtual IEnumerable GetTextParts(object value) { - var text = value as string; - if (text == null) return null; - - if (text.StartsWith(" diff --git a/Composite/Search/Crawling/SearchDocumentBuilder.cs b/Composite/Search/Crawling/SearchDocumentBuilder.cs index 5fd5087355..13e35391bb 100644 --- a/Composite/Search/Crawling/SearchDocumentBuilder.cs +++ b/Composite/Search/Crawling/SearchDocumentBuilder.cs @@ -7,7 +7,7 @@ using Composite.Core.Extensions; using Composite.Core.Linq; using Composite.Data; - +using Composite.Data.Types; using Texts = Composite.Core.ResourceSystem.LocalizationFiles.Composite_Search; namespace Composite.Search.Crawling @@ -23,6 +23,8 @@ public class SearchDocumentBuilder private readonly IEnumerable _extensions; + private IPage _currentPage; + /// /// Creates a new instance of . /// @@ -98,6 +100,11 @@ public void CrawlData(IData data, bool skipInheritedInterfaces = false) var interfaceType = data.DataSourceId.InterfaceType; var fields = DataTypeSearchReflectionHelper.GetSearchableFields(interfaceType); + if (data is IPage page) + { + _currentPage = page; + } + foreach (var field in fields) { var propertyInfo = field.Key; @@ -120,7 +127,7 @@ public void CrawlData(IData data, bool skipInheritedInterfaces = false) var textParts = fieldProcessor.GetTextParts(value); if (textParts != null) { - _textParts.AddRange(textParts); + _textParts.AddRange(textParts.SelectMany(ProcessXhtml)); } } @@ -316,6 +323,24 @@ public static IEnumerable GetDefaultDocumentFields() }; } + private IEnumerable ProcessXhtml(string textFragment) + { + if (textFragment.StartsWith(" _textParts = new List(); public IEnumerable TextParts => _textParts; + private IPage _page; + + public void SetPageContext(IPage page) + { + _page = page; + } + /// /// Crawls xhtml content and extracts text parts /// @@ -23,7 +41,7 @@ public bool CrawlXhtml(string xhtml) try { var doc = XhtmlDocument.Parse(xhtml); - ProcessNode(doc.Body); + CrawlXhtml(doc); return true; } @@ -34,17 +52,19 @@ public bool CrawlXhtml(string xhtml) } } + private void CrawlXhtml(XhtmlDocument document) => ProcessNode(document.Body); + private void ProcessNode(XNode node) { - if (node is XText) + if (node is XText textNode) { - _textParts.Add(((XText)node).Value); + _textParts.Add(textNode.Value); return; } - if (node is XElement) + if (node is XElement element) { - ProcessElement((XElement)node); + ProcessElement(element); } } @@ -102,6 +122,94 @@ private void ProcessFunctionCall(XElement functionNode) // TODO: handle the other parameter types } } + + var returnType = function.ReturnType; + if (returnType == typeof(XhtmlDocument) + || function.ReturnType == typeof(string)) + { + var functionResult = TryExecuteFunction(functionNode, FunctionExecutionTimeout); + if (functionResult is XhtmlDocument document) + { + CrawlXhtml(document); + } + + if (functionResult is string str) + { + if (str.TrimStart().StartsWith(" result = TryExecuteFunction(functionNode), cts.Token); + executeTask.Wait(timeoutMs); + + if(executeTask.Status == TaskStatus.Running) + { + cts.Cancel(); + }; + + return result; + } + + + private object TryExecuteFunction(XElement functionNode) + { + try + { + var tree = FunctionFacade.BuildTree(functionNode); + + using (new FakeHttpContext()) + { + if (_page != null) + { + PageRenderer.CurrentPage = _page; + C1PageRoute.PageUrlData = new PageUrlData(_page); + } + PageRenderer.RenderingReason = RenderingReason.BuildSearchIndex; + + return tree.GetValue(new FunctionContextContainer + { + SuppressXhtmlExceptions = false + }); + } + } + catch (Exception) + { + return null; + } + } + + private class FakeHttpContext : IDisposable + { + private readonly HttpContext _originalContext; + + public FakeHttpContext() + { + _originalContext = HttpContext.Current; + + HttpContext.Current = new HttpContext( + new HttpRequest("", "http://contoso.com", ""), + new HttpResponse(new StringWriter()) + ); + } + + public void Dispose() + { + HttpContext.Current = _originalContext; + } } } } diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index 13e56955de..6f730a93d7 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -151,6 +151,8 @@ private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary< var docBuilder = new SearchDocumentBuilder(_docBuilderExtensions); docBuilder.SetDataType(typeof(IPage)); + docBuilder.CrawlData(page); + using (new DataConnection(page.DataSourceId.PublicationScope, page.DataSourceId.LocaleScope)) { if (isPublished) @@ -182,8 +184,6 @@ private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary< } } - docBuilder.CrawlData(page); - return docBuilder.BuildDocument(Name, documentId, label, null, entityToken); } From 9e96867eff035c456b40f093cb51c7a707d5a436 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 31 Mar 2017 15:31:30 +0200 Subject: [PATCH 103/135] Search: indexing ancestor entity tokens --- .../Crawling/DefaultDocumentFieldNames.cs | 5 +++ .../Crawling/EntityTokenSecurityHelper.cs | 7 ++-- .../Search/Crawling/SearchDocumentBuilder.cs | 36 +++++++++++++++++-- Composite/Search/SearchQuery.cs | 18 ++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs b/Composite/Search/Crawling/DefaultDocumentFieldNames.cs index 8003b1a239..8239d06f9c 100644 --- a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs +++ b/Composite/Search/Crawling/DefaultDocumentFieldNames.cs @@ -32,6 +32,11 @@ public static class DefaultDocumentFieldNames /// public static readonly string ConsoleAccess = "access"; + /// + /// The name of the facet field that contains the hashes of all ancestor's and current entity tokens. + /// + public static readonly string Ancestors = "ancestors"; + /// /// The name of the boolean facet field that indicates whether the document has a url. /// diff --git a/Composite/Search/Crawling/EntityTokenSecurityHelper.cs b/Composite/Search/Crawling/EntityTokenSecurityHelper.cs index 626acd40c9..f7d60af57b 100644 --- a/Composite/Search/Crawling/EntityTokenSecurityHelper.cs +++ b/Composite/Search/Crawling/EntityTokenSecurityHelper.cs @@ -38,11 +38,13 @@ class GroupAccess private static Dictionary> _allUserGroupAccessDefinitions; public static void GetUsersAndGroupsWithReadAccess(EntityToken entityToken, + out IEnumerable ancestors, out IEnumerable users, out IEnumerable userGroups) { var userSet = new HashSet(); var userGroupSet = new HashSet(); + var ancestorsSet = new HashSet(); using (ThreadDataManager.EnsureInitialize()) { @@ -51,11 +53,12 @@ public static void GetUsersAndGroupsWithReadAccess(EntityToken entityToken, ImmutableHashSet.Empty, ImmutableHashSet.Empty, userSet, - userGroupSet, - new HashSet(), + userGroupSet, + ancestorsSet, 20); } + ancestors = ancestorsSet; users = userSet; userGroups = userGroupSet; } diff --git a/Composite/Search/Crawling/SearchDocumentBuilder.cs b/Composite/Search/Crawling/SearchDocumentBuilder.cs index 13e35391bb..c584ec1b9e 100644 --- a/Composite/Search/Crawling/SearchDocumentBuilder.cs +++ b/Composite/Search/Crawling/SearchDocumentBuilder.cs @@ -1,11 +1,14 @@ ï»żusing System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; +using System.Text; using System.Threading; using Composite.C1Console.Security; using Composite.Core; using Composite.Core.Extensions; using Composite.Core.Linq; +using Composite.Core.WebClient; using Composite.Data; using Composite.Data.Types; using Texts = Composite.Core.ResourceSystem.LocalizationFiles.Composite_Search; @@ -25,6 +28,8 @@ public class SearchDocumentBuilder private IPage _currentPage; + private static readonly MD5 HashingAlgorithm = MD5.Create(); + /// /// Creates a new instance of . /// @@ -230,9 +235,10 @@ public SearchDocument BuildDocument( private void AddAccessField(EntityToken entityToken) { + IEnumerable ancestors; IEnumerable users; IEnumerable groups; - EntityTokenSecurityHelper.GetUsersAndGroupsWithReadAccess(entityToken, out users, out groups); + EntityTokenSecurityHelper.GetUsersAndGroupsWithReadAccess(entityToken, out ancestors, out users, out groups); var tokens = users.Concat(groups.Select(g => g.ToString())).ToArray(); @@ -242,8 +248,24 @@ private void AddAccessField(EntityToken entityToken) DefaultDocumentFieldNames.ConsoleAccess, tokens)); } + + if (ancestors.Any()) + { + var ancestorTokens = ancestors.Select(GetEntityTokenHash).ToArray(); + + _facetFieldValues.Add(new KeyValuePair( + DefaultDocumentFieldNames.Ancestors, + ancestorTokens)); + } } + internal static string GetEntityTokenHash(EntityToken entityToken) + { + var entityTokenString = EntityTokenSerializer.Serialize(entityToken); + var bytes = Encoding.UTF8.GetBytes(entityTokenString); + + return UrlUtils.CompressGuid(new Guid(HashingAlgorithm.ComputeHash(bytes))); + } /// /// Gets the list of default document fields @@ -313,7 +335,17 @@ public static IEnumerable GetDefaultDocumentFields() new DocumentFieldFacet { FacetType = FacetType.MultipleValues, - PreviewFunction = value => value, + MinHitCount = 1 + }, + null) + { + Label = null + }, + new DocumentField( + DefaultDocumentFieldNames.Ancestors, + new DocumentFieldFacet + { + FacetType = FacetType.MultipleValues, MinHitCount = 1 }, null) diff --git a/Composite/Search/SearchQuery.cs b/Composite/Search/SearchQuery.cs index b32689ae5b..c8ddd7e328 100644 --- a/Composite/Search/SearchQuery.cs +++ b/Composite/Search/SearchQuery.cs @@ -131,6 +131,24 @@ public void ShowOnlyDocumentsWithUrls() } + /// + /// Filters the results, so only entity tokens that have at least one of the given entity tokens + /// as an ancestor, will be returned. This enables searching for the child elements in the console + /// and searching for data that belongs to a specific website on frontend. + /// + public void FilterByAncestors(params EntityToken[] entityTokens) + { + Selection.Add(new SearchQuerySelection + { + FieldName = DefaultDocumentFieldNames.Ancestors, + Operation = SearchQuerySelectionOperation.Or, + Values = entityTokens.Select(SearchDocumentBuilder.GetEntityTokenHash).ToArray() + }); + + AddDefaultFieldFacet(DefaultDocumentFieldNames.Ancestors); + } + + /// /// Filtering search results to which the given user does not have read access permission. /// From a2d360efcaec06c51c73021ecd4b7fedb95214bc Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 31 Mar 2017 16:15:31 +0200 Subject: [PATCH 104/135] Search: indexing "Last Updated/Update By" fields instead of "Creation Date/Created By" --- .../Core/ResourceSystem/LocalizationFiles.cs | 20 +++++++++---------- .../Core/ResourceSystem/LocalizationFiles.tt | 2 ++ Composite/Data/IChangeHistory.cs | 4 +++- Composite/Data/ICreationHistory.cs | 2 -- .../Crawling/DefaultDataFieldProcessor.cs | 8 ++++---- .../Crawling/DefaultDocumentFieldNames.cs | 2 +- .../localization/Composite.Search.en-us.xml | 4 ++-- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Composite/Core/ResourceSystem/LocalizationFiles.cs b/Composite/Core/ResourceSystem/LocalizationFiles.cs index 626b5fbd69..b5c02771af 100644 --- a/Composite/Core/ResourceSystem/LocalizationFiles.cs +++ b/Composite/Core/ResourceSystem/LocalizationFiles.cs @@ -6660,13 +6660,13 @@ public static class Composite_Search { public static string FieldNames_Description=>T("FieldNames.Description"); ///"Data Type" public static string FieldNames_DataType=>T("FieldNames.DataType"); -///"Creation Date" -public static string FieldNames_CreationDate=>T("FieldNames.CreationDate"); -///"Created By" -public static string FieldNames_CreatedBy=>T("FieldNames.CreatedBy"); +///"Last Updated" +public static string FieldNames_LastUpdated=>T("FieldNames.LastUpdated"); +///"Updated By" +public static string FieldNames_UpdatedBy=>T("FieldNames.UpdatedBy"); ///"Publication Status" public static string FieldNames_PublicationStatus=>T("FieldNames.PublicationStatus"); -///"MIME Type" +///"Media Type" public static string FieldNames_MimeType=>T("FieldNames.MimeType"); private static string T(string key) => StringResourceSystemFacade.GetString("Composite.Search", key); /// @@ -6691,13 +6691,13 @@ public static class Untranslated { public const string FieldNames_Description="${Composite.Search,FieldNames.Description}"; ///"Data Type" public const string FieldNames_DataType="${Composite.Search,FieldNames.DataType}"; -///"Creation Date" -public const string FieldNames_CreationDate="${Composite.Search,FieldNames.CreationDate}"; -///"Created By" -public const string FieldNames_CreatedBy="${Composite.Search,FieldNames.CreatedBy}"; +///"Last Updated" +public const string FieldNames_LastUpdated="${Composite.Search,FieldNames.LastUpdated}"; +///"Updated By" +public const string FieldNames_UpdatedBy="${Composite.Search,FieldNames.UpdatedBy}"; ///"Publication Status" public const string FieldNames_PublicationStatus="${Composite.Search,FieldNames.PublicationStatus}"; -///"MIME Type" +///"Media Type" public const string FieldNames_MimeType="${Composite.Search,FieldNames.MimeType}"; }} diff --git a/Composite/Core/ResourceSystem/LocalizationFiles.tt b/Composite/Core/ResourceSystem/LocalizationFiles.tt index 264060ec77..2877c4741f 100644 --- a/Composite/Core/ResourceSystem/LocalizationFiles.tt +++ b/Composite/Core/ResourceSystem/LocalizationFiles.tt @@ -53,6 +53,8 @@ namespace Composite.Core.ResourceSystem string className = fileIdentifier; + if(className == "MimeTypes") continue; + /* propertyDefinitions.Append(@" /// diff --git a/Composite/Data/IChangeHistory.cs b/Composite/Data/IChangeHistory.cs index 932540cf76..2247f931aa 100644 --- a/Composite/Data/IChangeHistory.cs +++ b/Composite/Data/IChangeHistory.cs @@ -11,8 +11,9 @@ public interface IChangeHistory: IData /// [StoreFieldType(PhysicalStoreFieldType.DateTime)] [ImmutableFieldId("{59E10FE8-EC55-4b10-B17A-FDE3EB4690F0}")] - [DefaultFieldNowDateTimeValue()] + [DefaultFieldNowDateTimeValue] [FieldPosition(502)] + [SearchableField(false, true, true)] DateTime ChangeDate { get; set; } @@ -21,6 +22,7 @@ public interface IChangeHistory: IData [ImmutableFieldId("{617E34B5-E035-4107-9109-DB0B33078B2A}")] [DefaultFieldStringValue("")] [FieldPosition(503)] + [SearchableField(false, true, true)] string ChangedBy { get; set; } } } diff --git a/Composite/Data/ICreationHistory.cs b/Composite/Data/ICreationHistory.cs index 85045d98fe..d8559b149a 100644 --- a/Composite/Data/ICreationHistory.cs +++ b/Composite/Data/ICreationHistory.cs @@ -14,7 +14,6 @@ public interface ICreationHistory: IData [DefaultFieldNowDateTimeValue()] [FunctionBasedNewInstanceDefaultFieldValue("")] [FieldPosition(502)] - [SearchableField(false, true, true)] DateTime CreationDate { get; set; } @@ -23,7 +22,6 @@ public interface ICreationHistory: IData [ImmutableFieldId("{617E34B5-E035-4107-9109-DB0B33078B2B}")] [DefaultFieldStringValue("")] [FieldPosition(503)] - [SearchableField(false, true, true)] string CreatedBy { get; set; } } } diff --git a/Composite/Search/Crawling/DefaultDataFieldProcessor.cs b/Composite/Search/Crawling/DefaultDataFieldProcessor.cs index 01684f8551..206d2546cd 100644 --- a/Composite/Search/Crawling/DefaultDataFieldProcessor.cs +++ b/Composite/Search/Crawling/DefaultDataFieldProcessor.cs @@ -49,10 +49,10 @@ public virtual string GetDocumentFieldName(PropertyInfo pi) return DefaultDocumentFieldNames.Description; } - if ((pi.Name == nameof(ICreationHistory.CreationDate) || pi.Name == nameof(IMediaFile.CreationTime)) + if ((pi.Name == nameof(IChangeHistory.ChangeDate) || pi.Name == nameof(IMediaFile.CreationTime)) && (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))) { - return DefaultDocumentFieldNames.CreationTime; + return DefaultDocumentFieldNames.LastUpdated; } return $"{pi.ReflectedType.Name}.{pi.Name}"; @@ -130,8 +130,8 @@ public virtual string GetFieldLabel(PropertyInfo propertyInfo) return Texts.FieldNames_Description; } - if (fieldName == DefaultDocumentFieldNames.CreationTime) return Texts.FieldNames_CreationDate; - if (propertyInfo.Name == nameof(ICreationHistory.CreatedBy)) return Texts.FieldNames_CreatedBy; + if (fieldName == DefaultDocumentFieldNames.LastUpdated) return Texts.FieldNames_LastUpdated; + if (propertyInfo.Name == nameof(IChangeHistory.ChangedBy)) return Texts.FieldNames_UpdatedBy; if (propertyInfo.Name == nameof(IMediaFile.MimeType)) return Texts.FieldNames_MimeType; var frpAttribute = propertyInfo.GetCustomAttribute(); diff --git a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs b/Composite/Search/Crawling/DefaultDocumentFieldNames.cs index 8239d06f9c..2d2bed915c 100644 --- a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs +++ b/Composite/Search/Crawling/DefaultDocumentFieldNames.cs @@ -45,6 +45,6 @@ public static class DefaultDocumentFieldNames /// /// The name of the creation time field. /// - public static readonly string CreationTime = "ctime"; + public static readonly string LastUpdated = "lastupdated"; } } diff --git a/Website/Composite/localization/Composite.Search.en-us.xml b/Website/Composite/localization/Composite.Search.en-us.xml index 46f1ca51f8..d1c210bec2 100644 --- a/Website/Composite/localization/Composite.Search.en-us.xml +++ b/Website/Composite/localization/Composite.Search.en-us.xml @@ -13,8 +13,8 @@ - - + + From 6b520e1c5657efafdc1b87cb9716a6582fa65064 Mon Sep 17 00:00:00 2001 From: Inna Boitsun Date: Tue, 4 Apr 2017 17:50:14 +0300 Subject: [PATCH 105/135] Fix company logo in startup screeen when site running in subfolder --- Website/Composite/content/branding/company-logo.inc | 2 +- Website/WebSite.csproj | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Website/Composite/content/branding/company-logo.inc b/Website/Composite/content/branding/company-logo.inc index 4502dcc87a..15ad58ad68 100644 --- a/Website/Composite/content/branding/company-logo.inc +++ b/Website/Composite/content/branding/company-logo.inc @@ -1,3 +1,3 @@
- logo + logo
\ No newline at end of file diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index a9564eead2..5d585ca763 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -254,6 +254,8 @@ Designer + + Designer From a282ca112746698e69adc808d3917a7940c6a19a Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 10 Apr 2017 10:29:42 +0200 Subject: [PATCH 106/135] Using spaces in ashx, asmx, asax files --- .editorconfig | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.editorconfig b/.editorconfig index 1f30264cb2..96c1832006 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,15 +1,15 @@ -# EditorConfig is awesome: http://EditorConfig.org - -root = true - -[*] -indent_style = tab -charset = utf-8 -trim_trailing_whitespace = true - -[*.cs] -indent_style = space -indent_size = 4 - -[*.md] +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +indent_style = tab +charset = utf-8 +trim_trailing_whitespace = true + +[*.{cs,asmx,ashx,asax}] +indent_style = space +indent_size = 4 + +[*.md] trim_trailing_whitespace = false \ No newline at end of file From b3e2fe5ee09ae037bf46aac55e990794411c883b Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 10 Apr 2017 15:56:54 +0200 Subject: [PATCH 107/135] Fixing a LINQ exception when deleting page meta data via API with Version Publication package installed --- Composite/Data/DataFacade.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Composite/Data/DataFacade.cs b/Composite/Data/DataFacade.cs index 67b5691d32..4af13480df 100644 --- a/Composite/Data/DataFacade.cs +++ b/Composite/Data/DataFacade.cs @@ -659,29 +659,27 @@ public static IData TryGetDataByUniqueKey(Type interfaceType, DataKeyPropertyCol /// public static IEnumerable TryGetDataVersionsByUniqueKey(Type interfaceType, DataKeyPropertyCollection dataKeyPropertyCollection) { - if (interfaceType == null) throw new ArgumentNullException("interfaceType"); - if (dataKeyPropertyCollection == null) throw new ArgumentNullException("dataKeyPropertyCollection"); + Verify.ArgumentNotNull(interfaceType, nameof(interfaceType)); + Verify.ArgumentNotNull(dataKeyPropertyCollection, nameof(dataKeyPropertyCollection)); LambdaExpression lambdaExpression = GetPredicateExpressionByUniqueKey(interfaceType, dataKeyPropertyCollection); MethodInfo methodInfo = GetGetDataWithPredicatMethodInfo(interfaceType); - IQueryable queryable = (IQueryable)methodInfo.Invoke(null, new object[] { lambdaExpression }); - - var datas = queryable.OfType(); + var queryable = (IQueryable)methodInfo.Invoke(null, new object[] { lambdaExpression }); - return datas; + return ((IEnumerable) queryable).Cast(); } // Overload /// public static IData GetDataByUniqueKey(Type interfaceType, object dataKeyValue) { - Verify.ArgumentNotNull(interfaceType, "interfaceType"); + Verify.ArgumentNotNull(interfaceType, nameof(interfaceType)); - PropertyInfo propertyInfo = DataAttributeFacade.GetKeyProperties(interfaceType).Single(); + PropertyInfo propertyInfo = interfaceType.GetKeyProperties().Single(); - DataKeyPropertyCollection dataKeyPropertyCollection = new DataKeyPropertyCollection(); + var dataKeyPropertyCollection = new DataKeyPropertyCollection(); dataKeyPropertyCollection.AddKeyProperty(propertyInfo, dataKeyValue); IData data = TryGetDataByUniqueKey(interfaceType, dataKeyPropertyCollection); From 4d2c361b34f167a5f0ac6d3da0ab214a67a696c5 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 11 Apr 2017 13:55:41 +0200 Subject: [PATCH 108/135] Fixing "List Unpublished Pages" not showing pages when there's a search perspective installed. --- Website/Composite/services/Tree/TreeServices.asmx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Website/Composite/services/Tree/TreeServices.asmx b/Website/Composite/services/Tree/TreeServices.asmx index 459f2214f2..73169c5b6a 100644 --- a/Website/Composite/services/Tree/TreeServices.asmx +++ b/Website/Composite/services/Tree/TreeServices.asmx @@ -88,7 +88,9 @@ namespace Composite.Services [WebMethod] public List GetUnpublishedElements(string dummy) { - var rootElement = ElementFacade.GetPerspectiveElements(false).First(); + var rootElement = ElementFacade.GetPerspectiveElements(false) + .FirstOrDefault(e => e.TagValue == "Content"); + var allElements = GetPublishControlledDescendants(rootElement.ElementHandle); var publicationStates = new Dictionary From e3d7901e5242a374351050977042ca698b1f3b32 Mon Sep 17 00:00:00 2001 From: neexite Date: Tue, 11 Apr 2017 15:45:05 +0300 Subject: [PATCH 109/135] Fix #427 [Console] User input can be reverted by the UpdateManager.js when there's a slow internet connection and multiple form elements --- .../Composite/scripts/source/page/updates/UpdateAssistant.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Website/Composite/scripts/source/page/updates/UpdateAssistant.js b/Website/Composite/scripts/source/page/updates/UpdateAssistant.js index 377b0c2a54..d183908276 100644 --- a/Website/Composite/scripts/source/page/updates/UpdateAssistant.js +++ b/Website/Composite/scripts/source/page/updates/UpdateAssistant.js @@ -154,9 +154,11 @@ _UpdateAssistant.prototype = { var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Msxml2.XMLHTTP.3.0"); if (request != null) { + Application.lock(target); request.open(method, target, (handler != null ? true : false)); if (handler != null) { function action() { + Application.unlock(target); if (request.readyState == 4) { var errorType = request.getResponseHeader("X-Error-Type"); // Handle error From 87780ae50e233352ea4278366342b5c8cfef2274 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 11 Apr 2017 14:17:50 +0200 Subject: [PATCH 110/135] VersionedDataHelperContract - extending with the Order() method --- Composite/Composite.csproj | 2 +- ...lper.cs => VersionedDataHelperContract.cs} | 66 ++++++++++++++----- .../PageElementProvider.cs | 6 +- .../ViewUnpublishedItems.aspx.cs | 2 +- 4 files changed, 54 insertions(+), 22 deletions(-) rename Composite/Data/Types/{IVersionedDataHelper.cs => VersionedDataHelperContract.cs} (61%) diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index c486cd13e8..c66ae41f21 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -251,6 +251,7 @@ + @@ -309,7 +310,6 @@ - diff --git a/Composite/Data/Types/IVersionedDataHelper.cs b/Composite/Data/Types/VersionedDataHelperContract.cs similarity index 61% rename from Composite/Data/Types/IVersionedDataHelper.cs rename to Composite/Data/Types/VersionedDataHelperContract.cs index 6cb42f691d..6255d76bad 100644 --- a/Composite/Data/Types/IVersionedDataHelper.cs +++ b/Composite/Data/Types/VersionedDataHelperContract.cs @@ -29,6 +29,16 @@ public abstract class VersionedDataHelperContract ///
public abstract List GetExtraProperties(T data) where T : IVersioned; + /// + /// Orders the selected data. + /// + /// + /// + /// + public virtual IEnumerable Order(IEnumerable dataset) where T : IVersioned + { + return dataset; + } } /// @@ -36,7 +46,7 @@ public abstract class VersionedDataHelperContract /// public static class VersionedDataHelper { - private static List _instances; + private static readonly List _services = new List(); static VersionedDataHelper() { @@ -58,19 +68,14 @@ internal static void Initialize() /// /// Returns if there are any versioning package instances available /// - public static bool IsThereAnyVersioningServices => _instances!=null && _instances.Count > 0; + public static bool IsThereAnyVersioningServices => _services.Any(); /// /// Registers instances of versioning packages /// public static void RegisterVersionHelper(VersionedDataHelperContract vpc) { - if (_instances == null) - { - _instances = new List(); - } - - _instances.Add(vpc); + _services.Add(vpc); } /// @@ -81,45 +86,70 @@ public static string LocalizedVersionName(this T str) where T : IVersioned var defaultVersionName = Core.ResourceSystem.LocalizationFiles.Composite_Management.DefaultVersionName; - if (_instances == null) + if (_services.Count == 0) { return defaultVersionName; } - return _instances.Select(p => p.LocalizedVersionName(str)).Any(name => name != null)? - string.Join(",", _instances.Select(p => p.LocalizedVersionName(str)).Where(name => name != null)): defaultVersionName; + var versionNames = _services + .Select(p => p.LocalizedVersionName(str)) + .Where(name => name != null).ToList(); + + return versionNames.Any() ? string.Join(",", versionNames) : defaultVersionName; } /// /// Returns column name and tooltip for the extra fields in publication overview /// - public static List GetExtraPropertiesNames() + public static IEnumerable GetExtraPropertyNames() { - return _instances?.SelectMany(p => p.GetExtraPropertiesNames() ?? new List()).ToList(); + return _services?.SelectMany(p => p.GetExtraPropertiesNames() ?? Enumerable.Empty()).ToList(); } /// /// Returns values for the extra fields in publication overview /// - public static List GetExtraProperties(this T str) where T : IVersioned + public static IEnumerable GetExtraProperties(this T str) where T : IVersioned { - return _instances?.SelectMany(p => p.GetExtraProperties(str) ?? new List()).ToList(); + return _services.SelectMany(p => p.GetExtraProperties(str) ?? Enumerable.Empty()).ToList(); } /// /// Returns currently live version name for the IVersioned data /// - public static string GetLiveVersionName(this T str) where T : IVersioned + public static string GetLiveVersionName(this T data) where T : IVersioned { - if (_instances == null) + if (!_services.Any()) { return null; } - var versionNames = _instances.Select(p => p.GetLiveVersionName(str)).Where(name => name != null).ToList(); + var versionNames = _services.Select(p => p.GetLiveVersionName(data)).Where(name => name != null).ToList(); return versionNames.Any() ? string.Join(",", versionNames) : null; } + + /// + /// Orders the data given in the dataset. + /// + /// The data type. + /// The data set to be ordered. + /// + public static IEnumerable OrderByVersions(this IEnumerable dataset) where TDataType : IVersioned + { + if (dataset is ICollection collection && collection.Count < 2) + { + return collection; + } + + var result = dataset; + foreach (var service in _services) + { + result = service.Order(result); + } + + return result; + } } /// diff --git a/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs b/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs index d57505abf1..dc44e7d46d 100644 --- a/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs +++ b/Composite/Plugins/Elements/ElementProviders/PageElementProvider/PageElementProvider.cs @@ -507,8 +507,10 @@ group page by page.Id into pageVersionGroups let versions = pageVersionGroups.ToList() let liveVersionName = versions.Count == 1 ? null : versions[0].GetLiveVersionName() - select pageVersionGroups.OrderByDescending(v => v.LocalizedVersionName() == liveVersionName).ToList()) - .SelectMany(v => v); + select versions + .OrderByVersions() + .OrderByDescending(v => v.LocalizedVersionName() == liveVersionName)) + .SelectMany(v => v); } diff --git a/Website/Composite/content/views/publishworkflowstatus/ViewUnpublishedItems.aspx.cs b/Website/Composite/content/views/publishworkflowstatus/ViewUnpublishedItems.aspx.cs index 7d25a1b311..a991147a4d 100644 --- a/Website/Composite/content/views/publishworkflowstatus/ViewUnpublishedItems.aspx.cs +++ b/Website/Composite/content/views/publishworkflowstatus/ViewUnpublishedItems.aspx.cs @@ -7,7 +7,7 @@ protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { - headerRepeater.DataSource = VersionedDataHelper.GetExtraPropertiesNames(); + headerRepeater.DataSource = VersionedDataHelper.GetExtraPropertyNames(); headerRepeater.DataBind(); } From 04827f348a2dc776d5f8b88bb95eb23ec67d07e9 Mon Sep 17 00:00:00 2001 From: neexite Date: Wed, 12 Apr 2017 12:03:12 +0300 Subject: [PATCH 111/135] Fix #427 updated --- .../Composite/scripts/source/page/updates/UpdateAssistant.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Website/Composite/scripts/source/page/updates/UpdateAssistant.js b/Website/Composite/scripts/source/page/updates/UpdateAssistant.js index d183908276..f17ae7938a 100644 --- a/Website/Composite/scripts/source/page/updates/UpdateAssistant.js +++ b/Website/Composite/scripts/source/page/updates/UpdateAssistant.js @@ -154,11 +154,10 @@ _UpdateAssistant.prototype = { var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Msxml2.XMLHTTP.3.0"); if (request != null) { - Application.lock(target); request.open(method, target, (handler != null ? true : false)); if (handler != null) { + Application.lock(target); function action() { - Application.unlock(target); if (request.readyState == 4) { var errorType = request.getResponseHeader("X-Error-Type"); // Handle error @@ -182,6 +181,7 @@ _UpdateAssistant.prototype = { handler.handleResponse(dom); } } + Application.unlock(target); } } /* From 601e2ab8a5928e74abd647de577555e8515730f5 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 18 Apr 2017 15:46:02 +0200 Subject: [PATCH 112/135] Search - adding "IncludeHighlights" property for the search query --- .../Endpoint/ConsoleSearchRpcService.cs | 6 +++-- Composite/Search/SearchQuery.cs | 5 ++++ Composite/Search/SearchResult.cs | 25 +++++++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs index ba054b5d03..7cc7727f81 100644 --- a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs +++ b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs @@ -126,8 +126,8 @@ public async Task QueryAsync(ConsoleSearchQuery query) var result = await _searchProvider.SearchAsync(searchQuery); - var documents = result.Documents.Evaluate(); - if (!documents.Any()) + var items = result.Items.Evaluate(); + if (!items.Any()) { return new ConsoleSearchResult { @@ -137,6 +137,8 @@ public async Task QueryAsync(ConsoleSearchQuery query) }; } + var documents = items.Select(m => m.Document); + HashSet dataSourceNames; Facet[] dsFacets; if (result.Facets != null && result.Facets.TryGetValue(DefaultDocumentFieldNames.Source, out dsFacets)) diff --git a/Composite/Search/SearchQuery.cs b/Composite/Search/SearchQuery.cs index c8ddd7e328..309d4fd307 100644 --- a/Composite/Search/SearchQuery.cs +++ b/Composite/Search/SearchQuery.cs @@ -194,6 +194,11 @@ public void FilterByUser(string userName) /// public int MaxDocumentsNumber { get; set; } + /// + /// When set to true, highlihts will be included in the search results. + /// + public bool IncludeHighlights { get; set; } + /// /// Facets to be returned. /// diff --git a/Composite/Search/SearchResult.cs b/Composite/Search/SearchResult.cs index 1a1ce439f4..caac0c66d5 100644 --- a/Composite/Search/SearchResult.cs +++ b/Composite/Search/SearchResult.cs @@ -19,6 +19,27 @@ public class Facet public int HitCount { get; set; } } + /// + /// Represents a search result item, which consists of the document as well as highlighted matched terms. + /// + public sealed class SearchResultItem + { + /// + /// Gets the underlying search document. + /// + public SearchDocument Document { get; set; } + + /// + /// Returns the label of the documents with highlighted matched terms. + /// + public string LabelHtmlHighlight { get; set; } + + /// + /// Returns text fragments of the full text field with highlighted matched terms. + /// + public string[] FullTextHtmlHighlights { get; set; } + } + /// /// Search result. /// @@ -27,7 +48,7 @@ public sealed class SearchResult /// /// Found documents. /// - public IEnumerable Documents { get; set; } + public IEnumerable Items { get; set; } /// /// Total documents found. @@ -40,6 +61,6 @@ public sealed class SearchResult public IDictionary Facets { get; set; } /// - public static SearchResult Empty => new SearchResult { Documents = Enumerable.Empty() }; + public static SearchResult Empty => new SearchResult { Items = Enumerable.Empty() }; } } From 66d42723d4209d8eddf265e2cfe71c07a6906ed8 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 19 Apr 2017 11:32:33 +0200 Subject: [PATCH 113/135] A small optimization to have better search result highlights --- Composite/Data/Types/IPage.cs | 1 - Composite/Search/DocumentSources/CmsPageDocumentSource.cs | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Composite/Data/Types/IPage.cs b/Composite/Data/Types/IPage.cs index db2a40842e..9a96461578 100644 --- a/Composite/Data/Types/IPage.cs +++ b/Composite/Data/Types/IPage.cs @@ -70,7 +70,6 @@ public interface IPage : IData, IChangeHistory, ICreationHistory, IPublishContro [ImmutableFieldId("{C9A81ADE-DAD5-4740-A891-DF1CE2FAB498}")] [Composite.Data.Validation.Validators.RegexValidator(@"^[\s-\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]*$")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "We want a string here")] - [SearchableField(true, false, false)] string UrlTitle { get; set; } diff --git a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs index 6f730a93d7..a918ecab7d 100644 --- a/Composite/Search/DocumentSources/CmsPageDocumentSource.cs +++ b/Composite/Search/DocumentSources/CmsPageDocumentSource.cs @@ -8,6 +8,7 @@ using Composite.Core.Extensions; using Composite.Core.Linq; using Composite.Core.Routing; +using Composite.Core.Routing.Foundation.PluginFacades; using Composite.Core.WebClient; using Composite.Data; using Composite.Data.ProcessControlled.ProcessControllers.GenericPublishProcessController; @@ -184,6 +185,13 @@ private SearchDocument FromPage(IPage page, EntityToken entityToken, Dictionary< } } + if (!string.IsNullOrEmpty(page.UrlTitle) + && !UrlFormattersPluginFacade.FormatUrl(page.Title, true).Equals(page.UrlTitle, StringComparison.OrdinalIgnoreCase) + && !UrlFormattersPluginFacade.FormatUrl(page.Title, false).Equals(page.UrlTitle, StringComparison.OrdinalIgnoreCase)) + { + docBuilder.TextParts.Add(page.UrlTitle); + } + return docBuilder.BuildDocument(Name, documentId, label, null, entityToken); } From 401ca1d1410e0bc60043358415ff4adcc073e031 Mon Sep 17 00:00:00 2001 From: neexite Date: Thu, 20 Apr 2017 12:12:34 +0300 Subject: [PATCH 114/135] Fix #417 [FireFox][Search,Components] WebSocket connection is not reopened automatically if website restarts --- Website/Composite/console/access/wampTest.js | 41 +++++++++++--------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/Website/Composite/console/access/wampTest.js b/Website/Composite/console/access/wampTest.js index 7e6e42ab93..81865e2ee5 100644 --- a/Website/Composite/console/access/wampTest.js +++ b/Website/Composite/console/access/wampTest.js @@ -16,32 +16,37 @@ const Warning = styled.div` const test = new Promise((resolve, reject) => { let url = new URL('/Composite/api/Router', location.href); + let isConnected = false; url.protocol = url.protocol.replace('http', 'ws'); const client = new Wampy(url.href, { realm: 'realm', maxRetries: 0, onConnect: () => { resolve(); + isConnected = true; + client.disconnect(); }, onError: err => { - render( - -

Problem establishing WebSocket connection to server

-

- There is an issue with connecting to the server – this - could indicate that the web server does not support - WebSocket requests. -

-

- For more information, - - please read more about WebSocket requirements. - -

-
, - document.querySelector('body > div.entry') - ); - reject(err); + if (!isConnected) { //FF throw error on disconnect and on server restarted + render( + +

Problem establishing WebSocket connection to server

+

+ There is an issue with connecting to the server – this + could indicate that the web server does not support + WebSocket requests. +

+

+ For more information, + + please read more about WebSocket requirements. + +

+
, + document.querySelector('body > div.entry') + ); + reject(err); + } } }); }); From e34e9a4d3417c23c998feb2e27c354b292edea24 Mon Sep 17 00:00:00 2001 From: neexite Date: Thu, 20 Apr 2017 15:54:29 +0300 Subject: [PATCH 115/135] Fix #426 [Components] Components window is empty when site is running in subfolder #426 --- Composite/Core/WebClient/Services/WampRouter/WampRouter.cs | 2 +- Composite/Core/WebClient/UrlUtils.cs | 4 ++++ Website/Composite/console/access/utils.js | 6 ++++++ Website/Composite/console/access/wampClient.js | 3 ++- Website/Composite/console/access/wampTest.js | 4 +++- Website/Composite/console/index.prod.html | 4 ++-- Website/WebSite.csproj | 3 +++ 7 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 Website/Composite/console/access/utils.js diff --git a/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs b/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs index ba4d036819..191c9838fb 100644 --- a/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs +++ b/Composite/Core/WebClient/Services/WampRouter/WampRouter.cs @@ -81,7 +81,7 @@ private void StartWampRouter() { _host = new WampAuthenticationHost(new UserNameBasedAuthenticationFactory()); - string routeUrl = UrlUtils.ResolveAdminUrl(WampConsoleUrl); + string routeUrl = $"{UrlUtils.AdminFolderName}/{WampConsoleUrl}"; if (routeUrl.StartsWith("/")) { routeUrl = routeUrl.Substring(1); diff --git a/Composite/Core/WebClient/UrlUtils.cs b/Composite/Core/WebClient/UrlUtils.cs index 997500d7f7..08c0e8e473 100644 --- a/Composite/Core/WebClient/UrlUtils.cs +++ b/Composite/Core/WebClient/UrlUtils.cs @@ -105,6 +105,10 @@ public static string AdminRootPath } + /// + internal static string AdminFolderName => _adminFolderName; + + /// /// Determines whether the current request is administration console request. /// (Requests to [/virtual path]/Composite/*) diff --git a/Website/Composite/console/access/utils.js b/Website/Composite/console/access/utils.js new file mode 100644 index 0000000000..b10c6fb529 --- /dev/null +++ b/Website/Composite/console/access/utils.js @@ -0,0 +1,6 @@ +ï»żexport function getBaseUrl() { + + let baseUrlMatches = /^.*?(?=\/Composite\/)/gi.exec(location.pathname); + let baseUrl = baseUrlMatches == null ? "" : baseUrlMatches[0]; + return baseUrl; +} diff --git a/Website/Composite/console/access/wampClient.js b/Website/Composite/console/access/wampClient.js index 1fb3602400..7a785388ec 100644 --- a/Website/Composite/console/access/wampClient.js +++ b/Website/Composite/console/access/wampClient.js @@ -1,4 +1,5 @@ import Wampy from 'wampy'; +import { getBaseUrl } from './utils.js'; let currentClients = {}; function getClient(realm) { @@ -6,7 +7,7 @@ function getClient(realm) { return Promise.resolve(currentClients[realm]); } else { return new Promise((resolve, reject) => { - let url = new URL('/Composite/api/Router', location.href); + let url = new URL(getBaseUrl() + '/Composite/api/Router', location.href); url.protocol = url.protocol.replace('http', 'ws'); const client = new Wampy(url.href, { realm, diff --git a/Website/Composite/console/access/wampTest.js b/Website/Composite/console/access/wampTest.js index 81865e2ee5..281654d850 100644 --- a/Website/Composite/console/access/wampTest.js +++ b/Website/Composite/console/access/wampTest.js @@ -2,6 +2,7 @@ import Wampy from 'wampy'; import React from 'react'; import { render } from 'react-dom'; import styled from 'styled-components'; +import { getBaseUrl } from './utils.js'; const Warning = styled.div` max-width: 400px; @@ -15,7 +16,8 @@ const Warning = styled.div` `; const test = new Promise((resolve, reject) => { - let url = new URL('/Composite/api/Router', location.href); + + let url = new URL(getBaseUrl() + '/Composite/api/Router', location.href); let isConnected = false; url.protocol = url.protocol.replace('http', 'ws'); const client = new Wampy(url.href, { diff --git a/Website/Composite/console/index.prod.html b/Website/Composite/console/index.prod.html index e8e3696dcc..7cc9e4e8e6 100644 --- a/Website/Composite/console/index.prod.html +++ b/Website/Composite/console/index.prod.html @@ -3,8 +3,8 @@ - - + +
diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index 5d585ca763..daaaeca7e0 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -185,8 +185,11 @@ ShowFunctionInfo.aspx + + + From a4ee5dd9b0d1cd8ddd5838441b3faeb8e173d658 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 10:07:16 +0200 Subject: [PATCH 116/135] Updating reset-installation.bat - cleaning out all assemblies from /bin --- .../App_Data/Composite/reset-installation.bat | 47 +++---------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/Website/App_Data/Composite/reset-installation.bat b/Website/App_Data/Composite/reset-installation.bat index c6896196c7..4c58a9f662 100644 --- a/Website/App_Data/Composite/reset-installation.bat +++ b/Website/App_Data/Composite/reset-installation.bat @@ -5,7 +5,6 @@ del Configuration\DynamicXmlDataProvider.config del Configuration\InstallationInformation.xml del Configuration\SystemInitialized.xml del Configuration\FirstTimeStart.xml -del ..\..\Bin\Composite.Generated.dll del ..\..\app_offline.htm /F rd Packages /S /Q md Packages @@ -65,14 +64,15 @@ md ..\..\App_Data\PageTemplates copy ..\..\App_Data\PageTemplates.web.config ..\..\App_Data\PageTemplates\web.config del ..\..\App_Data\PageTemplates.web.config /f +:: License file cleanup +del PackageLicenses\*.* /y + +:: Assembly cleanup +rmdir ..\..\bin /S /Q +mkdir ..\..\bin :: Starter site cleanup del ..\..\favicon.ico -del ..\..\Bin\dotless.Core.dll -del ..\..\Bin\Antlr3.Runtime.dll -del ..\..\Bin\WebGrease.dll -del ..\..\Bin\System.Web.Optimization.dll -del ..\..\Bin\Composite.Search.SimplePageSearch.dll rd /s /q ..\..\Frontend\Scripts rd /s /q ..\..\Frontend\Styles @@ -80,13 +80,9 @@ rd /s /q ..\..\Frontend\Images rd /s /q ..\..\Frontend\Composite - - :: Blog cleanup del ..\..\BlogRssFeed.ashx del ..\..\BlogCommentsRssFeed.ashx -del ..\..\Bin\Composite.Community.Blog.dll -del ..\..\Bin\CookComputing.XmlRpcV2.dll del ..\..\BlogMetaWeblog.ashx del ..\..\App_GlobalResources\Composite\Community\Blog.resx del ..\..\App_GlobalResources\Composite\Community\Blog.ru-ru.resx @@ -96,21 +92,7 @@ del TreeDefinitions\Composite.Community.Blog.Entries.xml del TreeDefinitions\Composite.Community.Blog.Entries.xmll -:: Razor package cleanup -del ..\..\Bin\CompositeC1Contrib.RazorFunctions.dll -del ..\..\Bin\Microsoft.Web.*.dll -:: del ..\..\Bin\System.Web.*.dll - - -:: Extranet cleanup -del ..\..\Bin\Composite.Community.Extranet.dll - - :: Newsletter cleanup -del ..\..\Bin\Composite.Community.Newsletter.dll -del ..\..\Bin\Composite.Community.Newsletter.SubjectBased.dll -del ..\..\Bin\Composite.Community.Newsletter.DataTypeBased.dll -del ..\..\Bin\Composite.Community.Newsletter.FunctionBased.dll del ..\..\Newsletter.ashx del ..\..\App_Data\Composite\TreeDefinitions\Composite.Community.Newsletter.SubjectBased.xml rd /s /q ..\..\App_Data\NewsletterType @@ -122,7 +104,6 @@ rd /s /q ..\..\Frontend\Composite :: Event calender cleanup -del ..\..\Bin\Composite.Community.EventCalendar.dll del ..\..\App_Data\Composite\TreeDefinitions\Composite.Community.EventCalendar.EventsApp.xml @@ -135,7 +116,6 @@ del ..\..\App_Data\Composite\TreeDefinitions\Composite.Community.ContactForm.xml del ..\..\App_Data\Composite\TreeDefinitions\Composite.Community.ContactFrom.EmailTemplate.xml :: Versioning cleanup -del ..\..\Bin\Composite.Versioning.ContentVersioning.dll del TreeDefinitions\Composite.Versioning.ContentVersioning.xml @@ -168,15 +148,10 @@ del Configuration\DynamicXmlDataProvider.config :: Omni corp cleanup del ..\..\Frontend\Composite\Search\SimplePageSearch\Styles.css -:: LESS cleanup -del ..\..\bin\Composite.Web.Css.Less.dll -del ..\..\bin\Orckestra.Web.Css.Less.dll - :: Package create cleanup rd ..\..\Composite\content\forms\InstalledPackages\Composite.Tools.PackageCreator /S /Q -del ..\..\Bin\Composite.Tools.PackageCreator.dll del ..\..\Composite\InstalledPackages\localization\Composite.Tools.PackageCreator.en-us.xml rd /s /q ..\..\App_Data\PackageCreator @@ -191,16 +166,6 @@ rd /s /q ..\..\RSS rd /s /q ..\..\App_GlobalResources -:: assemblies -del ..\..\bin\Composite.Tools.*.* -del ..\..\bin\Composite.Community.*.* -del ..\..\bin\Composite.Web.*.* -del ..\..\bin\Composite.Tools.*.* -del ..\..\bin\Composite.Media.*.* -del ..\..\bin\Composite.Forms.*.* -del ..\..\bin\Composite.XmlSerializers.dll -del ..\..\bin\WebGrease.dll - :: components del /q "..\Components\*" FOR /D %%p IN ("..\Components\*.*") DO rmdir "%%p" /s /q From 93a575362ace252ed2af2aa2f96cf85c537b3898 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 10:09:16 +0200 Subject: [PATCH 117/135] Removing IIS6 / IIS7 Classic mode settings from web.config files (since they are not supported any more) --- Website/Composite/web.config | 5 ----- Website/DebugBuild.Web.config | 11 ----------- Website/ReleaseBuild.Web.config | 11 ----------- 3 files changed, 27 deletions(-) diff --git a/Website/Composite/web.config b/Website/Composite/web.config index 3e0b35e486..e857526f8d 100644 --- a/Website/Composite/web.config +++ b/Website/Composite/web.config @@ -41,11 +41,6 @@ - - - - - diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index 809c8aaa7e..042037c0c5 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -30,16 +30,6 @@ - - - - - - - - - - @@ -61,7 +51,6 @@ - diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index 49d5a54aaf..3dbdd67949 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -30,16 +30,6 @@ - - - - - - - - - - @@ -61,7 +51,6 @@ - From 5faab2c915ba827042f8373e20e59e8cd3fff4cb Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 11:40:21 +0200 Subject: [PATCH 118/135] web.config cleanup --- Website/Composite/web.config | 21 +--- Website/DebugBuild.Web.config | 203 +++++++++++++++---------------- Website/ReleaseBuild.Web.config | 205 ++++++++++++++++---------------- 3 files changed, 207 insertions(+), 222 deletions(-) diff --git a/Website/Composite/web.config b/Website/Composite/web.config index e857526f8d..7f6d53adf6 100644 --- a/Website/Composite/web.config +++ b/Website/Composite/web.config @@ -19,15 +19,6 @@ - - - - - ecmascriptversion=3.0 - javascriptversion=1.8 - browser=Forefox - - @@ -57,18 +48,13 @@ - + - - @@ -78,9 +64,8 @@ - - - + + diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index 042037c0c5..c9540a2ef1 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -1,103 +1,104 @@ ï»ż - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index 3dbdd67949..c1edbebdbe 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -1,105 +1,104 @@ ï»ż - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 30f004c8a39454f457e011682a1e670b94c23872 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 11:55:19 +0200 Subject: [PATCH 119/135] web.config prettifying OCD style 1/2 - moving /configuration/system.web and /configuration/system.webServer to the top and alphabetically ordering /configuration/*/* elements --- Website/DebugBuild.Web.config | 58 ++++++++++++++++----------------- Website/ReleaseBuild.Web.config | 58 ++++++++++++++++----------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index c9540a2ef1..5deb121030 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -1,11 +1,13 @@ ï»ż - - - - - + + + + + + + @@ -20,38 +22,36 @@ + + + + + + + - - - - - - - - - - - - + + + - - - - - - + + + + + + @@ -63,12 +63,6 @@ - - - - - - @@ -77,10 +71,16 @@ + + + + + + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index c1edbebdbe..f4cd97b136 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -1,11 +1,13 @@ ï»ż - - - - - + + + + + + + @@ -20,38 +22,36 @@ + + + + + + + - - - - - - - - - - - - + + + - - - - - - + + + + + + @@ -63,12 +63,6 @@ - - - - - - @@ -77,10 +71,16 @@ + + + + + + From d7a1a6692eb24cfb54c2ad0af62a748546896f49 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 12:02:01 +0200 Subject: [PATCH 120/135] web.config prettifying OCD style 2/2 -ordering /configuration/*/*/* alphabetically elements where approproate --- Website/DebugBuild.Web.config | 18 +++++++++--------- Website/ReleaseBuild.Web.config | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index 5deb121030..358ab8b62d 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -10,13 +10,13 @@ + + + - - - @@ -32,8 +32,8 @@ - + @@ -48,19 +48,19 @@ + - - - + - - + + + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index f4cd97b136..9d69e4b75b 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -10,13 +10,13 @@ + + + - - - @@ -32,8 +32,8 @@ - + @@ -48,19 +48,19 @@ + - - - + - - + + + From df027907ef8a00eedd3724c46a6a3e01873cf98d Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 12:49:18 +0200 Subject: [PATCH 121/135] web.config prettifying OCD style 2/2b, alphabetically ordering --- Website/DebugBuild.Web.config | 2 +- Website/ReleaseBuild.Web.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index 358ab8b62d..472e907670 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -15,8 +15,8 @@ - + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index 9d69e4b75b..2ddf7de8b1 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -15,8 +15,8 @@ - + From 4d2291761a8d97369131f5a3cf861b6209595767 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 12:53:42 +0200 Subject: [PATCH 122/135] web.config cleanup - renaming sitemap provider from legacy name --- Website/DebugBuild.Web.config | 4 ++-- Website/ReleaseBuild.Web.config | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index 472e907670..faf345f6fa 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -36,9 +36,9 @@ - + - + diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index 2ddf7de8b1..b3b5930b61 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -36,9 +36,9 @@ - + - + From 78caff41abf01b11cff3538570ae099f19d7d749 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 21 Apr 2017 14:00:41 +0200 Subject: [PATCH 123/135] Search - adding SearchQueryHighlightSettings class --- Composite/Search/SearchQuery.cs | 38 ++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/Composite/Search/SearchQuery.cs b/Composite/Search/SearchQuery.cs index 309d4fd307..49cfc385c4 100644 --- a/Composite/Search/SearchQuery.cs +++ b/Composite/Search/SearchQuery.cs @@ -80,6 +80,34 @@ public SearchQuerySortOption(string fieldName, bool reverseOrder, SortTermsAs so public SortTermsAs SortTermsAs { get; set; } } + /// + /// Search query hightlight settings. + /// + public sealed class SearchQueryHighlightSettings + { + /// + /// When set to true, highlihts will be included in the search results. + /// + public bool Enabled { get; set; } + + /// + /// Maximum amount of highlight fragments. + /// + public int FragmentsCount { get; set; } = 1; + + /// + /// Maximum fragment size. The default is 100 characters. + /// + public int FragmentSize { get; set; } = 100; + + /// + /// Maximum amount of the full text field characters to be analyzed when extracting fragments to highlight. + /// The default value is 51200. + /// + public int MaxAnalyzedChars { get; set; } = 51200; + } + + /// /// A search query. /// @@ -194,11 +222,6 @@ public void FilterByUser(string userName) ///
public int MaxDocumentsNumber { get; set; } - /// - /// When set to true, highlihts will be included in the search results. - /// - public bool IncludeHighlights { get; set; } - /// /// Facets to be returned. /// @@ -215,6 +238,11 @@ public void FilterByUser(string userName) ///
public IEnumerable SortOptions { get; set; } + /// + /// Highlight settings. + /// + public SearchQueryHighlightSettings HighlightSettings { get; set; } = new SearchQueryHighlightSettings(); + internal void AddDefaultFieldFacet(string fieldName) { From c3834c8713fb726d8f2fefeb7e354f61add8d9c9 Mon Sep 17 00:00:00 2001 From: Marcus Wendt Date: Fri, 21 Apr 2017 14:08:46 +0200 Subject: [PATCH 124/135] Updating pr-300 code to reflect recent changes in C1 ServiceLocator --- .../StandardFunctionProvider/Mail/SendMailFunction.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs b/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs index dabd13c454..a038881b7a 100644 --- a/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs +++ b/Composite/Plugins/Functions/FunctionProviders/StandardFunctionProvider/Mail/SendMailFunction.cs @@ -5,7 +5,6 @@ using System.Net.Mail; using System.Web; using Composite.Core; -using Composite.Core.Application; using Composite.Core.Extensions; using Composite.Core.IO; using Composite.Core.Logging; @@ -13,7 +12,6 @@ using Composite.Data.Types; using Composite.Functions; using Composite.Plugins.Functions.FunctionProviders.StandardFunctionProvider.Foundation; -using Microsoft.Extensions.DependencyInjection; namespace Composite.Plugins.Functions.FunctionProviders.StandardFunctionProvider.Mail { @@ -116,7 +114,7 @@ public static bool SendMail(string subject, string body, bool isHtml, string fro - var mailer = ServiceLocator.ApplicationServices.GetService(); + var mailer = ServiceLocator.GetService(); mailer.Send(mailMessage); From cf1c3aa5fc80327cd678e474faf56908e076a56b Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 24 Apr 2017 13:44:48 +0200 Subject: [PATCH 125/135] Search - negative selection filters; selections no longer require adding a facet explicitly to a query --- .../Endpoint/ConsoleSearchRpcService.cs | 2 +- .../Crawling/DefaultDocumentFieldNames.cs | 22 +++++++++- Composite/Search/SearchQuery.cs | 40 +++++++++++++------ 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs index 7cc7727f81..e43af7cbd6 100644 --- a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs +++ b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs @@ -122,7 +122,7 @@ public async Task QueryAsync(ConsoleSearchQuery query) }; searchQuery.FilterByUser(UserSettings.Username); - searchQuery.AddDefaultFieldFacet(DefaultDocumentFieldNames.Source); + searchQuery.AddFieldFacet(DefaultDocumentFieldNames.Source); var result = await _searchProvider.SearchAsync(searchQuery); diff --git a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs b/Composite/Search/Crawling/DefaultDocumentFieldNames.cs index 2d2bed915c..edc11a5421 100644 --- a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs +++ b/Composite/Search/Crawling/DefaultDocumentFieldNames.cs @@ -1,4 +1,6 @@ -ï»żnamespace Composite.Search.Crawling +ï»żusing System; + +namespace Composite.Search.Crawling { /// /// Contains default document field names @@ -46,5 +48,23 @@ public static class DefaultDocumentFieldNames /// The name of the creation time field. /// public static readonly string LastUpdated = "lastupdated"; + + /// + /// Gets the field name for the given data type property + /// + /// The data type. + /// The property name. + /// + public static string GetFieldName(Type dataType, string propertyName) + { + Verify.ArgumentNotNull(dataType, nameof(dataType)); + Verify.ArgumentNotNull(propertyName, nameof(propertyName)); + + var propertyInfo = dataType.GetProperty(propertyName); + Verify.IsNotNull(propertyInfo, "Type '{0}' does not have a prorety '{1}'", dataType.FullName, propertyName); + + var processor = DataTypeSearchReflectionHelper.GetDataFieldProcessor(propertyInfo); + return processor.GetDocumentFieldName(propertyInfo); + } } } diff --git a/Composite/Search/SearchQuery.cs b/Composite/Search/SearchQuery.cs index 49cfc385c4..8a1b1b6bef 100644 --- a/Composite/Search/SearchQuery.cs +++ b/Composite/Search/SearchQuery.cs @@ -35,7 +35,7 @@ public class SearchQuerySelection public string FieldName { get; set; } /// - /// The array of values. + /// The array of values that are required to appear in the search documents. /// public string[] Values { get; set; } @@ -43,6 +43,11 @@ public class SearchQuerySelection /// Defines how multiple selected values should be resolved. ///
public SearchQuerySelectionOperation Operation { get; set; } + + /// + /// The array of field values, documents containing which, should not appear in the results. + /// + public string[] NotValues { get; set; } } @@ -140,8 +145,6 @@ public void FilterByDataTypes(params Type[] dataTypes) Operation = SearchQuerySelectionOperation.Or, Values = dataTypes.Select(type => type.GetImmutableTypeId().ToString()).ToArray() }); - - AddDefaultFieldFacet(DefaultDocumentFieldNames.DataType); } /// @@ -154,8 +157,6 @@ public void ShowOnlyDocumentsWithUrls() FieldName = DefaultDocumentFieldNames.HasUrl, Values = new [] {"1"} }); - - AddDefaultFieldFacet(DefaultDocumentFieldNames.HasUrl); } @@ -172,8 +173,6 @@ public void FilterByAncestors(params EntityToken[] entityTokens) Operation = SearchQuerySelectionOperation.Or, Values = entityTokens.Select(SearchDocumentBuilder.GetEntityTokenHash).ToArray() }); - - AddDefaultFieldFacet(DefaultDocumentFieldNames.Ancestors); } @@ -198,8 +197,6 @@ public void FilterByUser(string userName) Operation = SearchQuerySelectionOperation.Or, Values = tokens.ToArray() }); - - AddDefaultFieldFacet(DefaultDocumentFieldNames.ConsoleAccess); } /// @@ -244,18 +241,35 @@ public void FilterByUser(string userName) public SearchQueryHighlightSettings HighlightSettings { get; set; } = new SearchQueryHighlightSettings(); - internal void AddDefaultFieldFacet(string fieldName) + /// + /// Will indicate that the search results should return facet information for the given field. + /// + /// + public void AddFieldFacet(string fieldName) { + Verify.ArgumentNotNullOrEmpty(fieldName, nameof(fieldName)); + if (Facets.Any(f => f.Key == fieldName)) { return; } + var field = SearchDocumentBuilder.GetDefaultDocumentFields() + .FirstOrDefault(f => f.Name == fieldName); + + if (field == null) + { + field = SearchFacade.DocumentSources.SelectMany(f => f.CustomFields) + .FirstOrDefault(f => f.Name == fieldName); + + Verify.IsNotNull(field, $"Failed to find a document field by name '{fieldName}'"); + } + + Verify.IsNotNull(field.Facet, $"Faceted search is enabled for the field '{fieldName}'"); + Facets.Add(new KeyValuePair( fieldName, - SearchDocumentBuilder.GetDefaultDocumentFields() - .Single(f => f.Name == fieldName) - .Facet)); + field.Facet)); } } } From c54c87af3b1303e34046e922b4338775019e823d Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 24 Apr 2017 13:48:53 +0200 Subject: [PATCH 126/135] Renaming DefaultDocumentFieldNames -> DocumentFieldNames --- Composite/Composite.csproj | 2 +- .../Endpoint/ConsoleSearchRpcService.cs | 4 ++-- .../Crawling/DefaultDataFieldProcessor.cs | 8 +++---- ...entFieldNames.cs => DocumentFieldNames.cs} | 2 +- .../Search/Crawling/SearchDocumentBuilder.cs | 24 +++++++++---------- Composite/Search/SearchQuery.cs | 8 +++---- 6 files changed, 24 insertions(+), 24 deletions(-) rename Composite/Search/Crawling/{DefaultDocumentFieldNames.cs => DocumentFieldNames.cs} (95%) diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 66306791c0..7e2cfb45f0 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -256,7 +256,7 @@ - + diff --git a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs index e43af7cbd6..23a501fb9c 100644 --- a/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs +++ b/Composite/Plugins/Search/Endpoint/ConsoleSearchRpcService.cs @@ -122,7 +122,7 @@ public async Task QueryAsync(ConsoleSearchQuery query) }; searchQuery.FilterByUser(UserSettings.Username); - searchQuery.AddFieldFacet(DefaultDocumentFieldNames.Source); + searchQuery.AddFieldFacet(DocumentFieldNames.Source); var result = await _searchProvider.SearchAsync(searchQuery); @@ -141,7 +141,7 @@ public async Task QueryAsync(ConsoleSearchQuery query) HashSet dataSourceNames; Facet[] dsFacets; - if (result.Facets != null && result.Facets.TryGetValue(DefaultDocumentFieldNames.Source, out dsFacets)) + if (result.Facets != null && result.Facets.TryGetValue(DocumentFieldNames.Source, out dsFacets)) { dataSourceNames = new HashSet(dsFacets.Select(v => v.Value)); } diff --git a/Composite/Search/Crawling/DefaultDataFieldProcessor.cs b/Composite/Search/Crawling/DefaultDataFieldProcessor.cs index 206d2546cd..4bf2050449 100644 --- a/Composite/Search/Crawling/DefaultDataFieldProcessor.cs +++ b/Composite/Search/Crawling/DefaultDataFieldProcessor.cs @@ -46,13 +46,13 @@ public virtual string GetDocumentFieldName(PropertyInfo pi) { if (pi.Name == nameof(IPage.Description) && pi.PropertyType == typeof(string)) { - return DefaultDocumentFieldNames.Description; + return DocumentFieldNames.Description; } if ((pi.Name == nameof(IChangeHistory.ChangeDate) || pi.Name == nameof(IMediaFile.CreationTime)) && (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))) { - return DefaultDocumentFieldNames.LastUpdated; + return DocumentFieldNames.LastUpdated; } return $"{pi.ReflectedType.Name}.{pi.Name}"; @@ -125,12 +125,12 @@ private SortTermsAs GetFieldSortingMethod(Type propertyType) public virtual string GetFieldLabel(PropertyInfo propertyInfo) { var fieldName = GetDocumentFieldName(propertyInfo); - if (fieldName == DefaultDocumentFieldNames.Description) + if (fieldName == DocumentFieldNames.Description) { return Texts.FieldNames_Description; } - if (fieldName == DefaultDocumentFieldNames.LastUpdated) return Texts.FieldNames_LastUpdated; + if (fieldName == DocumentFieldNames.LastUpdated) return Texts.FieldNames_LastUpdated; if (propertyInfo.Name == nameof(IChangeHistory.ChangedBy)) return Texts.FieldNames_UpdatedBy; if (propertyInfo.Name == nameof(IMediaFile.MimeType)) return Texts.FieldNames_MimeType; diff --git a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs b/Composite/Search/Crawling/DocumentFieldNames.cs similarity index 95% rename from Composite/Search/Crawling/DefaultDocumentFieldNames.cs rename to Composite/Search/Crawling/DocumentFieldNames.cs index edc11a5421..b5aec41728 100644 --- a/Composite/Search/Crawling/DefaultDocumentFieldNames.cs +++ b/Composite/Search/Crawling/DocumentFieldNames.cs @@ -5,7 +5,7 @@ namespace Composite.Search.Crawling /// /// Contains default document field names /// - public static class DefaultDocumentFieldNames + public static class DocumentFieldNames { /// /// The name of the label field. diff --git a/Composite/Search/Crawling/SearchDocumentBuilder.cs b/Composite/Search/Crawling/SearchDocumentBuilder.cs index c584ec1b9e..a360413ac5 100644 --- a/Composite/Search/Crawling/SearchDocumentBuilder.cs +++ b/Composite/Search/Crawling/SearchDocumentBuilder.cs @@ -90,8 +90,8 @@ public void SetDataType(Type interfaceType) /// Sets the data type name, which will be used for populating the "Data Type" column in the search results. public void SetDataType(string dataTypeName) { - _fieldValues.Add(new KeyValuePair(DefaultDocumentFieldNames.DataType, dataTypeName)); - _facetFieldValues.Add(new KeyValuePair(DefaultDocumentFieldNames.DataType, new[] { dataTypeName })); + _fieldValues.Add(new KeyValuePair(DocumentFieldNames.DataType, dataTypeName)); + _facetFieldValues.Add(new KeyValuePair(DocumentFieldNames.DataType, new[] { dataTypeName })); } /// @@ -209,11 +209,11 @@ public SearchDocument BuildDocument( Verify.ArgumentNotNullOrEmpty(documentId, nameof(documentId)); Verify.ArgumentNotNullOrEmpty(label, nameof(label)); - _fieldValues.Add(new KeyValuePair(DefaultDocumentFieldNames.Label, label)); + _fieldValues.Add(new KeyValuePair(DocumentFieldNames.Label, label)); if (!string.IsNullOrWhiteSpace(Url)) { - _facetFieldValues.Add(new KeyValuePair(DefaultDocumentFieldNames.HasUrl, new[] { "1" })); + _facetFieldValues.Add(new KeyValuePair(DocumentFieldNames.HasUrl, new[] { "1" })); } AddAccessField(entityToken); @@ -245,7 +245,7 @@ private void AddAccessField(EntityToken entityToken) if (tokens.Any()) { _facetFieldValues.Add(new KeyValuePair( - DefaultDocumentFieldNames.ConsoleAccess, + DocumentFieldNames.ConsoleAccess, tokens)); } @@ -254,7 +254,7 @@ private void AddAccessField(EntityToken entityToken) var ancestorTokens = ancestors.Select(GetEntityTokenHash).ToArray(); _facetFieldValues.Add(new KeyValuePair( - DefaultDocumentFieldNames.Ancestors, + DocumentFieldNames.Ancestors, ancestorTokens)); } } @@ -276,7 +276,7 @@ public static IEnumerable GetDefaultDocumentFields() return new[] { new DocumentField( - DefaultDocumentFieldNames.Label, + DocumentFieldNames.Label, null, new DocumentFieldPreview { @@ -289,7 +289,7 @@ public static IEnumerable GetDefaultDocumentFields() }, new DocumentField( - DefaultDocumentFieldNames.Source, + DocumentFieldNames.Source, new DocumentFieldFacet { PreviewFunction = value => value, @@ -302,7 +302,7 @@ public static IEnumerable GetDefaultDocumentFields() }, new DocumentField( - DefaultDocumentFieldNames.DataType, + DocumentFieldNames.DataType, new DocumentFieldFacet { PreviewFunction = GetDataTypeLabel, @@ -319,7 +319,7 @@ public static IEnumerable GetDefaultDocumentFields() }, new DocumentField( - DefaultDocumentFieldNames.HasUrl, + DocumentFieldNames.HasUrl, new DocumentFieldFacet { PreviewFunction = value => value, @@ -331,7 +331,7 @@ public static IEnumerable GetDefaultDocumentFields() }, new DocumentField( - DefaultDocumentFieldNames.ConsoleAccess, + DocumentFieldNames.ConsoleAccess, new DocumentFieldFacet { FacetType = FacetType.MultipleValues, @@ -342,7 +342,7 @@ public static IEnumerable GetDefaultDocumentFields() Label = null }, new DocumentField( - DefaultDocumentFieldNames.Ancestors, + DocumentFieldNames.Ancestors, new DocumentFieldFacet { FacetType = FacetType.MultipleValues, diff --git a/Composite/Search/SearchQuery.cs b/Composite/Search/SearchQuery.cs index 8a1b1b6bef..f06686db89 100644 --- a/Composite/Search/SearchQuery.cs +++ b/Composite/Search/SearchQuery.cs @@ -141,7 +141,7 @@ public void FilterByDataTypes(params Type[] dataTypes) Selection.Add(new SearchQuerySelection { - FieldName = DefaultDocumentFieldNames.DataType, + FieldName = DocumentFieldNames.DataType, Operation = SearchQuerySelectionOperation.Or, Values = dataTypes.Select(type => type.GetImmutableTypeId().ToString()).ToArray() }); @@ -154,7 +154,7 @@ public void ShowOnlyDocumentsWithUrls() { Selection.Add(new SearchQuerySelection { - FieldName = DefaultDocumentFieldNames.HasUrl, + FieldName = DocumentFieldNames.HasUrl, Values = new [] {"1"} }); } @@ -169,7 +169,7 @@ public void FilterByAncestors(params EntityToken[] entityTokens) { Selection.Add(new SearchQuerySelection { - FieldName = DefaultDocumentFieldNames.Ancestors, + FieldName = DocumentFieldNames.Ancestors, Operation = SearchQuerySelectionOperation.Or, Values = entityTokens.Select(SearchDocumentBuilder.GetEntityTokenHash).ToArray() }); @@ -193,7 +193,7 @@ public void FilterByUser(string userName) Selection.Add(new SearchQuerySelection { - FieldName = DefaultDocumentFieldNames.ConsoleAccess, + FieldName = DocumentFieldNames.ConsoleAccess, Operation = SearchQuerySelectionOperation.Or, Values = tokens.ToArray() }); From 9643896cfed20fc760b67960afaf92a6f27d978d Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 24 Apr 2017 14:40:45 +0200 Subject: [PATCH 127/135] A compatibility fix --- .../Search/Crawling/DocumentFieldNames.cs | 22 +++++++++++++++++++ Composite/Search/SearchQuery.cs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Composite/Search/Crawling/DocumentFieldNames.cs b/Composite/Search/Crawling/DocumentFieldNames.cs index b5aec41728..22869d0f7c 100644 --- a/Composite/Search/Crawling/DocumentFieldNames.cs +++ b/Composite/Search/Crawling/DocumentFieldNames.cs @@ -2,6 +2,28 @@ namespace Composite.Search.Crawling { + [Obsolete("Use DocumentFieldNames instead", true)] + /// + public static class DefaultDocumentFieldNames + { + /// + public static readonly string Label = DocumentFieldNames.Label; + /// + public static readonly string Source = DocumentFieldNames.Source; + /// + public static readonly string Description = DocumentFieldNames.Description; + /// + public static readonly string DataType = DocumentFieldNames.DataType; + /// + public static readonly string ConsoleAccess = DocumentFieldNames.ConsoleAccess; + /// + public static readonly string Ancestors = DocumentFieldNames.Ancestors; + /// + public static readonly string HasUrl = DocumentFieldNames.HasUrl; + /// + public static readonly string LastUpdated = DocumentFieldNames.LastUpdated; + } + /// /// Contains default document field names /// diff --git a/Composite/Search/SearchQuery.cs b/Composite/Search/SearchQuery.cs index f06686db89..8a104ada45 100644 --- a/Composite/Search/SearchQuery.cs +++ b/Composite/Search/SearchQuery.cs @@ -265,7 +265,7 @@ public void AddFieldFacet(string fieldName) Verify.IsNotNull(field, $"Failed to find a document field by name '{fieldName}'"); } - Verify.IsNotNull(field.Facet, $"Faceted search is enabled for the field '{fieldName}'"); + Verify.IsNotNull(field.Facet, $"Faceted search is not enabled for the field '{fieldName}'"); Facets.Add(new KeyValuePair( fieldName, From e3f6a55346545ab48ed364d3489bbc530c2c01ff Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 24 Apr 2017 15:38:41 +0200 Subject: [PATCH 128/135] Search - fixing ancestors being indexed incorrectly --- Composite/Search/Crawling/EntityTokenSecurityHelper.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Composite/Search/Crawling/EntityTokenSecurityHelper.cs b/Composite/Search/Crawling/EntityTokenSecurityHelper.cs index f7d60af57b..fa1a1c91bd 100644 --- a/Composite/Search/Crawling/EntityTokenSecurityHelper.cs +++ b/Composite/Search/Crawling/EntityTokenSecurityHelper.cs @@ -47,12 +47,13 @@ public static void GetUsersAndGroupsWithReadAccess(EntityToken entityToken, var ancestorsSet = new HashSet(); using (ThreadDataManager.EnsureInitialize()) + using (new DataScope(DataScopeIdentifier.Administrated)) { CollectUsersAndGroupsRec(entityToken, - GetUserAccessDefinitions(), GetUserGroupAccessDefinitions(), + GetUserAccessDefinitions(), GetUserGroupAccessDefinitions(), ImmutableHashSet.Empty, ImmutableHashSet.Empty, - userSet, + userSet, userGroupSet, ancestorsSet, 20); @@ -114,7 +115,7 @@ private static void CollectUsersAndGroupsRec( foreach (var parent in parents) { - if(alreadyVisited.Contains(parent)) return; + if(alreadyVisited.Contains(parent)) continue; CollectUsersAndGroupsRec(parent, userAccessDefinitions, groupAccessDefinitions, From eedd63cec1f6af6553707f9a8ffaa75e2410f3dc Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Tue, 25 Apr 2017 10:24:37 +0200 Subject: [PATCH 129/135] PageRenderer - fixing a null ref when previewing a page without a public URL, refactoring --- .../WebClient/Renderings/Page/PageRenderer.cs | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/Composite/Core/WebClient/Renderings/Page/PageRenderer.cs b/Composite/Core/WebClient/Renderings/Page/PageRenderer.cs index 5363359a3b..7f185d3771 100644 --- a/Composite/Core/WebClient/Renderings/Page/PageRenderer.cs +++ b/Composite/Core/WebClient/Renderings/Page/PageRenderer.cs @@ -85,7 +85,7 @@ public static Control Render(this IPage page, IEnumerable public static XhtmlDocument ParsePlaceholderContent(IPagePlaceholderContent placeholderContent) { - if (placeholderContent == null || string.IsNullOrEmpty(placeholderContent.Content)) + if (string.IsNullOrEmpty(placeholderContent?.Content)) { return new XhtmlDocument(); } @@ -137,7 +137,7 @@ private static void ResolvePlaceholders(XDocument document, IEnumerable GetXElements(object source) { - if (source is XElement) + if (source is XElement element) { - yield return (XElement)source; + yield return element; } - if (source is IEnumerable) + if (source is IEnumerable nodes) { - foreach (XElement xElement in ((IEnumerable)source).OfType()) + foreach (var xElement in nodes.OfType()) { yield return xElement; } @@ -612,7 +609,7 @@ public static void NormalizeXhtmlDocument(XhtmlDocument rootDocument) /// public static bool DisableAspNetPostback(Control c) { - bool formDisabled = false; + bool formDisabled; DisableAspNetPostback(c, out formDisabled); return formDisabled; } @@ -622,9 +619,9 @@ private static void DisableAspNetPostback(Control c, out bool formDisabled) { formDisabled = false; - if (c is HtmlForm) + if (c is HtmlForm form) { - ((HtmlForm)c).Attributes.Add("onsubmit", "alert('Postback disabled in preview mode'); return false;"); + form.Attributes.Add("onsubmit", "alert('Postback disabled in preview mode'); return false;"); formDisabled = true; return; } From c9cf4154851b28779656573b576221cb70119868 Mon Sep 17 00:00:00 2001 From: neexite Date: Wed, 26 Apr 2017 12:10:39 +0300 Subject: [PATCH 130/135] Adjust component selector styles(made 3 column) --- .../Composite/console/components/presentation/Palette.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Website/Composite/console/components/presentation/Palette.js b/Website/Composite/console/components/presentation/Palette.js index 34fb77248a..56bfd1528d 100644 --- a/Website/Composite/console/components/presentation/Palette.js +++ b/Website/Composite/console/components/presentation/Palette.js @@ -1,4 +1,4 @@ -import React, { PropTypes } from 'react'; +ï»żimport React, { PropTypes } from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Immutable from 'immutable'; import styled from 'styled-components'; @@ -12,6 +12,9 @@ import Icon from 'console/components/presentation/Icon.js'; const itemOpenCloseTime = '200ms'; +const PaletteList = styled.div` + margin-right: -10px; +`; export const ItemGroup = styled.div` overflow: hidden; `; @@ -123,7 +126,7 @@ function resolveMediaURI(uri) { } const Palette = props => { - return
+ return {props.itemGroups.size === 0 ?
@@ -188,7 +191,7 @@ const Palette = props => { }).toArray()} ).toArray()} -
; + ; }; Palette.propTypes = { From 069bd3949962130af6acf9dc4e0e12fee674ae7f Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 26 Apr 2017 11:32:24 +0200 Subject: [PATCH 131/135] Fixing the old page selector control not working when there are pages with multiple versions --- .../WebClient/Renderings/Page/PageStructureInfo.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Composite/Core/WebClient/Renderings/Page/PageStructureInfo.cs b/Composite/Core/WebClient/Renderings/Page/PageStructureInfo.cs index ed0121e93c..87e05cf83a 100644 --- a/Composite/Core/WebClient/Renderings/Page/PageStructureInfo.cs +++ b/Composite/Core/WebClient/Renderings/Page/PageStructureInfo.cs @@ -11,7 +11,7 @@ using Composite.Data.Types; using Composite.Core.Logging; using Composite.Core.Extensions; - +using Composite.Core.Linq; using MapKey = System.Tuple; namespace Composite.Core.WebClient.Renderings.Page @@ -613,9 +613,16 @@ private class PageTreeInfo private class SitemapBuildingData { + private class PageIdComparer : IEqualityComparer + { + public bool Equals(IPage x, IPage y) => x.Id == y.Id; + + public int GetHashCode(IPage obj) => obj.Id.GetHashCode(); + } + public SitemapBuildingData() { - Pages = DataFacade.GetData().ToList(); + Pages = DataFacade.GetData().Evaluate().Distinct(new PageIdComparer()).ToList(); Structures = DataFacade.GetData().ToList(); PageById = new Hashtable(); From 84be967cf0c1b4b0dbe02d6f8dd96fc7666adb5c Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 26 Apr 2017 12:21:03 +0200 Subject: [PATCH 132/135] Search: adding IDocumentFieldProvider interface that allows adding custom index fields --- Composite/Composite.csproj | 1 + .../Crawling/DataTypeSearchReflectionHelper.cs | 13 +++++++++++-- .../Search/Crawling/IDocumentFieldProvider.cs | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 Composite/Search/Crawling/IDocumentFieldProvider.cs diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 7e2cfb45f0..77ea1ca4d7 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -258,6 +258,7 @@ + diff --git a/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs b/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs index ce57cf632f..c876057c11 100644 --- a/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs +++ b/Composite/Search/Crawling/DataTypeSearchReflectionHelper.cs @@ -95,11 +95,11 @@ internal static IDataFieldProcessor GetDataFieldProcessor(PropertyInfo propertyI /// public static IEnumerable GetDocumentFields(Type interfaceType, bool includeDefaultFields = true) { - var defaultFields = includeDefaultFields + var fields = includeDefaultFields ? SearchDocumentBuilder.GetDefaultDocumentFields() : Enumerable.Empty(); - return defaultFields.Concat( + fields = fields.Concat( from info in GetSearchableFields(interfaceType) let prop = info.Key let attr = info.Value @@ -112,6 +112,15 @@ where attr.Previewable || attr.Faceted { Label = processor.GetFieldLabel(prop) }); + + if (includeDefaultFields) + { + fields = fields.Concat( + ServiceLocator.GetServices() + .SelectMany(fp => fp.GetCustomFields(interfaceType))); + } + + return fields; } } } diff --git a/Composite/Search/Crawling/IDocumentFieldProvider.cs b/Composite/Search/Crawling/IDocumentFieldProvider.cs new file mode 100644 index 0000000000..0eab8426a5 --- /dev/null +++ b/Composite/Search/Crawling/IDocumentFieldProvider.cs @@ -0,0 +1,18 @@ +ï»żusing System; +using System.Collections.Generic; + +namespace Composite.Search.Crawling +{ + /// + /// Allows adding custom document fields to existing document sources. + /// + public interface IDocumentFieldProvider + { + /// + /// Returns custom fields that should be added to the datatype's search document. + /// + /// The data type. + /// + IEnumerable GetCustomFields(Type dataType); + } +} From b41542fcf01f740e026ce629ab14b2da6c725ded Mon Sep 17 00:00:00 2001 From: Taras Nakonechnyi Date: Wed, 26 Apr 2017 13:41:23 +0300 Subject: [PATCH 133/135] Using Bower for TinyMCE Update TinyMCE to latest version(4.5.7) --- .../visualeditor/tinymce/langs/readme.md | 3 - .../editors/visualeditor/tinymce/license.txt | 504 ------------------ .../tinymce/plugins/autolink/plugin.min.js | 1 - .../tinymce/plugins/lists/plugin.min.js | 1 - .../tinymce/plugins/paste/plugin.min.js | 1 - .../tinymce/plugins/table/plugin.min.js | 1 - .../skins/lightgray/content.inline.min.css | 1 - .../tinymce/skins/lightgray/content.min.css | 1 - .../skins/lightgray/fonts/tinymce-small.eot | Bin 9112 -> 0 bytes .../skins/lightgray/fonts/tinymce-small.svg | 62 --- .../skins/lightgray/fonts/tinymce-small.ttf | Bin 8924 -> 0 bytes .../skins/lightgray/fonts/tinymce-small.woff | Bin 9000 -> 0 bytes .../tinymce/skins/lightgray/fonts/tinymce.eot | Bin 12044 -> 0 bytes .../tinymce/skins/lightgray/fonts/tinymce.svg | 83 --- .../tinymce/skins/lightgray/fonts/tinymce.ttf | Bin 11880 -> 0 bytes .../skins/lightgray/fonts/tinymce.woff | Bin 11956 -> 0 bytes .../tinymce/skins/lightgray/img/anchor.gif | Bin 53 -> 0 bytes .../tinymce/skins/lightgray/img/loader.gif | Bin 2608 -> 0 bytes .../tinymce/skins/lightgray/img/object.gif | Bin 152 -> 0 bytes .../tinymce/skins/lightgray/img/trans.gif | Bin 43 -> 0 bytes .../tinymce/skins/lightgray/skin.ie7.min.css | 1 - .../tinymce/skins/lightgray/skin.min.css | 1 - .../visualeditor/tinymce/tinymce.min.js | 12 - Website/WebSite.csproj | 23 - Website/bower.json | 3 +- Website/gruntfile.js | 16 +- 26 files changed, 16 insertions(+), 698 deletions(-) delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/langs/readme.md delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/license.txt delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/autolink/plugin.min.js delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/lists/plugin.min.js delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/paste/plugin.min.js delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/table/plugin.min.js delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.inline.min.css delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.min.css delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.eot delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.svg delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.ttf delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.woff delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.eot delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.svg delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.ttf delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.woff delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/anchor.gif delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/loader.gif delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/object.gif delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/trans.gif delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/skin.ie7.min.css delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/skin.min.css delete mode 100644 Website/Composite/content/misc/editors/visualeditor/tinymce/tinymce.min.js diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/langs/readme.md b/Website/Composite/content/misc/editors/visualeditor/tinymce/langs/readme.md deleted file mode 100644 index a52bf03f9a..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/langs/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -This is where language files should be placed. - -Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/license.txt b/Website/Composite/content/misc/editors/visualeditor/tinymce/license.txt deleted file mode 100644 index 1837b0acbe..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/license.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/autolink/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/autolink/plugin.min.js deleted file mode 100644 index 547eea7ded..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/autolink/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -tinymce.PluginManager.add("autolink",function(a){function b(a){e(a,-1,"(",!0)}function c(a){e(a,0,"",!0)}function d(a){e(a,-1,"",!1)}function e(a,b,c){function d(a,b){if(0>b&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function e(a,b){1!=a.nodeType||a.hasChildNodes()?g.setStart(a,d(a,b)):g.setStartBefore(a)}function f(a,b){1!=a.nodeType||a.hasChildNodes()?g.setEnd(a,d(a,b)):g.setEndAfter(a)}var g,h,i,j,k,l,m,n,o,p;if("A"!=a.selection.getNode().tagName){if(g=a.selection.getRng(!0).cloneRange(),g.startOffset<5){if(n=g.endContainer.previousSibling,!n){if(!g.endContainer.firstChild||!g.endContainer.firstChild.nextSibling)return;n=g.endContainer.firstChild.nextSibling}if(o=n.length,e(n,o),f(n,o),g.endOffset<5)return;h=g.endOffset,j=n}else{if(j=g.endContainer,3!=j.nodeType&&j.firstChild){for(;3!=j.nodeType&&j.firstChild;)j=j.firstChild;3==j.nodeType&&(e(j,0),f(j,j.nodeValue.length))}h=1==g.endOffset?2:g.endOffset-1-b}i=h;do e(j,h>=2?h-2:0),f(j,h>=1?h-1:0),h-=1,p=g.toString();while(" "!=p&&""!==p&&160!=p.charCodeAt(0)&&h-2>=0&&p!=c);g.toString()==c||160==g.toString().charCodeAt(0)?(e(j,h),f(j,i),h+=1):0===g.startOffset?(e(j,0),f(j,i)):(e(j,h),f(j,i)),l=g.toString(),"."==l.charAt(l.length-1)&&f(j,i-1),l=g.toString(),m=l.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i),m&&("www."==m[1]?m[1]="http://www.":/@$/.test(m[1])&&!/^mailto:/.test(m[1])&&(m[1]="mailto:"+m[1]),k=a.selection.getBookmark(),a.selection.setRng(g),a.execCommand("createlink",!1,m[1]+m[2]),a.selection.moveToBookmark(k),a.nodeChanged())}}var f;return a.on("keydown",function(b){return 13==b.keyCode?d(a):void 0}),tinymce.Env.ie?void a.on("focus",function(){if(!f){f=!0;try{a.execCommand("AutoUrlDetect",!1,!0)}catch(b){}}}):(a.on("keypress",function(c){return 41==c.keyCode?b(a):void 0}),void a.on("keyup",function(b){return 32==b.keyCode?c(a):void 0}))}); \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/lists/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/lists/plugin.min.js deleted file mode 100644 index cbf610c5bc..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/lists/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -tinymce.PluginManager.add("lists",function(a){function b(a){return a&&/^(OL|UL|DL)$/.test(a.nodeName)}function c(a){return a.parentNode.firstChild==a}function d(a){return a.parentNode.lastChild==a}function e(b){return b&&!!a.schema.getTextBlockElements()[b.nodeName]}var f=this;a.on("init",function(){function g(a,b){var c=w.isEmpty(a);return b&&w.select("span[data-mce-type=bookmark]").length>0?!1:c}function h(a){function b(b){var d,e,f;e=a[b?"startContainer":"endContainer"],f=a[b?"startOffset":"endOffset"],1==e.nodeType&&(d=w.create("span",{"data-mce-type":"bookmark"}),e.hasChildNodes()?(f=Math.min(f,e.childNodes.length-1),b?e.insertBefore(d,e.childNodes[f]):w.insertAfter(d,e.childNodes[f])):e.appendChild(d),e=d,f=0),c[b?"startContainer":"endContainer"]=e,c[b?"startOffset":"endOffset"]=f}var c={};return b(!0),a.collapsed||b(),c}function i(a){function b(b){function c(a){for(var b=a.parentNode.firstChild,c=0;b;){if(b==a)return c;(1!=b.nodeType||"bookmark"!=b.getAttribute("data-mce-type"))&&c++,b=b.nextSibling}return-1}var d,e,f;d=f=a[b?"startContainer":"endContainer"],e=a[b?"startOffset":"endOffset"],d&&(1==d.nodeType&&(e=c(d),d=d.parentNode,w.remove(f)),a[b?"startContainer":"endContainer"]=d,a[b?"startOffset":"endOffset"]=e)}b(!0),b();var c=w.createRng();c.setStart(a.startContainer,a.startOffset),a.endContainer&&c.setEnd(a.endContainer,a.endOffset),x.setRng(c)}function j(b,c){var d,e,f,g=w.createFragment(),h=a.schema.getBlockElements();if(a.settings.forced_root_block&&(c=c||a.settings.forced_root_block),c&&(e=w.create(c),e.tagName===a.settings.forced_root_block&&w.setAttribs(e,a.settings.forced_root_block_attrs),g.appendChild(e)),b)for(;d=b.firstChild;){var i=d.nodeName;f||"SPAN"==i&&"bookmark"==d.getAttribute("data-mce-type")||(f=!0),h[i]?(g.appendChild(d),e=null):c?(e||(e=w.create(c),g.appendChild(e)),e.appendChild(d)):g.appendChild(d)}return a.settings.forced_root_block?f||tinymce.Env.ie&&!(tinymce.Env.ie>10)||e.appendChild(w.create("br",{"data-mce-bogus":"1"})):g.appendChild(w.create("br")),g}function k(){return tinymce.grep(x.getSelectedBlocks(),function(a){return/^(LI|DT|DD)$/.test(a.nodeName)})}function l(a,b,c){function d(a){tinymce.each(h,function(c){a.parentNode.insertBefore(c,b.parentNode)}),w.remove(a)}var e,f,h,i;for(h=w.select('span[data-mce-type="bookmark"]',a),c=c||j(b),e=w.createRng(),e.setStartAfter(b),e.setEndAfter(a),f=e.extractContents(),i=f.firstChild;i;i=i.firstChild)if("LI"==i.nodeName&&w.isEmpty(i)){w.remove(i);break}w.isEmpty(f)||w.insertAfter(f,a),w.insertAfter(c,a),g(b.parentNode)&&d(b.parentNode),w.remove(b),g(a)&&w.remove(a)}function m(a){var c,d;if(c=a.nextSibling,c&&b(c)&&c.nodeName==a.nodeName){for(;d=c.firstChild;)a.appendChild(d);w.remove(c)}if(c=a.previousSibling,c&&b(c)&&c.nodeName==a.nodeName){for(;d=c.firstChild;)a.insertBefore(d,a.firstChild);w.remove(c)}}function n(a){tinymce.each(tinymce.grep(w.select("ol,ul",a)),function(a){var c,d=a.parentNode;"LI"==d.nodeName&&d.firstChild==a&&(c=d.previousSibling,c&&"LI"==c.nodeName&&(c.appendChild(a),g(d)&&w.remove(d))),b(d)&&(c=d.previousSibling,c&&"LI"==c.nodeName&&c.appendChild(a))})}function o(a){function e(a){g(a)&&w.remove(a)}var f,h=a.parentNode,i=h.parentNode;return"DD"==a.nodeName?(w.rename(a,"DT"),!0):c(a)&&d(a)?("LI"==i.nodeName?(w.insertAfter(a,i),e(i),w.remove(h)):b(i)?w.remove(h,!0):(i.insertBefore(j(a),h),w.remove(h)),!0):c(a)?("LI"==i.nodeName?(w.insertAfter(a,i),a.appendChild(h),e(i)):b(i)?i.insertBefore(a,h):(i.insertBefore(j(a),h),w.remove(a)),!0):d(a)?("LI"==i.nodeName?w.insertAfter(a,i):b(i)?w.insertAfter(a,h):(w.insertAfter(j(a),h),w.remove(a)),!0):("LI"==i.nodeName?(h=i,f=j(a,"LI")):f=b(i)?j(a,"LI"):j(a),l(h,a,f),n(h.parentNode),!0)}function p(a){function c(c,d){var e;if(b(c)){for(;e=a.lastChild.firstChild;)d.appendChild(e);w.remove(c)}}var d,e;return"DT"==a.nodeName?(w.rename(a,"DD"),!0):(d=a.previousSibling,d&&b(d)?(d.appendChild(a),!0):d&&"LI"==d.nodeName&&b(d.lastChild)?(d.lastChild.appendChild(a),c(a.lastChild,d.lastChild),!0):(d=a.nextSibling,d&&b(d)?(d.insertBefore(a,d.firstChild),!0):d&&"LI"==d.nodeName&&b(a.lastChild)?!1:(d=a.previousSibling,d&&"LI"==d.nodeName?(e=w.create(a.parentNode.nodeName),d.appendChild(e),e.appendChild(a),c(a.lastChild,e),!0):!1)))}function q(){var b=k();if(b.length){for(var c=h(x.getRng(!0)),d=0;d0))return f;for(d=a.schema.getNonEmptyElements(),e=new tinymce.dom.TreeWalker(b.startContainer);f=e[c?"next":"prev"]();){if("LI"==f.nodeName&&!f.hasChildNodes())return f;if(d[f.nodeName])return f;if(3==f.nodeType&&f.data.length>0)return f}}function e(a,c){var d,e,f=a.parentNode;if(b(c.lastChild)&&(e=c.lastChild),d=c.lastChild,d&&"BR"==d.nodeName&&a.hasChildNodes()&&w.remove(d),g(c,!0)&&w.$(c).empty(),!g(a,!0))for(;d=a.firstChild;)c.appendChild(d);e&&c.appendChild(e),w.remove(a),g(f)&&w.remove(f)}if(x.isCollapsed()){var f=w.getParent(x.getStart(),"LI");if(f){var j=x.getRng(!0),k=w.getParent(d(j,c),"LI");if(k&&k!=f){var l=h(j);return c?e(k,f):e(f,k),i(l),!0}if(!k&&!c&&t(f.parentNode.nodeName))return!0}}},a.on("BeforeExecCommand",function(b){var c,d=b.command.toLowerCase();return"indent"==d?q()&&(c=!0):"outdent"==d&&r()&&(c=!0),c?(a.fire("ExecCommand",{command:b.command}),b.preventDefault(),!0):void 0}),a.addCommand("InsertUnorderedList",function(){u("UL")}),a.addCommand("InsertOrderedList",function(){u("OL")}),a.addCommand("InsertDefinitionList",function(){u("DL")}),a.addQueryStateHandler("InsertUnorderedList",v("UL")),a.addQueryStateHandler("InsertOrderedList",v("OL")),a.addQueryStateHandler("InsertDefinitionList",v("DL")),a.on("keydown",function(b){9!=b.keyCode||tinymce.util.VK.metaKeyPressed(b)||a.dom.getParent(a.selection.getStart(),"LI,DT,DD")&&(b.preventDefault(),b.shiftKey?r():q())})}),a.addButton("indent",{icon:"indent",title:"Increase indent",cmd:"Indent",onPostRender:function(){var b=this;a.on("nodechange",function(){for(var d=a.selection.getSelectedBlocks(),e=!1,f=0,g=d.length;!e&&g>f;f++){var h=d[f].nodeName;e="LI"==h&&c(d[f])||"UL"==h||"OL"==h||"DD"==h}b.disabled(e)})}}),a.on("keydown",function(a){a.keyCode==tinymce.util.VK.BACKSPACE?f.backspaceDelete()&&a.preventDefault():a.keyCode==tinymce.util.VK.DELETE&&f.backspaceDelete(!0)&&a.preventDefault()})}); \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/paste/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/paste/plugin.min.js deleted file mode 100644 index bdb9a440e0..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/paste/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a,b){"use strict";function c(a,b){for(var c,d=[],f=0;f/g]),f(h.parse(e)),i}function f(a){function b(a,b,c){return b||c?"\xa0":" "}return a=d(a,[/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g,/|/g,[/( ?)\u00a0<\/span>( ?)/g,b],/
$/i])}return{filter:d,innerText:e,trimHtml:f}}),d("tinymce/pasteplugin/Clipboard",["tinymce/Env","tinymce/dom/RangeUtils","tinymce/util/VK","tinymce/pasteplugin/Utils"],function(a,b,c,d){return function(e){function f(a){var b,c=e.dom;if(b=e.fire("BeforePastePreProcess",{content:a}),b=e.fire("PastePreProcess",b),a=b.content,!b.isDefaultPrevented()){if(e.hasEventListeners("PastePostProcess")&&!b.isDefaultPrevented()){var d=c.add(e.getBody(),"div",{style:"display:none"},a);b=e.fire("PastePostProcess",{node:d}),c.remove(d),a=b.node.innerHTML}b.isDefaultPrevented()||e.insertContent(a,{merge:e.settings.paste_merge_formats!==!1,data:{paste:!0}})}}function g(a){a=e.dom.encode(a).replace(/\r\n/g,"\n");var b,c=e.dom.getParent(e.selection.getStart(),e.dom.isBlock),g=e.settings.forced_root_block;g&&(b=e.dom.createHTML(g,e.settings.forced_root_block_attrs),b=b.substr(0,b.length-3)+">"),c&&/^(PRE|DIV)$/.test(c.nodeName)||!g?a=d.filter(a,[[/\n/g,"
"]]):(a=d.filter(a,[[/\n\n/g,"

"+b],[/^(.*<\/p>)(

)$/,b+"$1"],[/\n/g,"
"]]),-1!=a.indexOf("

")&&(a=b+a)),f(a)}function h(){function b(a){var b,c,e,f=a.startContainer;if(b=a.getClientRects(),b.length)return b[0];if(a.collapsed&&1==f.nodeType){for(e=f.childNodes[v.startOffset];e&&3==e.nodeType&&!e.data.length;)e=e.nextSibling;if(e)return"BR"==e.tagName&&(c=d.doc.createTextNode("\ufeff"),e.parentNode.insertBefore(c,e),a=d.createRng(),a.setStartBefore(c),a.setEndAfter(c),b=a.getClientRects(),d.remove(c)),b.length?b[0]:void 0}}var c,d=e.dom,f=e.getBody(),g=e.dom.getViewPort(e.getWin()),h=g.y,i=20;if(v=e.selection.getRng(),e.inline&&(c=e.selection.getScrollContainer(),c&&c.scrollTop>0&&(h=c.scrollTop)),v.getClientRects){var j=b(v);if(j)i=h+(j.top-d.getPos(f).y);else{i=h;var k=v.startContainer;k&&(3==k.nodeType&&k.parentNode!=f&&(k=k.parentNode),1==k.nodeType&&(i=d.getPos(k,c||f).y))}}u=d.add(e.getBody(),"div",{id:"mcepastebin",contentEditable:!0,"data-mce-bogus":"all",style:"position: absolute; top: "+i+"px;width: 10px; height: 10px; overflow: hidden; opacity: 0"},A),(a.ie||a.gecko)&&d.setStyle(u,"left","rtl"==d.getStyle(f,"direction",!0)?65535:-65535),d.bind(u,"beforedeactivate focusin focusout",function(a){a.stopPropagation()}),u.focus(),e.selection.select(u,!0)}function i(){if(u){for(var a;a=e.dom.get("mcepastebin");)e.dom.remove(a),e.dom.unbind(a);v&&e.selection.setRng(v)}u=v=null}function j(){var a,b,c,d,f="";for(a=e.dom.select("div[id=mcepastebin]"),b=0;b>8);return decodeURIComponent(escape(c))}function l(a){var b,c,d;return c="",b=a.indexOf(c),-1!==b&&(a=a.substr(b+c.length)),d="",b=a.indexOf(d),-1!==b&&(a=a.substr(0,b)),a}function m(a){var b={};if(a){if(a.getData){var c=a.getData("Text");c&&c.length>0&&-1==c.indexOf(B)&&(b["text/plain"]=c)}if(a.types)for(var d=0;d')}var g,h,i,j=!1;if(c)for(g=0;g0}function s(a){return c.metaKeyPressed(a)&&86==a.keyCode||a.shiftKey&&45==a.keyCode}function t(){e.on("keydown",function(b){function c(a){s(a)&&!a.isDefaultPrevented()&&i()}if(s(b)&&!b.isDefaultPrevented()){if(w=b.shiftKey&&86==b.keyCode,w&&a.webkit&&-1!=navigator.userAgent.indexOf("Version/"))return;if(b.stopImmediatePropagation(),y=(new Date).getTime(),a.ie&&w)return b.preventDefault(),void e.fire("paste",{ieFake:!0});i(),h(),e.once("keyup",c),e.once("paste",function(){e.off("keyup",c)})}}),e.on("paste",function(b){var c=(new Date).getTime(),k=n(b),l=(new Date).getTime()-c,m=(new Date).getTime()-y-l<1e3,q="text"==x.pasteFormat||w;return w=!1,b.isDefaultPrevented()||p(b)?void i():o(b)?void i():(m||b.preventDefault(),!a.ie||m&&!b.ieFake||(h(),e.dom.bind(u,"paste",function(a){a.stopPropagation()}),e.getDoc().execCommand("Paste",!1,null),k["text/html"]=j()),void setTimeout(function(){var a;return r(k,"text/html")?a=k["text/html"]:(a=j(),a==A&&(q=!0)),a=d.trimHtml(a),u&&u.firstChild&&"mcepastebin"===u.firstChild.id&&(q=!0),i(),a.length||(q=!0),q&&(a=r(k,"text/plain")&&-1==a.indexOf("

")?k["text/plain"]:d.innerText(a)),a==A?void(m||e.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.")):void(q?g(a):f(a))},0))}),e.on("dragstart dragend",function(a){z="dragstart"==a.type}),e.on("drop",function(a){var b=q(a);if(!a.isDefaultPrevented()&&!z&&!o(a,b)&&b&&e.settings.paste_filter_drop!==!1){var c=m(a.dataTransfer),h=c["mce-internal"]||c["text/html"]||c["text/plain"];h&&(a.preventDefault(),e.undoManager.transact(function(){c["mce-internal"]&&e.execCommand("Delete"),e.selection.setRng(b),h=d.trimHtml(h),c["text/html"]?f(h):g(h)}))}}),e.on("dragover dragend",function(a){e.settings.paste_data_images&&a.preventDefault()})}var u,v,w,x=this,y=0,z=!1,A="%MCEPASTEBIN%",B="data:text/mce-internal,";x.pasteHtml=f,x.pasteText=g,e.on("preInit",function(){t(),e.parser.addNodeFilter("img",function(b,c,d){function f(a){return a.data&&a.data.paste===!0}function g(b){b.attr("data-mce-object")||k===a.transparentSrc||b.remove()}function h(a){return 0===a.indexOf("webkit-fake-url")}function i(a){return 0===a.indexOf("data:")}if(!e.settings.paste_data_images&&f(d))for(var j=b.length;j--;){var k=b[j].attributes.map.src;k&&(h(k)?g(b[j]):!e.settings.allow_html_data_urls&&i(k)&&g(b[j]))}})})}}),d("tinymce/pasteplugin/WordFilter",["tinymce/util/Tools","tinymce/html/DomParser","tinymce/html/Schema","tinymce/html/Serializer","tinymce/html/Node","tinymce/pasteplugin/Utils"],function(a,b,c,d,e,f){function g(a){return/h?g&&(g=g.parent.parent):(j=g,g=null)),g&&g.name==b?g.append(a):(j=j||g,g=new e(b,1),f>1&&g.attr("start",""+f),a.wrap(g)),a.name="li",h>k&&j&&j.lastChild.append(g),k=h,d(a),c(a,/^\u00a0+/),c(a,/^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/),c(a,/^\u00a0+/)}for(var g,j,k=1,l=[],m=a.firstChild;"undefined"!=typeof m&&null!==m;)if(l.push(m),m=m.walk(),null!==m)for(;"undefined"!=typeof m&&m.parent!==a;)m=m.walk();for(var n=0;n]+id="?docs-internal-[^>]*>/gi,""),q=q.replace(/
/gi,""),o=k.paste_retain_style_properties,o&&(p=a.makeMap(o.split(/[, ]/))),k.paste_enable_default_filters!==!1&&g(l.content)){l.wordContent=!0,q=f.filter(q,[//gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(a,b){return b.length>0?b.replace(/./," ").slice(Math.floor(b.length/2)).split("").join("\xa0"):""}]]);var r=k.paste_word_valid_elements;r||(r="-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody");var s=new c({valid_elements:r,valid_children:"-li[p]"});a.each(s.elements,function(a){a.attributes["class"]||(a.attributes["class"]={},a.attributesOrder.push("class")),a.attributes.style||(a.attributes.style={},a.attributesOrder.push("style"))});var t=new b({},s);t.addAttributeFilter("style",function(a){for(var b,c=a.length;c--;)b=a[c],b.attr("style",n(b,b.attr("style"))),"span"==b.name&&b.parent&&!b.attributes.length&&b.unwrap()}),t.addAttributeFilter("class",function(a){for(var b,c,d=a.length;d--;)b=a[d],c=b.attr("class"),/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(c)&&b.remove(),b.attr("class",null)}),t.addNodeFilter("del",function(a){for(var b=a.length;b--;)a[b].remove()}),t.addNodeFilter("a",function(a){for(var b,c,d,e=a.length;e--;)if(b=a[e],c=b.attr("href"),d=b.attr("name"),c&&-1!=c.indexOf("#_msocom_"))b.remove();else if(c&&0===c.indexOf("file://")&&(c=c.split("#")[1],c&&(c="#"+c)),c||d){if(d&&!/^_?(?:toc|edn|ftn)/i.test(d)){b.unwrap();continue}b.attr({href:c,name:d})}else b.unwrap()});var u=t.parse(q);k.paste_convert_word_fake_lists!==!1&&m(u),l.content=new d({},s).serialize(u)}})}return j.isWordContent=g,j}),d("tinymce/pasteplugin/Quirks",["tinymce/Env","tinymce/util/Tools","tinymce/pasteplugin/WordFilter","tinymce/pasteplugin/Utils"],function(a,b,c,d){return function(e){function f(a){e.on("BeforePastePreProcess",function(b){b.content=a(b.content)})}function g(a){if(!c.isWordContent(a))return a;var f=[];b.each(e.schema.getBlockElements(),function(a,b){f.push(b)});var g=new RegExp("(?:
 [\\s\\r\\n]+|
)*(<\\/?("+f.join("|")+")[^>]*>)(?:
 [\\s\\r\\n]+|
)*","g");return a=d.filter(a,[[g,"$1"]]),a=d.filter(a,[[/

/g,"

"],[/
/g," "],[/

/g,"
"]])}function h(a){if(c.isWordContent(a))return a;var b=e.settings.paste_webkit_styles;if(e.settings.paste_remove_styles_if_webkit===!1||"all"==b)return a;if(b&&(b=b.split(/[, ]/)),b){var d=e.dom,f=e.selection.getNode();a=a.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(a,c,e,g){var h=d.parseStyle(e,"span"),i={};if("none"===b)return c+g;for(var j=0;j]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return a=a.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(a,b,c,d){return b+' style="'+c+'"'+d})}a.webkit&&f(h),a.ie&&f(g)}}),d("tinymce/pasteplugin/Plugin",["tinymce/PluginManager","tinymce/pasteplugin/Clipboard","tinymce/pasteplugin/WordFilter","tinymce/pasteplugin/Quirks"],function(a,b,c,d){var e;a.add("paste",function(a){function f(){"text"==g.pasteFormat?(this.active(!1),g.pasteFormat="html"):(g.pasteFormat="text",this.active(!0),e||(a.windowManager.alert("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off."),e=!0))}var g,h=this,i=a.settings;h.clipboard=g=new b(a),h.quirks=new d(a),h.wordFilter=new c(a),a.settings.paste_as_text&&(h.clipboard.pasteFormat="text"),i.paste_preprocess&&a.on("PastePreProcess",function(a){i.paste_preprocess.call(h,h,a)}),i.paste_postprocess&&a.on("PastePostProcess",function(a){i.paste_postprocess.call(h,h,a)}),a.addCommand("mceInsertClipboardContent",function(a,b){b.content&&h.clipboard.pasteHtml(b.content),b.text&&h.clipboard.pasteText(b.text)}),a.paste_block_drop&&a.on("dragend dragover draggesture dragdrop drop drag",function(a){a.preventDefault(),a.stopPropagation()}),a.settings.paste_data_images||a.on("drop",function(a){var b=a.dataTransfer;b&&b.files&&b.files.length>0&&a.preventDefault()}),a.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:f,active:"text"==h.clipboard.pasteFormat}),a.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:g.pasteFormat,onclick:f})})}),f(["tinymce/pasteplugin/Utils"])}(this); \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/table/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/table/plugin.min.js deleted file mode 100644 index b9808cb605..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/table/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a,b){"use strict";function c(a,b){for(var c,d=[],g=0;g10)&&(b.innerHTML='
')}return{getSpanVal:b,paddCell:c}}),d("tinymce/tableplugin/TableGrid",["tinymce/util/Tools","tinymce/Env","tinymce/tableplugin/Utils"],function(a,c,d){var e=a.each,f=d.getSpanVal;return function(g,h){function i(){var a=0;G=[],H=0,e(["thead","tbody","tfoot"],function(b){var c=M.select("> "+b+" tr",h);e(c,function(c,d){d+=a,e(M.select("> td, > th",c),function(a,c){var e,g,h,i;if(G[d])for(;G[d][c];)c++;for(h=f(a,"rowspan"),i=f(a,"colspan"),g=d;d+h>g;g++)for(G[g]||(G[g]=[]),e=c;c+i>e;e++)G[g][e]={part:b,real:g==d&&e==c,elm:a,rowspan:h,colspan:i};H=Math.max(H,c+1)})}),a+=c.length})}function j(a,b){return a=a.cloneNode(b),a.removeAttribute("id"),a}function k(a,b){var c;return c=G[b],c?c[a]:void 0}function l(a,b,c){a&&(c=parseInt(c,10),1===c?a.removeAttribute(b,1):a.setAttribute(b,c,1))}function m(a){return a&&(M.hasClass(a.elm,"mce-item-selected")||a==K)}function n(){var a=[];return e(h.rows,function(b){e(b.cells,function(c){return M.hasClass(c,"mce-item-selected")||K&&c==K.elm?(a.push(b),!1):void 0})}),a}function o(){var a=M.createRng();a.setStartAfter(h),a.setEndAfter(h),L.setRng(a),M.remove(h)}function p(b){var f,h={};return g.settings.table_clone_elements!==!1&&(h=a.makeMap((g.settings.table_clone_elements||"strong em b i span font h1 h2 h3 h4 h5 h6 p div").toUpperCase(),/[ ,]/)),a.walk(b,function(a){var d;return 3==a.nodeType?(e(M.getParents(a.parentNode,null,b).reverse(),function(a){h[a.nodeName]&&(a=j(a,!1),f?d&&d.appendChild(a):f=d=a,d=a)}),d&&(d.innerHTML=c.ie?" ":'
'),!1):void 0},"childNodes"),b=j(b,!1),l(b,"rowSpan",1),l(b,"colSpan",1),f?b.appendChild(f):d.paddCell(b),b}function q(){var a,b=M.createRng();return e(M.select("tr",h),function(a){0===a.cells.length&&M.remove(a)}),0===M.select("tr",h).length?(b.setStartBefore(h),b.setEndBefore(h),L.setRng(b),void M.remove(h)):(e(M.select("thead,tbody,tfoot",h),function(a){0===a.rows.length&&M.remove(a)}),i(),void(I&&(a=G[Math.min(G.length-1,I.y)],a&&(L.select(a[Math.min(a.length-1,I.x)].elm,!0),L.collapse(!0)))))}function r(a,b,c,d){var e,f,g,h,i;for(e=G[b][a].elm.parentNode,g=1;c>=g;g++)if(e=M.getNext(e,"tr")){for(f=a;f>=0;f--)if(i=G[b+g][f].elm,i.parentNode==e){for(h=1;d>=h;h++)M.insertAfter(p(i),i);break}if(-1==f)for(h=1;d>=h;h++)e.insertBefore(p(e.cells[0]),e.cells[0])}}function s(){e(G,function(a,b){e(a,function(a,c){var d,e,g;if(m(a)&&(a=a.elm,d=f(a,"colspan"),e=f(a,"rowspan"),d>1||e>1)){for(l(a,"rowSpan",1),l(a,"colSpan",1),g=0;d-1>g;g++)M.insertAfter(p(a),a);r(c,b,e-1,d)}})})}function t(b,c,d){var f,g,h,j,n,o,p,r,t,u,v;if(b?(f=B(b),g=f.x,h=f.y,j=g+(c-1),n=h+(d-1)):(I=J=null,e(G,function(a,b){e(a,function(a,c){m(a)&&(I||(I={x:c,y:b}),J={x:c,y:b})})}),I&&(g=I.x,h=I.y,j=J.x,n=J.y)),r=k(g,h),t=k(j,n),r&&t&&r.part==t.part){for(s(),i(),r=k(g,h).elm,l(r,"colSpan",j-g+1),l(r,"rowSpan",n-h+1),p=h;n>=p;p++)for(o=g;j>=o;o++)G[p]&&G[p][o]&&(b=G[p][o].elm,b!=r&&(u=a.grep(b.childNodes),e(u,function(a){r.appendChild(a)}),u.length&&(u=a.grep(r.childNodes),v=0,e(u,function(a){"BR"==a.nodeName&&M.getAttrib(a,"data-mce-bogus")&&v++0&&G[c-1][h]&&(o=G[c-1][h].elm,q=f(o,"rowSpan"),q>1)){l(o,"rowSpan",q+1);continue}}else if(q=f(d,"rowspan"),q>1){l(d,"rowSpan",q+1);continue}n=p(d),l(n,"colSpan",d.colSpan),k.appendChild(n),g=d}k.hasChildNodes()&&(a?i.parentNode.insertBefore(k,i):M.insertAfter(k,i))}}function v(a){var b,c;e(G,function(c){return e(c,function(c,d){return m(c)&&(b=d,a)?!1:void 0}),a?!b:void 0}),e(G,function(d,e){var g,h,i;d[b]&&(g=d[b].elm,g!=c&&(i=f(g,"colspan"),h=f(g,"rowspan"),1==i?a?(g.parentNode.insertBefore(p(g),g),r(b,e,h-1,i)):(M.insertAfter(p(g),g),r(b,e,h-1,i)):l(g,"colSpan",g.colSpan+1),c=g))})}function w(){var b=[];e(G,function(c){e(c,function(c,d){m(c)&&-1===a.inArray(b,d)&&(e(G,function(a){var b,c=a[d].elm;b=f(c,"colSpan"),b>1?l(c,"colSpan",b-1):M.remove(c)}),b.push(d))})}),q()}function x(){function a(a){var b,c;e(a.cells,function(a){var c=f(a,"rowSpan");c>1&&(l(a,"rowSpan",c-1),b=B(a),r(b.x,b.y,1,1))}),b=B(a.cells[0]),e(G[b.y],function(a){var b;a=a.elm,a!=c&&(b=f(a,"rowSpan"),1>=b?M.remove(a):l(a,"rowSpan",b-1),c=a)})}var b;b=n(),e(b.reverse(),function(b){a(b)}),q()}function y(){var a=n();return M.remove(a),q(),a}function z(){var a=n();return e(a,function(b,c){a[c]=j(b,!0)}),a}function A(a,b){var c=n(),d=c[b?0:c.length-1],f=d.cells.length;a&&(e(G,function(a){var b;return f=0,e(a,function(a){a.real&&(f+=a.colspan),a.elm.parentNode==d&&(b=1)}),b?!1:void 0}),b||a.reverse(),e(a,function(a){var c,e,g=a.cells.length;for(c=0;g>c;c++)e=a.cells[c],l(e,"colSpan",1),l(e,"rowSpan",1);for(c=g;f>c;c++)a.appendChild(p(a.cells[g-1]));for(c=f;g>c;c++)M.remove(a.cells[c]);b?d.parentNode.insertBefore(a,d):M.insertAfter(a,d)}),M.removeClass(M.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"))}function B(a){var b;return e(G,function(c,d){return e(c,function(c,e){return c.elm==a?(b={x:e,y:d},!1):void 0}),!b}),b}function C(a){I=B(a)}function D(){var a,b;return a=b=0,e(G,function(c,d){e(c,function(c,e){var f,g;m(c)&&(c=G[d][e],e>a&&(a=e),d>b&&(b=d),c.real&&(f=c.colspan-1,g=c.rowspan-1,f&&e+f>a&&(a=e+f),g&&d+g>b&&(b=d+g)))})}),{x:a,y:b}}function E(a){var b,c,d,e,f,g,h,i,j,k;if(J=B(a),I&&J){for(b=Math.min(I.x,J.x),c=Math.min(I.y,J.y),d=Math.max(I.x,J.x),e=Math.max(I.y,J.y),f=d,g=e,k=c;g>=k;k++)a=G[k][b],a.real||b-(a.colspan-1)=j;j++)a=G[c][j],a.real||c-(a.rowspan-1)=k;k++)for(j=b;d>=j;j++)a=G[k][j],a.real&&(h=a.colspan-1,i=a.rowspan-1,h&&j+h>f&&(f=j+h),i&&k+i>g&&(g=k+i));for(M.removeClass(M.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),k=c;g>=k;k++)for(j=b;f>=j;j++)G[k][j]&&M.addClass(G[k][j].elm,"mce-item-selected")}}function F(a,b){var c,d,e;c=B(a),d=c.y*H+c.x;do{if(d+=b,e=k(d%H,Math.floor(d/H)),!e)break;if(e.elm!=a)return L.select(e.elm,!0),M.isEmpty(e.elm)&&L.collapse(!0),!0}while(e.elm==a);return!1}var G,H,I,J,K,L=g.selection,M=L.dom;h=h||M.getParent(L.getStart(!0),"table"),i(),K=M.getParent(L.getStart(!0),"th,td"),K&&(I=B(K),J=D(),K=k(I.x,I.y)),a.extend(this,{deleteTable:o,split:s,merge:t,insertRow:u,insertCol:v,deleteCols:w,deleteRows:x,cutRows:y,copyRows:z,pasteRows:A,getPos:B,setStartCell:C,setEndCell:E,moveRelIdx:F,refresh:i})}}),d("tinymce/tableplugin/Quirks",["tinymce/util/VK","tinymce/Env","tinymce/util/Tools","tinymce/tableplugin/Utils"],function(a,b,c,d){var e=c.each,f=d.getSpanVal;return function(g){function h(){function b(b){function c(a,c){var e=a?"previousSibling":"nextSibling",f=g.dom.getParent(c,"tr"),h=f[e];if(h)return q(g,c,h,a),b.preventDefault(),!0;var k=g.dom.getParent(f,"table"),l=f.parentNode,m=l.nodeName.toLowerCase();if("tbody"===m||m===(a?"tfoot":"thead")){var n=d(a,k,l,"tbody");if(null!==n)return i(a,n,c)}return j(a,f,e,k)}function d(a,b,c,d){var e=g.dom.select(">"+d,b),f=e.indexOf(c);if(a&&0===f||!a&&f===e.length-1)return h(a,b);if(-1===f){var i="thead"===c.tagName.toLowerCase()?0:e.length-1;return e[i]}return e[f+(a?-1:1)]}function h(a,b){var c=a?"thead":"tfoot",d=g.dom.select(">"+c,b);return 0!==d.length?d[0]:null}function i(a,c,d){var e=k(c,a);return e&&q(g,d,e,a),b.preventDefault(),!0}function j(a,d,e,f){var h=f[e];if(h)return l(h),!0;var i=g.dom.getParent(f,"td,th");if(i)return c(a,i,b);var j=k(d,!a);return l(j),b.preventDefault(),!1}function k(a,b){var c=a&&a[b?"lastChild":"firstChild"];return c&&"BR"===c.nodeName?g.dom.getParent(c,"td,th"):c}function l(a){g.selection.setCursorLocation(a,0)}function m(){return t==a.UP||t==a.DOWN}function n(a){var b=a.selection.getNode(),c=a.dom.getParent(b,"tr");return null!==c}function o(a){for(var b=0,c=a;c.previousSibling;)c=c.previousSibling,b+=f(c,"colspan");return b}function p(a,b){var c=0,d=0;return e(a.children,function(a,e){return c+=f(a,"colspan"),d=e,c>b?!1:void 0}),d}function q(a,b,c,d){var e=o(g.dom.getParent(b,"td,th")),f=p(c,e),h=c.childNodes[f],i=k(h,d);l(i||h)}function r(a){var b=g.selection.getNode(),c=g.dom.getParent(b,"td,th"),d=g.dom.getParent(a,"td,th");return c&&c!==d&&s(c,d)}function s(a,b){return g.dom.getParent(a,"TABLE")===g.dom.getParent(b,"TABLE")}var t=b.keyCode;if(m()&&n(g)){var u=g.selection.getNode();setTimeout(function(){r(u)&&c(!b.shiftKey&&t===a.UP,u,b)},0)}}g.on("KeyDown",function(a){b(a)})}function i(){function a(a,b){var c,d=b.ownerDocument,e=d.createRange();return e.setStartBefore(b),e.setEnd(a.endContainer,a.endOffset),c=d.createElement("body"),c.appendChild(e.cloneContents()),0===c.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length}g.on("KeyDown",function(b){var c,d,e=g.dom;(37==b.keyCode||38==b.keyCode)&&(c=g.selection.getRng(),d=e.getParent(c.startContainer,"table"),d&&g.getBody().firstChild==d&&a(c,d)&&(c=e.createRng(),c.setStartBefore(d),c.setEndBefore(d),g.selection.setRng(c),b.preventDefault()))})}function j(){g.on("KeyDown SetContent VisualAid",function(){var a;for(a=g.getBody().lastChild;a;a=a.previousSibling)if(3==a.nodeType){if(a.nodeValue.length>0)break}else if(1==a.nodeType&&("BR"==a.tagName||!a.getAttribute("data-mce-bogus")))break;a&&"TABLE"==a.nodeName&&(g.settings.forced_root_block?g.dom.add(g.getBody(),g.settings.forced_root_block,g.settings.forced_root_block_attrs,b.ie&&b.ie<11?" ":'
'):g.dom.add(g.getBody(),"br",{"data-mce-bogus":"1"}))}),g.on("PreProcess",function(a){var b=a.node.lastChild;b&&("BR"==b.nodeName||1==b.childNodes.length&&("BR"==b.firstChild.nodeName||"\xa0"==b.firstChild.nodeValue))&&b.previousSibling&&"TABLE"==b.previousSibling.nodeName&&g.dom.remove(b)})}function k(){function a(a,b,c,d){var e,f,g,h=3,i=a.dom.getParent(b.startContainer,"TABLE");return i&&(e=i.parentNode),f=b.startContainer.nodeType==h&&0===b.startOffset&&0===b.endOffset&&d&&("TR"==c.nodeName||c==e),g=("TD"==c.nodeName||"TH"==c.nodeName)&&!d,f||g}function b(){var b=g.selection.getRng(),c=g.selection.getNode(),d=g.dom.getParent(b.startContainer,"TD,TH");if(a(g,b,c,d)){d||(d=c);for(var e=d.lastChild;e.lastChild;)e=e.lastChild;3==e.nodeType&&(b.setEnd(e,e.data.length),g.selection.setRng(b))}}g.on("KeyDown",function(){b()}),g.on("MouseDown",function(a){2!=a.button&&b()})}function l(){function b(a){g.selection.select(a,!0),g.selection.collapse(!0)}function e(a){g.$(a).empty(),d.paddCell(a)}g.on("keydown",function(d){if((d.keyCode==a.DELETE||d.keyCode==a.BACKSPACE)&&!d.isDefaultPrevented()){var f,h,i,j;if(f=g.dom.getParent(g.selection.getStart(),"table")){if(h=g.dom.select("td,th",f),i=c.grep(h,function(a){return g.dom.hasClass(a,"mce-item-selected")}),0===i.length)return j=g.dom.getParent(g.selection.getStart(),"td,th"),void(g.selection.isCollapsed()&&j&&g.dom.isEmpty(j)&&(d.preventDefault(),e(j),b(j)));d.preventDefault(),h.length==i.length?g.execCommand("mceTableDelete"):(c.each(i,e),b(i[0]))}}})}l(),b.webkit&&(h(),k()),b.gecko&&(i(),j()),b.ie>10&&(i(),j())}}),d("tinymce/tableplugin/CellSelection",["tinymce/tableplugin/TableGrid","tinymce/dom/TreeWalker","tinymce/util/Tools"],function(a,b,c){return function(d){function e(a){d.getBody().style.webkitUserSelect="",(a||l)&&(d.dom.removeClass(d.dom.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),l=!1)}function f(b){var c,e,f=b.target;if(!j&&h&&(g||f!=h)&&("TD"==f.nodeName||"TH"==f.nodeName)){e=k.getParent(f,"table"),e==i&&(g||(g=new a(d,e),g.setStartCell(h),d.getBody().style.webkitUserSelect="none"),g.setEndCell(f),l=!0),c=d.selection.getSel();try{c.removeAllRanges?c.removeAllRanges():c.empty()}catch(m){}b.preventDefault()}}var g,h,i,j,k=d.dom,l=!0;return d.on("MouseDown",function(a){2==a.button||j||(e(),h=k.getParent(a.target,"td,th"),i=k.getParent(h,"table"))}),d.on("mouseover",f),d.on("remove",function(){k.unbind(d.getDoc(),"mouseover",f)}),d.on("MouseUp",function(){function a(a,d){var f=new b(a,a);do{if(3==a.nodeType&&0!==c.trim(a.nodeValue).length)return void(d?e.setStart(a,0):e.setEnd(a,a.nodeValue.length));if("BR"==a.nodeName)return void(d?e.setStartBefore(a):e.setEndBefore(a))}while(a=d?f.next():f.prev())}var e,f,j,l,m,n=d.selection;if(h){if(g&&(d.getBody().style.webkitUserSelect=""),f=k.select("td.mce-item-selected,th.mce-item-selected"),f.length>0){e=k.createRng(),l=f[0],e.setStartBefore(l),e.setEndAfter(l),a(l,1),j=new b(l,k.getParent(f[0],"table"));do if("TD"==l.nodeName||"TH"==l.nodeName){if(!k.hasClass(l,"mce-item-selected"))break;m=l}while(l=j.next());a(m),n.setRng(e)}d.nodeChanged(),h=g=i=null}}),d.on("KeyUp Drop SetContent",function(a){e("setcontent"==a.type),h=g=i=null,j=!1}),d.on("ObjectResizeStart ObjectResized",function(a){j="objectresized"!=a.type}),{clear:e}}}),d("tinymce/tableplugin/Dialogs",["tinymce/util/Tools","tinymce/Env"],function(a,b){var c=a.each;return function(d){function e(){var a=d.settings.color_picker_callback;return a?function(){var b=this;a.call(d,function(a){b.value(a).fire("change")},b.value())}:void 0}function f(a){return{title:"Advanced",type:"form",defaults:{onchange:function(){l(a,this.parents().reverse()[0],"style"==this.name())}},items:[{label:"Style",name:"style",type:"textbox"},{type:"form",padding:0,formItemDefaults:{layout:"grid",alignH:["start","right"]},defaults:{size:7},items:[{label:"Border color",type:"colorbox",name:"borderColor",onaction:e()},{label:"Background color",type:"colorbox",name:"backgroundColor",onaction:e()}]}]}}function g(a){return a?a.replace(/px$/,""):""}function h(a){return/^[0-9]+$/.test(a)&&(a+="px"),a}function i(a){c("left center right".split(" "),function(b){d.formatter.remove("align"+b,{},a)})}function j(a){c("top middle bottom".split(" "),function(b){d.formatter.remove("valign"+b,{},a)})}function k(b,c,d){function e(b,d){return d=d||[],a.each(b,function(a){var b={text:a.text||a.title};a.menu?b.menu=e(a.menu):(b.value=a.value,c&&c(b)),d.push(b)}),d}return e(b,d||[])}function l(a,b,c){var d=b.toJSON(),e=a.parseStyle(d.style);c?(b.find("#borderColor").value(e["border-color"]||"")[0].fire("change"),b.find("#backgroundColor").value(e["background-color"]||"")[0].fire("change")):(e["border-color"]=d.borderColor,e["background-color"]=d.backgroundColor),b.find("#style").value(a.serializeStyle(a.parseStyle(a.serializeStyle(e))))}function m(a,b,c){var d=a.parseStyle(a.getAttrib(c,"style"));d["border-color"]&&(b.borderColor=d["border-color"]),d["background-color"]&&(b.backgroundColor=d["background-color"]),b.style=a.serializeStyle(d)}function n(a,b,d){var e=a.parseStyle(a.getAttrib(b,"style"));c(d,function(a){e[a.name]=a.value}),a.setAttrib(b,"style",a.serializeStyle(a.parseStyle(a.serializeStyle(e))))}var o=this;o.tableProps=function(){o.table(!0)},o.table=function(e){function j(){function c(a,b,d){if("TD"===a.tagName||"TH"===a.tagName)v.setStyle(a,b,d);else if(a.children)for(var e=0;e',p.insertBefore(e,p.firstChild)),i(p),w.align&&d.formatter.apply("align"+w.align,{},p),d.focus(),d.addVisual()})}function o(a,b){function c(a,c){for(var d=0;dc;c++){for(f+="",d=0;a>d;d++)f+=""+(g.ie?" ":"
")+"";f+=""}return f+="",e.undoManager.transact(function(){e.insertContent(f),h=e.dom.get("__mce"),e.dom.setAttrib(h,"id",null),e.dom.setAttribs(h,e.settings.table_default_attributes||{}),e.dom.setStyles(h,e.settings.table_default_styles||{})}),h}function i(a,b){function c(){a.disabled(!e.dom.getParent(e.selection.getStart(),b)),e.selection.selectorChanged(b,function(b){a.disabled(!b)})}e.initialized?c():e.on("init",c)}function k(){i(this,"table")}function l(){i(this,"td,th")}function m(){var a="";a='';for(var b=0;10>b;b++){a+="";for(var c=0;10>c;c++)a+='';a+=""}return a+="
",a+=''}function n(a,b,c){var d,f,g,h,i,j=c.getEl().getElementsByTagName("table")[0],k=c.isRtl()||"tl-tr"==c.parent().rel;for(j.nextSibling.innerHTML=a+1+" x "+(b+1),k&&(a=9-a),f=0;10>f;f++)for(d=0;10>d;d++)h=j.rows[f].childNodes[d].firstChild,i=(k?d>=a:a>=d)&&b>=f,e.dom.toggleClass(h,"mce-active",i),i&&(g=h);return g.parentNode}var o,p=this,q=new d(e);e.settings.table_grid===!1?e.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",onclick:q.table}):e.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",ariaHideMenu:!0,onclick:function(a){a.aria&&(this.parent().hideAll(),a.stopImmediatePropagation(),q.table())},onshow:function(){n(0,0,this.menu.items()[0])},onhide:function(){var a=this.menu.items()[0].getEl().getElementsByTagName("a");e.dom.removeClass(a,"mce-active"),e.dom.addClass(a[0],"mce-active")},menu:[{type:"container",html:m(),onPostRender:function(){this.lastX=this.lastY=0},onmousemove:function(a){var b,c,d=a.target;"A"==d.tagName.toUpperCase()&&(b=parseInt(d.getAttribute("data-mce-x"),10),c=parseInt(d.getAttribute("data-mce-y"),10),(this.isRtl()||"tl-tr"==this.parent().rel)&&(b=9-b),(b!==this.lastX||c!==this.lastY)&&(n(b,c,a.control),this.lastX=b,this.lastY=c))},onclick:function(a){var b=this;"A"==a.target.tagName.toUpperCase()&&(a.preventDefault(),a.stopPropagation(),b.parent().cancel(),e.undoManager.transact(function(){h(b.lastX+1,b.lastY+1)}),e.addVisual())}}]}),e.addMenuItem("tableprops",{text:"Table properties",context:"table",onPostRender:k,onclick:q.tableProps}),e.addMenuItem("deletetable",{text:"Delete table",context:"table",onPostRender:k,cmd:"mceTableDelete"}),e.addMenuItem("cell",{separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:f("mceTableCellProps"),onPostRender:l},{text:"Merge cells",onclick:f("mceTableMergeCells"),onPostRender:l},{text:"Split cell",onclick:f("mceTableSplitCells"),onPostRender:l}]}),e.addMenuItem("row",{text:"Row",context:"table",menu:[{text:"Insert row before",onclick:f("mceTableInsertRowBefore"),onPostRender:l},{text:"Insert row after",onclick:f("mceTableInsertRowAfter"),onPostRender:l},{text:"Delete row",onclick:f("mceTableDeleteRow"),onPostRender:l},{text:"Row properties",onclick:f("mceTableRowProps"),onPostRender:l},{text:"-"},{text:"Cut row",onclick:f("mceTableCutRow"),onPostRender:l},{text:"Copy row",onclick:f("mceTableCopyRow"),onPostRender:l},{text:"Paste row before",onclick:f("mceTablePasteRowBefore"),onPostRender:l},{text:"Paste row after",onclick:f("mceTablePasteRowAfter"),onPostRender:l}]}),e.addMenuItem("column",{text:"Column",context:"table",menu:[{text:"Insert column before",onclick:f("mceTableInsertColBefore"),onPostRender:l},{text:"Insert column after",onclick:f("mceTableInsertColAfter"),onPostRender:l},{text:"Delete column",onclick:f("mceTableDeleteCol"),onPostRender:l}]});var r=[];j("inserttable tableprops deletetable | cell row column".split(" "),function(a){"|"==a?r.push({text:"-"}):r.push(e.menuItems[a])}),e.addButton("table",{type:"menubutton",title:"Table",menu:r}),g.isIE||e.on("click",function(a){a=a.target,"TABLE"===a.nodeName&&(e.selection.select(a),e.nodeChanged())}),p.quirks=new b(e),e.on("Init",function(){p.cellSelection=new c(e)}),e.on("PreInit",function(){e.serializer.addAttributeFilter("data-mce-cell-padding,data-mce-border,data-mce-border-color",function(a,b){for(var c=a.length;c--;)a[c].attr(b,null)})}),j({mceTableSplitCells:function(a){a.split()},mceTableMergeCells:function(a){var b;b=e.dom.getParent(e.selection.getStart(),"th,td"),e.dom.select("td.mce-item-selected,th.mce-item-selected").length?a.merge():q.merge(a,b)},mceTableInsertRowBefore:function(a){a.insertRow(!0)},mceTableInsertRowAfter:function(a){a.insertRow()},mceTableInsertColBefore:function(a){a.insertCol(!0)},mceTableInsertColAfter:function(a){a.insertCol()},mceTableDeleteCol:function(a){a.deleteCols()},mceTableDeleteRow:function(a){a.deleteRows()},mceTableCutRow:function(a){o=a.cutRows()},mceTableCopyRow:function(a){o=a.copyRows()},mceTablePasteRowBefore:function(a){a.pasteRows(o,!0)},mceTablePasteRowAfter:function(a){a.pasteRows(o)},mceTableDelete:function(a){a.deleteTable()}},function(b,c){e.addCommand(c,function(){var c=new a(e);c&&(b(c),e.execCommand("mceRepaint"),p.cellSelection.clear())})}),j({mceInsertTable:q.table,mceTableProps:function(){q.table(!0)},mceTableRowProps:q.row,mceTableCellProps:q.cell},function(a,b){e.addCommand(b,function(b,c){a(c)})}),e.settings.table_tab_navigation!==!1&&e.on("keydown",function(b){var c,d,f;9==b.keyCode&&(c=e.dom.getParent(e.selection.getStart(),"th,td"),c&&(b.preventDefault(),d=new a(e),f=b.shiftKey?-1:1,e.undoManager.transact(function(){!d.moveRelIdx(c,f)&&f>0&&(d.insertRow(),d.refresh(),d.moveRelIdx(c,f))})))}),p.insertTable=h}var j=e.each;h.add("table",i)})}(this); \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.inline.min.css b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.inline.min.css deleted file mode 100644 index c0dc150c45..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.inline.min.css +++ /dev/null @@ -1 +0,0 @@ -.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:0 0;text-decoration:none;color:#000;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:400;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px!important;height:9px!important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#39f;color:#fff}.mce-spellchecker-word{border-bottom:2px solid red;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid green;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#39f!important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.min.css b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.min.css deleted file mode 100644 index b65aa3efe1..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/content.min.css +++ /dev/null @@ -1 +0,0 @@ -body{background-color:#FFF;color:#000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:0 0;text-decoration:none;color:#000;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:400;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px!important;height:9px!important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#39f;color:#fff}.mce-spellchecker-word{border-bottom:2px solid red;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid green;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#39f!important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.eot b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.eot deleted file mode 100644 index c8abe592bdb5e0e639e0e9d7011943d787e76b1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9112 zcmcgyX>c6Jb?%>3;LN`@QeI*Ry|+W9%1M#yHd1`irxxoLUadu5YKl{`Fol zac$!>#yZ(Wc8Z;4&$2V@1Y2N(>;g*j>@@xui?YLLdy+kk+B|y-EgkF_TAo6$Q|uhZ zrP($%#76Ms&XmxB7-?oM)7i-VM}|vnX6-q5H!u%7#9Xo%{STFS(JBbG4+xo9j{}a^vPM*1V>0RFb zD(df`UOj#8#Qcx?-u@|L>F=Qa)S3B9i|iiuBgQgm)YE6@&n$eo|0GND*l<>St60pePhx(j~dEX68}>oarR}UX$E1by=-l&kPS|v}$J9bA@m{m%FYgbb4-QK_KU%v*6BZv(@2D zEvFe42_~{m2XLcXfJmL{M`(3tjC)p(g#!CNp@s3vb1HwI96D-c{(Vsh4Z%&b!(N zgJ#p4dQ<3fZAk}P9xXLia9IYhN>GOha8U*ucEvV^_%P2IQEu3V73FO_X@M2Pst_+u zWr|mh?w&u{+#Y)6HqD-N)x{V851rT0 zi21{aciLZp{UsSRprvh$#WP7P&}tI8dlQR%)73;xQo_0~GnWgxgT$R^G-$2RkQ&yE z(gq@T;DgtBS)swjtvR^^jmCUdXf)=ufep;%i>zP&j6TN(url`n8W|tL4pv5{c)^bF zC{OWimQe^{U#*TY?4n(e;VzZ+>mo3-@dgPSofl3jA>`KAe|e(Hay%q;c>0K&Fqhd z6X94mW%egfhy?g6UHN<$CGMah-fy@4yN{{4~11>bSu;5Cdfz$*Z3({N>Z}nJfTuM?{A*2wspD!%DE;;)7vdI*F4L~>V zVGn>az!F~S;AMWk!W+=cbbxC+IF*26v{l$T)Yaa_*Hh_kPnW-D!x!SA=;-8?7?gJ@rmT2&C?`@S|PYrl1-bzDTv1;ci32C|_oc&EJ^o!j<^bWJC76 zTa=(vF5pE%K779N>v_`4IWvdtKuQ`&l&gAqJsU6>_*a*7>u=^~uW?!}QQCP;;Nk)k zCV3R=FsBYPp3 ztN80>(^!jAN=qi9S}r@JmF>|f%}HhnUJL+8<_^y|+p>2wl^Wf<#YWC|p8WFtl_v_} zRwLYIXm@&Mr7QOi6z{F1kr#W8zI0Ap+&U1BML56h0|+JjEsgdt3J+k4Ffke7$*~j< z8Jg_q%U=Gvcb(5(e`oss(`^6J^G5>j@mW6mv%s@&eMFud=K?Zt)gRBx5ne7td51N` zr?{mFKI>io`sHk2$Lag0-?^^+@z1>L-u3qaN1k8Wf9a#Qo(*8A!kAYuegtmnXF(7U z3L$Rep+qmQ*oDz)kOIc`@{U9sU>d4Aj6F%AZETv4joPXL1YUVK1a!iq`lw2SUX;UU z=>^QIfl~xwAViQpTH#|Qt0Q3$dHt2kvHlLLKlXYiqwm&(!Pj*| zE8YsKmm38z(s=BBWw+*Y1pT>aXF@@|3~y{k=E-0PTL(Xs_Kx=6 zU;D4JKV*N-zR!N}o8ASB_7vMNR-#=dON)J(|}gx{6Th_f)CwjCbwcG4q0dFKu!7Zy1L7yswD4ye9M+` zN;+bX8axg^45$fg1y6fv%|#SY^}CF3VJuR&E5t_L(EU`rorZ#x+}5LYR#C^*#I-ycJN1G z8Wf_38@Y0&oGEAQY*aI%dNPsHtd#DQrnJhGULGCN>>)kJ@p8_(@*g}R;Vrsy@Ytb! z>GVj}G_xb=^u9yK20z}SSd#g!H@*c+?aDj!Tp0^nILD;Eq)Fz>1>z>yAp>C&=Sz~j zDF_F=Iw?pGyqIeaI) zhm%iE2#)#FHN)w?rZuTT6wg)#ldHA$piI#W^nawgXYGgYp7qj0r14hPhc~1Q*yswY@OY zc`DR57|j%ftOO*8OHrX{L=mVcoLyX;P1^0K_^l9;4L82L50$2^BNxmVx3q2B}|$Zj+>mN*jX!h@9}9Q2&gBq@9u{)ulnqaR7ou zC7soTCOzRoxm+Ba;F5F`u8TmNF31Lg2Vkhw2mw?iujp&!fh$Z9dKDNPV6DI}Rso-7 zC_*j{-jZ<}VJ@QC3Y5DB+Tj~FmeG3S zhB~GKP3$FR<*4>}@)I&n1JjC_IZ0-)ZszIGpiH1drd}sI8efZHbSAE>pt9{QpP5 z=ZBpIiJVRoVOAkxe97<775Dk@Wg-OqNU$#OVOKI{#mZDHGh-R1Wn@gl&KS0tu`9eP zU2n;iFiR?zE}x^r2|tI%-lElS!<<7a@)uX=F#*f93-2q}19J<$Q5+kMvkLBD-h^IB zoL4}Nka9r^;Y(xieeuMkwb4n@lxFBsb{4{h_v5b~u5$1vYjn1XMZp?Cby<67XFJvh zog_8r^wg6r$%uFJrM+I2lR%UEL96ItIGJ@hM>X6$bcTE6N}vtJvDi20dJAkXBZmjP zfe&yJByWedjT{NOG+Ge0?uI^n;ut|0o=z}t7 z=Hf^dbwWURO2A63IxP+kqj8LogKG&CCPBg4s8%R6`VeF(yp+PN<0#byokEM6t3q~B z15RSagqk*37T^>WI$6Tq6|_DO9N#s;9MsvU#2Cf}HFMAs%vhOI7#7H%PX^~P45!d> zhZ5H_I;0s1oK-d?eI!R9+vT@gOCWdn{#RWD^Dv6eOzkgwE zwdE=aHgKhYleyKihH{AxC?Q3D*h|L^PBV9=bSI8uI47xz1}5C?mP+MvspQ^`QlS+2 zUbXsq^TB7n@mmsBM|T_gKG*0%oePhTk{LVnl_z)L><;_PbRfBa|1V%M)A-oL5O9IBSW5rgO*`LL%uOC1s`B*E;mO?W^uKi{cBKag(-&U7km!Du zO8njKBg4f53=qBI(syEV|xJo53qb9XWK1o;iOqEfNBTu;cO)4Gont1%x}D7Ns| z^R_e*W{CAPwOi99AjDLeveQbRnt)sFz^N>_&6RDS4HU;t;#(7aZ_4`z%p3v+ZE{Q< zSVy|53AwP~xkwUrgVut82+JU3O+a$w!wU->r`%oW4OwCsB0b4i8)wiqNDym$r-@^o zx)6ir;CmL?Fd~5p{04=Rgoz4=krVDwnQ}tVMth@;+8aq{0syBjmEoq)tkHtH|F22a zM3_hy+@1B8Z%f;ie-#9hk15-hf#u8qU^4N{TGuLMScpFAXVS`ZsX)GQW>>KDD}f5+ zTwn6$(%urJNsaQ@nBp_cz^5c z+viY%R=ae_P;;Zs%%QC`hQYx9$8d)*L_sV?XY>Io!yXtMxCIbh@Xh$7+oFRtX24-bi0uQ>H$Y8qX+S3^2Z?&e?|NbEqGzw|%hTSvTsG){MVZ zdAW*r5M38Z*84Bj^Ep3XeXp8dllq=~nq9{^?+8E4FY=eQ5$$)i|Ag(hq%Y}j2eN^g z!0})@G!vQ&y%zd!tB#oz^#6e;M5#U5fq+Z>0SiXFsHGuech!p(^!Tl>J$KFW|YNjYd$< zC_7&-<6sMN>9+?^{%pM*#1A(*>t*t4@2!`c5chl&Sb{HvXd#+@*{A83eVTsRr|Fk{ zntnNiu@BV8`ZRCT(-J*WEOCk2S2?{xhS7rYRz diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.svg b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.svg deleted file mode 100644 index df07ee7b89..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.ttf b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.ttf deleted file mode 100644 index 31554f69222a02bf692dcfb6390aebae75f83241..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8924 zcmcgyd2C$Ad7pW2ci%3LJ&YZOk97-^d{t-VP7M}eY%dl^Zg zeeCa>x68|t+JBly&70%ReDlrBH^1*#G0qrkW-im&=mSSaN^NHC3AEfmnm=)7VTpZj zd4)0FjryZcEnHYa9z*>S^6*oqpZ(;QtDnuG?lRW%;mO5?Cxbh8{erPx>NkE84aRr$ zU!(rVsP~;bbMex2Mg8eB3zwGIJ?zJfWzwjp&n}!< z{7T2cPopj{$8Rs4yKoVF;>i+!X{HAlzsiD)Y2VU_;@AD0{|j??g!-*}IN09!2(VDr z<%(oNN5V(ii^h{y1r2YSF@ZOIO|SqsWGu?UOk*LmrK{VjrD}Plwt{`aldiJrKy^&j z`N}_~18F_2)kmui^%rLxBih!@iMcA1iiI^k?%Wn2u63!q;3v*ftio8{v@_XI(oA$X znbLTfJIP!*o-rr*_6(Bgxx3B z=XMqZaxOXx?wmGP9m&+vs^@hnYc6LiSVL!_(7D1iS5o0mTrY_gyWq_QZwYWVjLo%& zxj%EAH*jJbDQ@M;Dc;NDia+AhRP5?UUTD9o)0-!Pn%i0EY99_Y>2Eff!OLBk74vF8 ze4)Lo&{)0=uz=yGjY2U{L(HFj`C2Cz$Plud$*GT5*ywlT~{c+QA& z!#1oaZ{tY|tQb~>cyTJzykb@CX+FdAM$Rr*94i@MuY}s0Po8(`3jsb$)JH-+QwKslf(wCC84`FvB@`GP1GbM?E4CH zxu7>l+=)hm)+!CDVb3USB60^lc%7G38eH6(lRMC8tY?)*V@;dbz*@e<`t{H1^K1Y+ zb3Z$Q^Bl$rRz|0J!H)1KPx0-RQ3&B&t&VY=qFu2<9XQ#_c)_E`Un?Ay{Z>Pb(IwruH>GyTW1ldU5o*Cul5z|2e_ zotwBeGSWKfajm`0?2m^N;aE6j_9sw?1o$gm`Fs~8?w}#wZ??5-JP<)S(Ql^0F`gwd za`2ueYZE@)-WQ9-gW=fjl-V8#H+6=;>C^7Y|3^3&kHz}h!<|jx zK)adR9b-X-5fBm9&1^P^TL6^c<*`E1e`P~GShGTmojjSTm^qG1=pX?(j53awmmQ;$ zBat&T8E;)KbmBTLx5neGRqjgZk-T!ig~k>aT?sUhn!sm4H&?`4J=PkRk}j+eQi$3w z78hTa9Q}ORWD36qa5wK^4}vqm5+-#pnV+xn1~fAr;Mz`3C7>7`6^;&db$0QM)lFaZ zOB2GAVujIrA~i6O`Y<)%s`o&u_Q9KN$z+>)y(MU6>cw}hHEV+SC#a+MK+2mV8hpZg zTjkeN10IXF($Lm8cN-;dwFF(^s=F+3x#%u$VR=@a0WT8r;q#T>$dg{qnK>K>Qqn-8T-D1P*?_{pKlMnr zJ~Kaijni(4(ynU)4;NT4$)nhSY3)9$HIPK*mLUiP*1*IAhd147bv-0#Y!QAPBKgIVgNugclgHHwtZu% z)Y!glHgdk}^Woc)1Ye9o8_P=9VV-oOk^jm$Q8xryrPk=eqVsKliSC*WU{qd4Bo8rH|fv zHh`fDV_w1dQFexX4g>+A5aKo-O7!xIT^O4IDPU|b??|)(rg2qAa3(3VjnDA$FE`BU zPllp~_V<_R%j=oPG9Vvp#jK!uxlsTkjnCd!_h>#xeiz-K$yB+~%jeD~=&waP6AEH7 z%-D>~lfe*<4t6M=9i6?u_g`aw!2XQ=fc@|{eF_$xDUM;hM5j!e7Uwd>m2U0fP_CO0 z8L+K7hO%lHPP$U+P#x>TNMIlmMeb|p-^7{z8fWUN?Zq1>Dt$nYx5A#HqI%WD?RvrF zTkZA#Ee!t}3c5=4=p76_S7#0ka46lnBKphQcJgGS6J$suheKzOp&&F9<7R}L8EzX; z!f;dY=P@oxhbv5GE9hA(N~!&R?bGV+3&@{vO(2> znzG?_^_I(3N!I(swrvxXbod@MSRB3^P!l)`p7zq33ooGRcbVA6Sfs93h>s-eWWC^~ zAAX0!#&5wB&y}5|x%%Q{+&HUM^&w;CH!@c9)tk#<^1$%%YuK6eW)5KvF+ahY2Ak{Z zuEb8OJ!9(52AIiqfIo86a3OlQktR9N)c_#H` zO)_6D;5R`J8E}(0UzTJ|K{#O5NkKxQ8sG#nzX9tEvV&OcpX;AwO*oT&HqDMe*IRI| z?5J+!$@!}c>$XnF;Tz#SoNRJJaIBvePb;To=S)(-q<|zOC{7Kc##0-AZU{OC+MP^;C#jZGJr+qK7q;pX1_eJK*&?C@*5g zSg=xLSesRbbAcmN#|t%`r$YUJ(M(RrszU<56czGD6oHCTe!hihgA)G14iVY=2ll*t z|NSrT8Mr^Yb*$SydhFq$p@)whwY$f*a=F*NaJ*1Be!<+j#TWv1|%WIkr)wzRZt$yu>{@-tWZc0aLW#}m8z z8u_Ym`MsW0s>hnj=clY-bFke`&Mhs?CGB=p{8os_2av07__Zdy67t~y@*#t8!hx&p z=mz#{`)G%?-O6b%wx@QAT|M!u=Xd;a$NAs;TifXAG3=MM*QQfx;iUmfAG~&DYcRO= z3ZzWbZOZ`gfMOzBSP#o8zX!+^$0dh11A8!-#1%8?mBGbx47z?9dQH(yRJSn*fXE5o z2=!weB<++usU8htjsOS}m2_4Un)HN=%jF_)f=ALzxGo%VdLSEc9)O`zBLq;MyrQp> z1+Fkb=v82FfVBd@SOt8RaS?KH@Rp3*aC70!R&eUk-Cff+{`Rkie$?JZV31EoMGo8(7~3&VPk`g{D&(yZd{=y zQ@+AVC2?&Rl6LsUjTN-sxS_&Spoz1@s(hM!9ZlnZrK$aUo#@#OG_gz^Q>FG0v zMz#*k6bP~0ymj{{J~i3Egvn2R;%+NHUwuEm^T0!+v(G$ODn0nj?C3)WcE;bY&NJVK zCVsX+qwIvI`Y;Yt#Sd^{>p=x&vC=&+Z-%bz`g+GMv%Ui8v+K7XmtA8AzF00#Oq9!C zJg`=xwKUd5IY8X^==iGZC+_>gU}R|bk&%%jyN4o!U${>n+eAc>yKg-iBD>}huKI`{ zI>o^Q6TQ6?2L_7{WQOoe;4B16TY+gstehk>SXc8DG$<1&k*e28kH*(y7{YWUt91?U zLM};@D-HUiu6VqQk}e=^6hG`NNaPevgj$7&@nye5SKQ~rmx&PWM}l>M54(~vD^{jr znHkG4EhA$ZcE+&Hj9uYX>3Ykqgj!O$boo35C;S{Y_7<&v8`d0JmA|+`k4b2*-I%Xj zcg!u=MsXZ8VinxMx(U6Kh*#hmA?1SP!k5Nj`{Ij9d!y4uQ#V7Gva=92yq|pSaFv5U zS)~xDNk+VzFYWWHoCKQ8586c!!%3~nd8*;%p)<@Q zR|0LwkHxv+uD3wa;lsMk9=ngJ}sACPBg8s8(EP^dZPn zcqxTj$5E;aib9K;t6X+b15RScgjzOO7T^>WiY(#n3fdnCj&GV^4JtM&F@|wL%^b7@ zGgj9Wh6eK2lR-R&AqpLLC~-ZbLz z!rgAER4$iF?%gOAN|EnZtFJd7{LD9hOG4}DZsWesH@Z;g!V_bp#twb;shx=3;hdQc zBp0y%1vF-w!HR+3O-2`_H>2#Yf^Dw`+7LISP#ZL*A9vHv_Z4$fhli^?J$!g7H#hTd z-HF}lp`rAJS1%;GU!@X%xBJLQ@xF;njb$e8E6$#>evs%U+y1II+MT#cB{1ZI2mC=^ z8COb}1QfbY7gtxy>?)VI5j9r`%@w52WS#E-%QQ5mxgL?toY^oU&77q050}Zr zmZ@xZYD*&NHtaVNF%6((4VlS~j-)wcQ9!f&*uHJs_C1D37XwR>8QdrE2UW^5!*y>K zn_xL)(xFb80O1KT%z%(7l*yR0bIMi&4Ajrm!H-VfNBPH{-N%pbo_IKVK2*#V7Ru#? zLjTZEKi4(yBaIg)KlZJy?Hw+=y6+kqylW&^*xT9N+uPlHbZGc!FW0ze9nWrT?{X|` z5%^xN?`r~;hH642RsEGS+@({a19XLpi>C`JQ=2Erc>yY5pK0wb)}A1{;Z{^CHkTU- zc@(YtII$Y@afN&fe?M9!0sX9fV1iD%ZERw2WJ_fd~Y zE6b$<`9{pHVCPpI709{1?9HdWWk|`ThtfA)!Jo8eN4tvmo|u?8ac?mY$i2`SCGTQs zuB+5>&UE6zxR&t##@WB$p@duQQjnqMMxEJ1gEWT50$8t|>nL^6xVfch>kA1D10D02 zKg!u(KXb^Yi~TNOuSX%Pcldqd7C&z&Rg{F|LHkd}u;r9D|Ih)+So@s=w}fH<>9iPK z9u?`d_OYKkGy%Av{U^LZZ{Q0mQn+A^sdOz-eD8_2UH`?J1889ECp|Yu8u?1K{);6= z_cZlcjZwcLs6=KRN2J(3Jn8gf#lK*^)l5P=}YU%)Q3{z8|6y@#@E$3+w^@N z^@H`c4>o=4MxD~S@wY0kR51t9b&+Jf|8hN__w%)R)%u#$@5!gxb;Nl``C)#MzpRaF zzpMQxbjKxqS${i_4a^3P2h*Y1(0u5%(0>~TjkCr-ho1|-5&kF=h>S<(BVUfZ+ceko zQqx~I4>r#=f4|vlnQeK#fZi3(QEno?LAw&z& z^vga?zwFcW%RWuN?9=qiA&h;nKGvssk)2{^*|Uh!pFm_{h+RNwft|+RG1Q+%{S-Tg z9%)4KhQae~`(HeD_SrKh7KbjJSvYW2)93KB?>W^M|D^z4^qrpn0Rkub$N&HU diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.woff b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce-small.woff deleted file mode 100644 index 6be9a1d82dcbd713f484be0a3859a641f7ed904e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9000 zcmcgyS#TW3dG4Os-Py&l*um~%KpcxbxH|-vIJkqw0we*nctD~kQQ#3uvMzuWEYb!q zk&-AS6;IisOk1+e(287kRU(vi+1@9){gC6dWYJYY{B)BX3~-G6`ov3%yfnHk0zp4=AJOnLT~ex1tepZg9Eml)$= zw9Zj#Gi#3>KQ(_AZ6{EFSf%eREk7}Tp4#37*|K`N03l|wnccNaU^d4`2ZSl-;^hp0(n}o&K7aPi`3qPt@#Xi^QPKm9UtvMU zv~O$Rl6}L^`M)xUM^In;@YvcKl?B);>vCB#p(CM%BQ>71Drk7qObNW{Yk~#XUC5)@ zA&rI5macB8ma66D+VV2m!CjSA2dbm0&X@l=9Z2hGtv*_HsJ}Sl7}2(7PRv!AP%NzS zar?Faaji?;1wV0?Vim^nrk%-#l4hdA$&|**+)3uj@r*gnw`Gt_Cufcpa;itpbdr9r zNp6|Ctk$k&hKDm+H8bqFLb#sGT~`#kJh!VLkaN*haA&pI>Tsr(Rz0stS#vpC#u~Z` zg|20$xsnQh>Uv46*adGccuRn@A#AQa#QmA;ynz$jNO3DyPVqh-SNsv5reaq={6hO3 zUEUlK)ZDH@cl%JNNq?)!3|{KSte98(;S25Eg|3>KTuXP|(LNY7o8Ho!LYHbwI@t1P ztFeR2GJsuTBWwa(l);8wv5g@<%yUMR8@6FZc^gk!V8yU1#EVmz;uWi6Pw{D1~X~Gf8aFY7)A81Dkxq)kIBF!oDvvmkWA>#O-J_XsytY8upCR1|qlNgV%Xkp~1z? zIk^pu#(Gw0G}g3%4XouWtY3ddpJM~qnS0rBoaYcuure~m3wDG@d5Ukdj6w+KYITg^ z6zz%?>cGiX#tL>2haKg)Y{4$jC#OUoj7qjp9vwp^nF!_3g}y^V)^^e7vPb);<>tD>6$;o;T^k8AC1W`8`K2*<)Hvp<1CB*0(o z&gZ)+aR&|YezUDz2x?T)da!U%{6>tQzAidz7b;N{Um(SKz_ zy;!qCj2%3gshByAOXwg0IgB!nmzN!*k|U8bH5qSRDs5;s0z=g&Z z7F-E5kea|}K{r>#TRqkqmy#~55K@TRFBTTwkR1Jd*<=d825>j;V)uhHz!D~PFqxmP z@CGz99pKsyP9>li9Tkoab#->}_00oX;i|hVaJlF% zcd|Sq&5R9h{BZyy)`q3k5&Y&A?lx{1<;$#b_#1OwxDtPwY{;H>lM?Qf3wV)`51+66 zdY<%h&dlLBkdg)x<*Hs@&ju6*{;5a0^_ltUtDJUAly+Vfc(}lVNgl;IOl$X1t$`#e zw+ulbunHy~IK1Ijt7{=aV@pf7rq@6f%DG`FdX0_q0p=#uNM8u%D*pP|H1?vD(vpd& zmdg%lWqWi=bCOwt7Xtv2xy?7uw#^8BSO8OmiOC30j-`0W&}7Hv?4@sd*ZAzU zcc<@LWc!z%KOA_U&+^%y2cCWVV_0d7a{(E+;*aO$2rn0+yu%veQ{2)7pY^VN^HO$m z$Krj{?_SgXZ2+RdQlFWr4KN#22K%#fe=CZ zXoZiJtd4|1oC#riv}{@5FtjJ`(?2H(&PjT`zURpOeVYkRa1pT#Wr$RwYh8dfYc`_Kn(ZLR-v!k>3_x|hbkJw+ZAFv<( zwok#LGsQ8CmFSd7)8bqvxzeq@9LjYAA_KNn$52)c!%0_49jaq}7zqqSqR4#>{o6Rx z-{4GLwY_-bM5Pbt@mAPVR8+5;xK%Hhd@H^FzlGu7LP1xF9=(I1=jzOX0S={GS44k( z%TAtbbb<_NMfV5lC1afEnCJZ>F_;jusD1-peAq> zJnf}57hXWs?=rrHu}EF75Fbg_#rnWaKl~1d{M1kJ#B*gQX|B9D88^;KRei{q`Spy| zeD&sXm^?6i{2F#9y^%whL(EUGrorZ#x+}5MYR{OuvjJwZ?ck5xG+c;YZsf|9a;BWI zvr)~6>d8b(vr@WKn$jv$dU?`X=X>#>3s)} z4t}~tu_W`|Z+-`w+LgEIxiS{IaE?iRNt4W%3;0dYLk8R=&X*)vQxFbVbyAR!s0KKJ z%x}OtgX{nn`Srg8rpG~pD(DfFaD?6$id2;?LL%OXKa`;AgFDILv5FG2L#nZ}Z z**TLGFzMfh(mimn@Z{c9@xb04mUbky_sPORYscOL#a#hIze=)wx+M|{wngSU z=gAjm8~M(Y2L=ZZP@A7?-*6@$vL1>S$95I|0fkAYuxqRst$j!1`+iFI=+7#lO)Zg# z#@13HYPGqwbci0-On#1wv+aP_>!7@V6=T6lkzs9C8O{ZcP#rJSbe;A2?T_u=+{jmq%kTB3QoYt>K0j#%n}h9ka`x=m*`(c$ zir)$m`4Do|1HaaUS3*7BHAAZwdxCU51p2x@{Q%9#BlAll8K!@_T?xaa?kEGq4AP zNnA0LUKw0G$Dr$%q1PncM0Fd30EnFMjZiOs2gkA*(2Usici&em985bcJ2XD!^4L29w zYz3Fk5agq4@}K_d(pw*B;=5n`;?&AN>AIRAC*E~yVx<)YOo7&(WvRQk&&|w&rAW3s z;D&Hd&lz?u0v&8Q95yz{$X{N*e*H2nnet^;Dv7H*k+ehCuP>wZ`gIki0!^GHR^`*= zYiJt(D^2Y`>O@bkqltaOhJY#?1(#(X_~^Vr5;6+gg*tp^p9#Y*?Qyb-## z>1!Rk%-RZ|&#vEoTy~A^|8luJK3*<=dH-sO*3wuLCpSb5sTO)(J4-XF? z-aQ!E`lWmH(G5ftxqH@1DPQ_6F3Wj(k5V95i2Lj z4A#{=1r5psN~G#_(xdUU7=|z%$!cB0yO2xL6-rlbo<8^sU13KBU*6QNci zVtmQ(&>i>r@MR)|`;lPX;KQzD%!-w%SZ2mDOv}iahMh5NGh)HB;pmgMo76Jx$vbi z*uMB;(%$HF(bUb*rR*w%4euvkKUC%5Pu3{5icP^D;OesWuC8|M4?0O|(CMouTapp) z#>+Eam6Je|`9ZtrVK}LEIY%|TJamS6MJSAYI zR-HBn!DxgLaxg7{!Xzlz8`X*njXnff3NNK_>o`hvK~ZQ?bCt_3YQRbCm{7|G%L1ID zLXjoBT|xT;!SPKKtU<*_CB`r=sF{P7V8+Ut!q7nedNPQ|Fhrr_4kfNzl|)O-??2dEZMjN<4O}T8GPfFQ zD3>Te2`Td3UJ5rj&D@#NojAg9PEr#MOt{l6mCEH($-NV$LMih7YW0og15bbJcOm9?n z!rrc)zP_HmBZEUn`nbkL>sWSud$(g@i@^6%eP0u(G*lBJsp_ws;VzvT9iS^*Ts&P+ znc6%_&I?ch`%G(hvGxSn4L74wvAJAN$fIc8r-{{=k1OO``1^TFns773dYanJX%Y}( zsZ8l4;MAisycC)>T2S}@X;L*2Cej0QXZ_>r(spHE z1%c#aO1EX8IWqv5OgyvJvh% z<3amR#<1m-H~!E8$yoiJ1Gj`?0O_?gf9h8y{Ewf>7GMfWuIS&dP@RYPC+T0>E)e^lA{+6oN=Wr5_< z4D~YA8|f=+%G8Ha;~V8?1B|b!bGG689O?(^Z69v<)`L2wHREqqUan#eqU$2bdjF+* zKIiAF^Q!eVso#?q*)_y@NBALrfxn`SXuq%h8oJ}6zNEhs$Od)=js?@9U7@+q>!JTP z4j8A6e+fSqelz@WBoG;k%tgK$d9P`<>E))sZQj~E+x-1zuVq)u^DTee^3&Fl)p;zKC#&}EdbtUH&$odk_=ONHMAI+(H2tzq(=Yop{jyKfFNZMp{`y#-<^^_= zoo3G>N`D-Yi9vQArFpi9zoV!>iTX))20hY<_2?R&Hu2`{2t=} z$ynPTADEih=PBR+UyQY%K>ol1B-CVF42&8kKK9#SxdVeBkGweErbtUwi$+8;9O7-uU$|PR&*3=BP=O zWaakPm?-%)N~)sd3rkA!xmS~}q};qR))wF|3xG)v_=aEEP-z^X_6W6GX6xNHG?a z^;zA;bW_)Lu2+~QXRJ==e zN#|sb^hnODRFaCNab=WD32>%&P|lA z%+S%b=iI|qVst8omoMd&0`KM-#m|+z67%y09*JRyN~}al^rSx;l#fm`%YM=UTCh;@YYTMpDUdd|K>vT0zw@bKy1qHt9k0jnAj0!{`4dCGLU z6`b-07Gf-viilqjZ^xm~ER*z#PL9IluwNQBOy}Z#$@XG)Te9to`i9e>@lGwi)hIwncSh^#i%@1My`q*x^kKNB$w!k}hJ~Yfh zlwR)V;b<(RWYQi`0tlekH-N3rmtvl%9UI8y-5?V2&!lr89<`s!SpOmj7~~uFC?$|I zD7r6-NCq{mvP5f64XZ4Q+co4rOkdO1s?EjmnC~;+NB*4F+ICHPjlUROoou^0)0S4& zty9u%nXB89tD{B#n#yaQU|n6@U*A+$-&$W^<8gZeb#+bt`gpw^Kbuw6EIGa#DRoWt z{&-zo5ant_iFm!gsje;{;{Th@Xq?42Y}^nxaneO#j%k_nnzO}dG?Q+dER2j4Cfm}P zXta2C&HcWn+WD61&|`JWb@fg4f2ZcCpPYl%Ycql(mqroNLybb7fyB z23ox*;(W2V-hVH%x>jea08knsd2kRH*2_kby+bG|kYo%6q1!o-!oO)R||V zXVAH82jAET`Vl8DOC4v>CH>~dM_jI0#qTn-|DcD}+#-n3;^>lGjpIaM9C-6ngL902 zgNgR`1n)_->z3D^s66>rLnP85Ue9YZP4VJ)EhNjBhDI#fa;Wp7Xy%l8ANdlRtLPyg z)%AtA;e<>qhLwhmS(v+vc>zyaAS1!&=_ISfZmbudr*)f^Tk~8RSvd06vEQPqTQ25E zw2-_ZCmBu|Q-6C1<8$c7;)y}l%2wc9V`vUH%m*`SMh!)Zpp+6q#YhAxMGC*>wrw8FUZU-}>eeMJslgxvndagU|I680jJGc#MZ$h5lP*YVzJFLMMg#*? zhB-v?JLi4BuwzXovt~zud_H>TxxL!SE^k1oY4l3kCGwb4hy3K;b9avFJ%yT3t;F9k z0|ZC=Ed2(!!Vf_>%nMwJczI+X!6ildO-F91eeUroKm)|zazF99 z`37(_=N=oEpgvcNljt@m7Q+~Bxuckp+7wK(Etc;y26eeRU6Ny!^bM2nYI{qsw7JZUp?^=~J9|kw%&->t`yS%Se zX{bR@=cuPi^n~z}-ddNuE)a;Kv(sIZF+AtmPZrimjSJyR)q1k)bQiRbc^=ybb>|=y zqFbN@-NEk0N>{JO|J%~KA?8b95pFmjzq~>|xmVtGnJ&G;Pg=`#@y)5kjDm4c({L;e znZkdmK?oZLzvM#GlI@GeV%WytaiQ-;7e6%&&HNSuD-3RE-~|#hK-(H<+YMC7LP0MN zro0j)n!z=$0Y*ZK%%K>;ey*7Y;MJd#RFSi@FQYzbdw9tjUS24yEz}0suTUoziH1-r z#7igzG-}N1vJS!4);37as4#;wUDjqXk_wZIiY6tktid)j3At^IQ#YgsYV&>hfq>)S z_-SBiwrG#CA$)|N)*!Z2uV5I}(>Xdm0Mp*7L9JP=skm1y0tWvu<}DTkhWU~KGx=MFhO#wcmo7DGss znM+ihZ)&`{IyFNyp)o@?B%3C@Qqjv(880t#t`VHT)=#i8rC2_5vjHfB zUzImQ5A0%tY(3kK)xl!WO3*UU8e~EaGPY3k0)FOszpTW7tKFr7EY!tpCIWEY3pGrY z*w_OHhlUQ)v@QRI6$e+XI=G^(v$Jg>WZv14UB9X)v@0<_Bo%grdRDE^b_|Ut%m+2a zJ=6AKnN>GIO;w&<+=A7Xq%G9_{6do+qsHgb`)>Oiq64ObCX<+Jifx6NM$A;P_Zu6n z%;O;dC9qT|5DOZCr9Jq;@}uDMfV_F36hIACLZ~YU2-1#alG(b)r4Hqf^o^TYuxKRX47`%<*-rhnB24*ATA} zPrM<%uB~ld+!t1&1Fd7z(_^gzQ6=oNQu)^+%OiDlctuyHj&yEn3AKi5Yw>E?)OjSe z5}-+9FXHs~0F%@(AMjf#6)Vaaxfm+OG9^B;ir1_zf z#$eGw2`bgXW3oH1z)}Gz1-k^3H1tDUa_86XdS0qIeR|mWYiM4tXmTJ~2^dZya%qj1 zp?w`^x{jgkY!xB~iRS5amtsZWLVqmY=xz8(MCkDuJI;pE4!b^Q55$LB+HOr6*<5>^Ix9$B;I$j(6}JhEc~ z#yMxAjz2qA-4Hb>O*?GD@y%z$>8`kT?5ghWtBz^$u5_3YU&Bk-n@Gw+!qORW+t$3* zKnX$OSg`12ELp#3f}l5uO=A{nc&?ew1Nn1|U^@4=ghDOkNcG7zo5-Wnm22iu$8n}K zsOL$mL<@{u)w0$D{tzaN!Gq#JxCyKQY=BH~IvRKkv{7=gGZzkDIAh*MZ}j)(8B<5f zOGtt*8zOe$j3~tQSvy;lJ#&HjQ|9fM#81+&WUgexYy-}0F;c{YJ2)95iYj16Mop=< z>c5(+nPAZ^%oemXYhYK(V1lDdbwPRaWQGEi>B+cCe{VK!8EW;h%`1gHzI?8 zfH_{?@h~5k00>bU>!g!nYA=|^wej)hoQWvBTyt5ca|^vi*_gLcGVWlk@ngeb(Jpz!xjn0$|=aF6qqHJ%mCYP zyg;DB0?B}+2P#?sz%Uu8=m7w2=KcE@`W08`eYrmG=gZ}%>bBqZk(~w*nyeEqqoU(Z z5h|R!v7fg2s)zQkhOGrljy1$!pbO}r`c~{RgQ_Z^8t}Y8ZMi(@v`|kwcrb*mwUCYU z{IX=*=w6jTtGaizZNs2>eyV+FXvNKE&z|iZ9`58Xr?2UzoLQa9jh;yHESY|Af1qW?l!zsYM67S+H&qoXvm-fLTz9Xp9U~(#t)n+S7T<@bE32 zJ*s|u`}X6xvF3WGVLA>8HY;J3gF7i-1Gxv{t*5Hu4ur=`uAdbv#N zn0&W3yExsjRu7J}3t=T&+UBf5Z7#^>TJWnz)&zddKsI^MEPnY2?waVn32QHS9*7Dj zrwB7Kn65@9Ib&+dgjJXhqhT^o12c3(GBl%txk#D;TQFx+Q!OY?{Kf#=G&R-$2C2&$ z`0K)bObn9A;*T9Rhg^-ZfPauZLGWJqc{@x#*mZ1sJ?84ELr;v7nT9#S_Rf&Je5x=DKH(N z(Q4S`QDV3j1AB5Pe4vD52U}GxpPk1&Km{@mRnnZ%WPNZ;*DTZc5A!2EEghRD2L~rN zceq@WU-tP)FPR=|>5G0QSPZ#CQrLX7xM@?7oQ!#zj2ji*UmUrrlj=}i@YZj9Cfe6R z^~R?CzAuL*R4fJ`vuYJL5p8I;{Ayqwn9FLSX`s{+E;%Ex|Kf(TsOE*h7Oy4u3>Ud( zAd&(VC$*k(j|OkaRRf4gNG$?CGMt2A>l%cT#+jxYOD`NG1IZ+=VDA8=M-^s|HvtJm zclENkG{X93RH%UBhKV%57G9JAJ-85=G$#J)hZMitFx7#b-`Pkks z?>1W(j4rV0jD?mdHEwy-ElaiaZog6+t~X!dx0>zcGU%J3EOu&EXE>^?XYNh;Zg~|F zy(F2k)R!ze9EPO>L&0^IU&`g9WZHm_+gBy#4#lKfD_@Y-Z!)*?XU%VqJoU^|BlHxG z-1dj73*$HL$qo*AdiuLgy!Vd=cbVUb?j7R~nYZ#$I_UfgQIx854J~trYUO3c?8-9_ z|4DyWk2|+wSB&TPVrW>}F6c9#mJN*S5VjgN0|BRTDKx}Y{Cj)))t>&|VVTq>q|%j9 zObLnn-h$lQ1KSK48Sw8Vom-CegjY(-cw`x0DPda3Q|B9#@4l{C+k92W_A>{EIS;mG zqej=~q*aqWvg_0%C$p=!WJldT_wu25d}#TKwViS9c5kZ>Mz2luq(iH3zJE*-50~Zq zmD@IFjIO`0{L8*he!c9v{rjK&gXF3my`xH_k{gM~M{@m>H|);4s5}oQg4>o~ahX+F z?1w`iA#j=`=z|ELwCI9e34y=~dE$h}I1E`jAII?_Yno)V4eH~SnHgz(&qh=0;pHAP ziL*Z=>H1(>MH6M1E+s{gje9D(RRn8&7Hd6$wN8*_hr=oZ3ymLgaNewiy_YS4NP?HB zfm@agMV@Hda{ZxF>Cp9Cni>L9ING%F+9_3?x^`nzG%N)g-kZ8>bj9{mZMe4cn$2s% zY1vm7QiAnq{^QF}-+s8e`|$0jFYnm1XV;3t)`8a6fvtrVyY}qqFn=(-r6n%$c-Pvz zrmNBRaL?&=L>HXa#ifIP0mBKK6I9zwwOST&3{a9mn5fK?JXvpeq z3tMr@D??w*V+r5ILHNRw>^SIEFp9xp{PPaS+$5}mpRm<81eg1}R{J;Y@!x#HfBH}T zXFu(K?kf#1z2^UK(`?{D^ZS0@W&X3DZ!(`&9=PzWz>ohYVE&rN0_L}QDPaC1-(6$= zg$%J(F+e=5a#9Yw!&CFXd{&Kl68oYt4fIDlMBk_g8<%qvs#z8?(!Jmq@D(%;VZXCw zo*#Il6Eb=;yOtebx3dS?N3pYHPZyR2sM7<*U^*v!JJq^UhdORuu)9eyvBOYJ+_7j_ z@ua(XuD>+U2f-oy2ss#ltZvYF zRd^1aT7wd~6#RkRvS^n-UmX*pvBzQ#Rmb=bmYzFv-0FDb25c92UXi)w`@lb%5dl0& zK;-*ni`fftO4jKYy2g7819hpkw&U-AbW37O;rg$B=}A?M7w^1Y)|-=_p@$y*$mOF4 z*2Qb{>zhUL_5b#zbC4}`PHcJz3kf&RlI&XpPOMy*+TLz8Gj)dzz1<9EihF~KF#B8c zxQDF=wpk}@@5EwWUg8k-<}2na*YULZ-Rn5M-nh>EuJkHiJiRDGti=rY?KsxL z4FpmmP%X_E^gWzmG7X*x(3&}O0;UVmw;^O5qI+Rd4DIjY5NqY6v=X2ukuEk=dg@2C zm0Y*>w(=ekH4%lPA`*X8d5=wkR#bY*ieh{VcrpYXj;v<**bVk7V&C{cLNM^4I|W@H zq5=vLh7FWzNDMC^ZVl!WdPxRy3`2)vWauzv&;%XR1iENO?z57=ohF3DSlI61b&QJt!^xiaDgoNoIJ{tTQ3mxM!{!-;(IH7kwv z!0)odXI(nV>ecNo3OjX*cKLhY&)8um9{Qd$f$x<5jJ*jNKFX*0W70n9Z*jw-%U_gV zcQw0CxIXN9*1gY@_KbK=dA_K0DqEF*s@Yd_y5^;t*St}$<~`(nwzg1vqV}0Oe_c=A zC+dD!-&TKf{d?=5_0{_dzCFIvzAyTt{&xQd{6A^vX?SnLTY>(-nSc>^GguRB4&D{~ zX5+@jn?kEXhe96@8KDc|KzKy#@HX~1EQ$0ulprGZ%g_E=lp^|2kVe!+B^5Sqhe@&w z*kKpKC+#rZUPtV(2kBeva4q=M8Jq;}@*>5L94jm#yx$JX2(PijE`;y0!*1MXC+)BY z={xLjEiA%Mo;Y~)jw6#(i@)ODHFf;fgU600dkZ}m|8)DJwJw^tV`~4&!xP6Be-nPu zlB36to=EPWIy!ZH;>6UxE0vi>dji10Q_T$TnqvB)o2@H9P?L*p4 a_{Jj1HsSO0V{987ePUj~dV_CV>iIu7&I2(3 diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.svg b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.svg deleted file mode 100644 index a4c92e0b59..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.svg +++ /dev/null @@ -1,83 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.ttf b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/fonts/tinymce.ttf deleted file mode 100644 index 422ff56f8dfccf59c8dd9b2feda517d730d2428a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11880 zcmcIq3v?XSdA@gMcSkE}SG(G$Bx}77c30M8wbE*|vMtMF*$BT820tJeBxGUi`XP+X ztB_7iOTfI+B#?%ZSdHO?Hl#^gPTB@1nbSklCM7vE$0s47B%6?s7v%J$4JD~|)bGDD zBdvuoNzUm=ckcV%|K9uG|Ns7fmT|^d1JjwzikDy6+uzjOa2h3N5hkV%PtNT6&J`Vu z@ny)ruz&KF8N>nPe}cGf|Dii>{D+O^_mKZj#ybA^rs>Ijp343I#aQQY)DPZ-g1U_B zA>^My{*s#xAHTheH{Oi=i|8|O=;+j>zU|aW#=2dof8y}u?K5mIdjk1cK@Vj^1({bmA#&qJC&BHOfmSQpZJH9yMn7^r}hs0QUr5Ipwl#7>P z2j&eI!*01*Jqu&QQo&R(?=A&1K_pAalwv_ypVM7TH+5a-dX;ICwndeVIVPiE9`jd0 zw`p)qt*W3_X4_C$i=Xere{s0Igec_qPP88yL|^HA7>+8jy; zQ5%g#N(mkb%I|+TKAtj@sovg{R7v%w;ytoUIwO0eM{-`JnpC`Ag;!j4E|YWV*AK_h zVs2J6o=A9s+Uqjc|!4WZlZN{mSIQiH5b`RP^W^td^xWacrVW=ey-$| zn4dTCNDL$@u`LjcdjTSlx&ba5EU#Q>NRk;FdSB5M!ZKMEnKub^;pBF-foL6evvr z=cVDmbS~Z(9WQ2&CEKy+Z#V-Q?=<2&(&x6v;kDy&K^+Zh{ysEXt6qEy8Xd}PBY&YA-?q@7p;9Wc)8sT6{FZc6sG!{}aX%9F73{dJH#L?%=F;CRa z4d(K0Fp2ojq;p^%b%5Gf|0OUm*f;D^%3x`5bbl0?40>2?iPxMSR$DZ;d&qy7zN({L zn~&o$-)Fv$;(4vTPp2Bdx4kr=&YFS9T;`1hK9Jmv8AE0 zy|J;*!F+HstCeo5V>kDbE zxm+tcRCQm-Kp|(EW@uXVJ=4=q8Ioq|%(Eaf=-zcgZfpeqh?|$Ci8Gjz{ubyXDOakI zcNsc=@WX0uF+}M6?2=lI<3@lEy!q`z^Njw65}ln1UQBfAR@9lOKKWKtB+?{a&ug?y z@#1$a7Ry+MMk3k@=<}i&=63TwiX{wJ)k8k&>kDziNtxITs|*LTxONxwGCymBj)a`2 zo2-(!v0i+E*KJX5t#fH+@yc7*ev7JZxlkb0Li&b+WH@b1{p~5x=kSds6N9Xst-!qo zX^u3^2Qz9$4Mj@elrmDKNCYJ%N+Fz26YZF8fKd?Wkr@3O^UTnyzwFmOIE?TMlUivS z?akZdan#}ql6cM^rCYdL2&nUCvjiWY2#IFv4|-iUtbPA&$L7K8MaG`59bLkf8Vov+ zX)X@+znrZFz5NL(681}(bU{+{10zx?A_Sl^!l9Dix$gUg9cwa~H9HCv^RYY6?A1>6 zcmqmZvscnCQpcP=6estdxpPb}7V1Lv5`V`EFdUt;^c&y`KNR5zFK{K|<&nVzmlWwY zUAdu8Jxx;UE3b}Sen8vyxyPpg4Um7!{lx3$8^_R}du&{S{#^BPHRtEiSWX(@F-fDl z_VlNQa$N^5AA9vH(!aiCqQG=bKmNIG$9U-VC*07u1@!-hn13Au9_G=(GKX@=c@*dk z0tyiIO-SNy_kuiJ_qC`eF<%A(N~6vbUe1M5p^CgBkP($r_u3BBYH=_EOHf2>`QSjF zYredn5Bs?fvH3jWkIAlj@0t3z&lmSj)qB15XS{J=U6Zmd($|t$89P%bOvP3v602fo zIz5?n{8v^k`XuGvwJT>n5I5}4`w(Ngysuqps>4iYXr?L5g!Gf%dY8N|5Qt*3lRZ;0 zJZCyj6xK=2i|LE?da~za53G*`8QagM*#UN#-ONs~JJ{XW>Dt}+f7@C&)O;Bt!i@mr zmscpJ@XEVx)5UlANo$)fd^pvZQ7{f@8m^@wQ~ED8C}G3k7u{&uvVGB549EC8ZuGsF z;-`k8ncqTUg~1ICvOr=6cv}N+yMZcMDCp(ElvjdAGq}bzz({D3c{C%~&o$Eky!vy} zDsp!2W%MU&4=-86%gdtB5f}sFSC|v$sfJK0#LH*}G-}N0vJS=8(J@59s4{~yUDoD6 zNtH=PRg;od)li3-gx)qLXd1EuwS~F-K)`WG{4_8_r#)+kBs>Xt>m`UNEo4PS%9fah zknuW{Jney%se%lmKxS19Xq{PsP(u|B7V;#dv2Gi)$grYUvdh7%#4-KRcCL`FNvWxP z+Ak@7ITB7tv4mXeACbxXFc?w}KcMoG)I8A7AXUZmr~P!qM?X&B-OjTy2b**xKuN?xAI zczKC)jo<{14yuZQSTZSaUc@0(V#UnO24M_-Ro)Ccu!jw?^=vzK2b)1VLEAukkO?`+ z*h0~Z_?hSZvJwNXc9#pXFc-6#2*7zC%rI4A;}0Ad9zH1FU?vBNj zd1qI4{i4NoM@2Q|e#+wozU)eb>JRi8b71ZylwTkQM!#UVXL zozJEB-}*Pi2TTV~Cb8BO+sckwD^=|C#z89!cnClVA{7S2qD5d?4}OUJDC9gKZ(bM$ zFhi9P`U(buwxecXAmSq)Q(;L+?D7xZGt=EYbI%7aUrcFj*=!pHK9*RUOmE0!Hl&kl z6TLe#nVr2Y{jL7s%=q|B(BInMVwLS)v2*t|g~BzvcdqE(k?ovRbKAzR?CiX9d|OVP z?9A@ymh?;3U%zVA_3JNjV%?gdEo;s<#p}cqZ;G$$=vWu`g_Y=F`}oYvc>7>f3Hz*4 z{d)FigE1mjjPVCg0K|EC2{Z6CE!AVfdAvZ zvuE$4#Zo-a`fc&{+B z%JuHNb&Q-K-;8X$er9C+!TqaO?|*Q7Waj#fk#9nzrCP2$q+dq3lrZgO`k^aZQp~+T zQyBKeAmrJe3&^t|LFgKqGBV8n1y?|-Hp593_;J0V3Lq#X=7?`6zWU=QHf%WY@vEJ9 z;nMMi)I3uscZ`OWp`C}Jiit{uIi zxA%&pTD&J6W+d0}68w$a-6UN{{aUt9U)&MrZ zCb%62Zpd-Ig3qvRzNA(jo1J9kPn;`*FjE!v(sNAoEQeoT@l zX?QYMvJticceWHMVZmLToDn4zFe9U;RNM4l&DBh>F5y1F+yWX+8op2f5s5VV-Sw} zK^Gj>(gMa&gvT)kt1$z-)yqoo(X7RuY{u9amC$q6wyX(7i#$yiEJd(u7p)iUQ|=R} z5i7?!xCQ_td^T8RTfAFBt1~o0sw}|KvfR_Xgd$krpCd5 zU_0zLVvq>gJYTWzS`OYX#vNd&3Kt}S0%1gw=dsklOF#l42*FZB(iR0(f4{2s_v@Ek zruXOiy`QgCo@&^B>qmAPKxnc~vW%KeI8CT=?)m{b<|`iBzZ$+4Y&rH2#K0EN!S(Gp zWd>7KKsDfbf!cC;vT0$ScJW{cM{6M)>G@^Jj>)NGa@O;(EE3v7#%&ayI*gMFWc17v1wVn z%>wqaZcYpz*xu8#{lGAvH7627v3OfsJT{czvsI#s?vi~zLu?pxS#Dkj#;GL-yIHXA zJUE+y41lnp7SR|vrlgmPs#@&6d1U0~?xLz6+rItSvF###q0(wrppoY;xj|KLxFmH6 z{%=qRwr(95*ea55FLZ0Pm$UX>hLK6(5?X(bf`TIoEUW8|p9WhjY#zo9#|wisV<3FX z(IIbv7cMl4k8|VvfxysA_?(swXX=#-?PK!Y#_Zv+C(a{|tP9~KTRP^PL1QlJ=6cAh zX4V3E&A>K!@GSoF5qxW+?@icyA@jggxH%=bi6L|~a>*If(irauX)je9Y=q+C;pe+4`%Abzv>5 ziKl^5%lOC{f&Uj@I7@0?C~Was@}1!VpBadyz{N?eSSf0VmV9aeGYPFl;73M~K(?+y zDQTQ(y0P?wgJhtX)D`?4fb{6XY7GN7M$$%bQs7#`X zzxpA??{@i>#wJOLdgHl9x7Y3VN_RfC_shG@_C==)d^+QyWlEh}9&^i5eWTm2)Q20* zSNJVvXQcxEW@w9(n$sDsDl5*vDc>!xLZO#5Q6Ypjr1hK3t^8T@+oMlC^VBFkg~PZ0;p)P~^?R~I!=Bft{b=qb8$D|W?relJMF*7m@j`Lt|+u7fyg z_zVP`#z&!HuHwJ1IG`2>`bK0jn@~!hjABYi)b|zSz9M`xGOuqY?R&DbYUE5C`7~wqFo{btkpOaQi6=m1$kDSP^-jW@2``pWi|TK>556>`Dj>PRJ8CJjUV3 z()k3g4|&rhqhm;)sLswx6MHtAT9H?ZW)gRQR?_vMj;bcwFkMQDCL8xub*l;X`ZV@> z5__E>&kl!I1|Awe^x%S93uiA|3Xv2qaRawJ8HzmFvgO)?o3r!BfE&Zu<{3ph*O}6W|Z=`wP(q+_8cOCA%6WzewlE!qVJDu`%qtqQhKoEBqtZw z07Uk?uYrEu@O#j15NQA1Dc5v58-XD;<`%x{-=^8bgXZ`ByvO`!Ki_0N ztvqn&j|I$c^K!uaN4~qx{0kXst7?FGSoMS)c!#I%frY9%^90UCV;cC6 zPKbV^B79uVmr%{}kdf_$z<{q{aR~pNt@HfA8{N>+o7vUuCUzTpkbM*S%5h` zSPG_dBDPDdPwFtotq<&OGED3=OcQr38df~%UY;8$5B5WGh4rZT{lVr4j^k93|^C-$D|ffqLz|Butyf-^5<)Ff*P9^bGSCg zf3Wo4nG@E;qu1fMAoEJhE#C+E(TWV zYQRa93s>9Qy=JEFh@rQ;!A$Yppeo${);jKC>w#_72zwL1|H1FXVqRY6Q1#|3<}26m zwE5j@IDWlxjrm>aRlIomyb7@wvyitF*b6rhNSQ#jG;7fB;S7^$h(v<+%vlpKU5I`g zLf#?zE=-1@{ku5i+Bq4m1gJ@+ivyLO`Vk!^*R8XyzDHzDWMQa?!XH)NW3!-@m7cP) zpl=aRhG4^y*9<>)gTIQzH+~=?1bEP$f-MhK0fPu+1Em@g!wZO8gZqSDl7Sk-&|w%E zI-D7_K*x1KYol=K7e1M}zG?VZtN}U(&%b~66VEyEd<7?}W0%OkFXSLn=p%lw$y_?> z=UuuO2^9;^Hftm+Pu(bwpxLpLcjCiK>Xx=co_o-yVD~qcj6>}Q?Xnk_)Gb4v0$UQO zPfgi;1$hHOw_}EQ7C}QuA|THZL_NitRmO^ld+hXSmyWi2?YQTqojxVI{XK|h?KBe) z{hl*{-zohWdlNc*jL-1Lqtd^xmeo0t10l0VD8curAmdyes(4=8eragjR(PhCUuLLg&JP@TfT9ZR~M) z66tX`L1gTgpZ&FHMf{*lGHD9kJ6Mly9-q^^jAia1*%8 zixNL-th9vmemgBAy~a+vkiN@KyYW3cX{S9X-(jcg;SqlF_<b*5AoK(~ z#3tFX3$`3PdgOR=|MZdRW0S|H_a$$*Be`kn=(eLrj}+LLnENus#k&Wk- zlJw!UA#pYeNhoQ+Doze*fkN9H+7bir^rW=Vz@Z!;2&935K-d!gpd}4d^VHvW-+R(n zaU9^BzM1>(e(!g```vH5@3yVuUCD{m8#aVaIo`EbQBJ3(BNH zcq$M4*M1bD>@DOkqfnP|J-q+$iQ5_LYR5bnlMif!1xh~R`RG7 z^IxzM_aa~W@IY;j(i&sGyj?ct45rBlC=obCOixn0#Vkm*qmI(;cvGu(=3<{kTtGV) zu*F%jQmCk}Nk0q!Z1CrQ{qs-#V(1s2c>Un(Uwi%h8wcMo-uTTgZ=b8q&7lWIuCPky zYfQ9!7A;lL^2J3h`P{2XS5j_W7AwTOktZULM||OrhF%Wc89LGY{pQon+k)q9Sj3?3 z`r?dZ{w4vv)mUPzyi6=vyhP!p%YcD7!^MCtH>+o1AS@M31@rDwFcU6>ysd*VL+tIc28J88UttFTsdb@Cv25sU{V#SK$>`oy+80`pqM8w3wX{jVDtR@uK9B&q^-&(dy;YP@Yu0oSSG}ongR; zz2-i)4A7|nFJI0pMc&IZik~ZaCFbW%JQ4$lN~}yUmdc~N94qHX`6`}OGI_OJibY)P zjHkI_|IK=+D;Agu#JWQI&HEdgJ!jsb*ffAIJp9=2(70xdfYpt*6DNa#JY^kNR=_Em zSctJuDk6SCyq$nXvrN*fIt5Boz;cBIMc&2pp-~Q^^m0EB zM`Ix+llFiTKmetIA#8oV9P>o&+)ys>29bz=CY=NEsDsqT`jUwH~L!|8UiB!zv+y|S$yrfwQ&B3ZTY^*p{NN1wa(wUVH z_*&}cM{2-~wIeq)wlw~|nxlzx>Z|}P*ihf%Lve!*s0DbO@)j*>_PK0ldDhMPSeZ`e zV6Mx0r9B-$qRmAjsd6yGhk1VqA(BxQ6@aDqoFBJ0eBsUDh z)O6jDn2CciJ*^ui(vm*o3u&#nTq`)6>rwl4k16GtV>V+;xI) ztONaslb5B5GnkTo^Y9UuE7kD34DCPYVFkAcB6MMPQLV;tA^->8{Py8FM!(@iXJ>-< zB|3F0>P%Fheyb@GX%ep&G+L&3@w*m^Wh_G@7HtLe`Gy$gcJqFUB@9>9Lq6*33vt6q znLvhBhK*TRyNh|5pS3|og3r@QR*BtMFFsG}HY>N*xj3_MR;#>nXha2XD88xGZA|+5t8L3hvf|3%Y5H5s?Fs2(I6a;!C zMt@_D8CvyM1KI~i5PoS=D@`NZyp116ExI6%=lm$$!rg*FT{xS?_@IgqYqoxn>$+j# z{dXOk2eX$Ld#-kL2`DufWFXUA9O8coTLpLr5>h1Wmon+1q~-@lrBXyNKxLFeB)@ar z4~pAXW-=?c6)EQ9cb?s?o$T=jl)7fGq+OzpIejQj?mm0xxZYQ+3)M^f9Vm}&VRWDa_ejbhGq){G|G&*a~esVb1bztlGt6!1+?JW}prfd4i&uu==L$5#OhQuwR z|2M__s~L1x9vv!k2#1_Uf!rWP0j$0WNu2FofQRG03iZV1%g}(*sPlxEa3NHvBCiO| zh{~yZZ3k+#Fc>LI5Jao^&|scxzPz80__+_U`2ymP%C36v+4{K87xzxpd%g8%y>VY% zld?L}-;!7sJ6kMH#g-)!%VTFdJ(<<~*H$k2H09p4D`!3cH{#Fx5M#Q$uS037!%Sys zrYX#X^wZvYm%KUEDf2`f2BbP z8wS55q6uYtqp=va@%KdZeVF2BhM}3?Mq;VK4Gp|NVg_hi18uv>{tN}ZJecxIkZ1 zv%0K9uoVi!6pSh}IMZcq7LZh#WK=aNX;lpu%p~NtF-g;q9jMLE<%b3w2ggrCXXvzN z4H1VY25-Ft5T*I7s7Toy(-1sfhma>6SeYuoAP8hu)u632E0ESuMT7Y~F=?#ZrdgQ< zpcQNdtrEoyL_4@bvL>ab@@c=M_~l4AA;l7MX<$?;kIL#`QOXzPjM`tzUWxN^gXU<< z8l<2=5_C>%T-%Z8SrP~==}B~~-8j+t_L76oKR7Y*;PVHa7%)m&w#^U{W#$qc=ZBiC z?M}lGO=!%J4auenuT=8#RL09ooNJ^`VCx{N7=R^{0{cZ2LM2wr+~iM?zbbEl9oWN$ z*&4P5*a0#K6NCoBK_=vA#+DYnpg;4xUsht!tKH?IEX>7hCIaQWA7+>;v55x{jEo$h zWn1x!OAjnxeqd>#ySuQEGVkolu36p}+L4$Xk%~J)eaqKmyGAAx=0lp|o+&&gv)UnO zsOobUj$n-?X$yTnzc8f7sPnn>fm{EU=z!^<$t2dAVw>1eYo&_4-`HqnULS&@1eOW| zV!eiVEjDsNsG1u#RE5c&!Ng0!P%ARwY69#dgSNNno|?>*MteeB*3Ze2)e zZP{!a1wNiwl}xYAWY(sWs}jB2GnwtZEd#Co;IWB`V?lrGK#NtjbLsY-*A|P{?%ck# zdt0`1kDA*&aaCvMRTGYmQ*wr)wkY|RbJm*24FGAGup8QQYuTvNPGJn^RZ>Ox_4 z+!t1&Lmd;xj!kq7MU}A6D&=2`EQvHU;1yk#I^4a!Ez}XJug9xxefQziGAK=3FpIZ)QDU4AtN}wLT3p~KTju+{u z3p}Bl^*g+XOawRd)l`sP$f)2?crWF6t)!&Lx~Uz;0izSN?I_P249HTWsYIHutBRDB zCr^p2R}Ju2G9(bA3%xa19~1*z_+~h01u7VpO18V03p%D)0{Dqs0Ux$>*%&-JXhE&o zcuaQZ6?iHjrQnxfl7@MROK$(#T`x#=r%sJJe+|RyRZR{gs{z9)L@nXC9pmdb(+vz` zXKOTKkZ7JxcR5yqUMMu+|GfX)x%+9c6wk2%Tl|K9*ex1Qjz7kW#AN6kiSrI5asUA^0B|Ie zrL99C#|VunX|qg+FC0T4k3l%j2OV%&OY=I8B0P>USdAIzTfM9VAI&P@WCO;=sH8n- zZOfXpXpyJsf~5$scFB4{KIML)HDcvh2iKs$2%insWN1467cG`_V!8kygv!V)htEpa z3?$H>_yHvs7h<_iC$ZPHYqb2TZCE4iwFPxeEJKGaksd3jAfHlTmOz;Sw&6s9K$QiO z0Z9*3wEz^uWT2`CplCY}v`vkJ06})ZH)4PY-aJ>a&sq-NFUB3kP!%pnQVN6-NuI}2 z11~`n2!RQfB9gYis0Id9bznfh;tG8rH{ktzrSeR}mRmo(-GGKB>%_~b>7>(y8s}~p zq;0AWs%+oF&3}I_6%|?2mJy{sv zt&-BJ?jA3!9X8KRcaDrKz3I%EGu@-3-TdYB)xA_Rt5du26Dgi0*AMOwbj~P+shEzr z0V`P{T$o=ewFI&SlYsji#K1MwLOIto>^11yfwi3_(E~0w+lwK*Z_tx)1mT%gahnlI zNrpbK^W@mr$(;jwTfBXJp|HL^-exKGvTja}9N5y+v*o}DpD`yB!?Acc_Wi zIevVLNMEe9nibl}^OxPIsyAMix(xpt)xk}h1_w8ZPgv9(G;98Frb2~R5 z0Sr*G4*jn}7z=rMp67L*pjp4WE`rbIitz?@W!55rtu%;$NJj3HcSlq6YIiSRuD}?OD*G)GXnoFZa7P7UI=XQT6E8Fk!uDbDNu1z z>#Ou>h!$NnfS82TBIQR$kN~!>K`3dQX}Yoa!a*`nOyUau4yg3#!fbdGkU#~%DvL`a z;5Vbf1Qa(+WC6DEk_^>@3z11M@mD{j_}wnQ(%2*^QExog==QqZUg^#!c7J)N*|Fes zflp^5)UMRI<#D$x)i=8RN`1J|e1+d)c2+8&Z-%zmsac)jsItDfH|4wKn^{P%SXwzff%>1O3WRKNw-wLAgx(%ZsO0G-x+)6Q_qaiQ#^d@dsh@E zZ`hR`9`W=I_MEuqkB4`d-;M5`;18R(@Nqim{0h;Oy7Y{+yF>MIdnvo@^do;d*wg3E zE!`30`P~2wsO^D0^J&=tTnDk$@EHho8ka&NT*be?Z&2+U>>riMY(gnr8O4;4sP8Yz z{eAGwkdp!bezLjcSYLRV)XpRAe3^u0p-!D2OuqZtR&B$TU0Y5c809?Jk&PNXpOcnP z^~tW=A3d2}u`xUD_PLjg#N#7NmagiKbGLhQV=#J6qAwj$V?!_K%XwxAl)J%}Q=89v{mMPF=q<@1piRmZp`Dj(PMRl9c#Ol5rSnM~AM&P2MqyZ=tj^3xle^ZLS|6|UnMs`e8A;cN z3sp_DVY-wQP1fzI>Q)or`V4Tr2e?jhv}1TB2bo&~#7guJNT?QuX2b?yEPf45wvZLr4iW zruk1UKXu!o-rhsEow~eh*RCB)i<^czI)*kCm+siLtIPc1=*G6V#N$1y@|vzjJHvga zRuf%t!i!4>|AG!Dd`>WJGqq+}#Bo4L2I)io;1lE`&y}@ZQuT0Tg zcwCeAT%@(ZQC1?~mgDP+%!^!WF0*1*{;;_m9mK$H5C=~MTe$5%(4b8s(3t>zi0>~% z8&Jnm9+d2AI9+j!1&?`2{wek{1JB%AoM|YRxa|>oo&z>CCr^}aBFci7FS2VxupuC= zU{9zSx$>(}KG4-)>rI0S$^*f#w{2`|btS4Zr1+8A=foPR9=d+b*Mk8Lh1GH6QQY4Z z$cKKFaJ8cEPip&6U$9bofO6uK3u}Nz_WQ4azHayfU^hr<|NSA?blMxCLu$+|e8nlR z40|yT6uwJ<@P#MY39zf+6hi>~^8v@)BwYnR;j3>7F7fxQ@UP$Hzv+bk)Svm!eA@r~ zSDIdW&Hvw~*~Ek95B$8x{1-o8Z$7I$c>ddgpZrh2{0)x<%W2_rPh@?%yH|2-A#sxorY=Rjzznz$3&rEl|AV`eD!j>Q8nz2gS89j*qI2>+{AWlpLs zE8X1_3We0>Vsmpy4OQ=}%}IBns2No%n)FoftIhG1&T(<#vFooNqW}kxH4O%@NzY+Y z3n)=b$sgJyi*fl2wK)Ne4U0Kao8v!ReD2IiYvQr%v0dPKCFYjz2mfeA2I@%yBHu4t z%wC97@=m|lGudApYDg6d$KU_>#>B?rbzl9`)2bRT-Fcm?wE{{2g5AzSF2*z^z<5^kO)*|!FqSh;Yuz1?eO>JA%vyBo|D_Xbtr_P5q?FIxlM zW~Hz<@%<0J6N`CynM2f@ub8h~%hTrfuI2c8<6853(yMs!^aT|H7c=0ulfZ==8c3Ox zYH7xx@8JxSX^2FEaOSKDI$emq4I%Fk-3yapXnz-nTn8tkl@w|c>0(2rXMRju$#rXQ ztM3t66ImE4qVUJn_t+$8Wu<4VEZ|$vCquB|$ZLj=-Qcex_KgoD1OpGcQ?TVBDqs)+ zY-p*5#PEW~t-*alFUdfSVdyZ73?0r4TA<^)ptVuB{0pDR+|V@gYt{f6gXcd!`|;sS)qy4Q?+ZSN6#9toHJM9C{hUh|BcWpc*=&tu<*6Ix5i~n?@=knsQQhKp$a4?c z6z%@TqH(DGkX`nTMRo1SQ(%h%^{FYFs~~S6=yuEy&md?BNd)9Mf~cohv&vW>;vPGF z#-*dJUOVmuX{S%gZhtT089U9yL*H{I@SW11vo|5b$N4e-gtS-sJKV77@)zaTU9GMY zuE$)@x%Ya~o-xnuo-Zoh$|mKX>-N^2s(Y#KHE-0bc@KJ@t1s4{sQ*-hzoD<;;|)J* zEHvKKcu(VVzD8fsx660R_eFoy-|7E=|EEoTP4_gt6&MVh4j6$qgLT2y;9bFQHLq*F zF|<5%F!ZsI5jr0ZgvZ1VZ)Q)zlSq$42_j>^{OoT;E20ktWkg-nQel&Jnk37RopvF8 z(oWOub;M44P`=Sl*Mm=;#!28VFG~EVvCl2JEo7{a^UEZWPh=b?ZCGT$Js5YK8glO+(s2y z-$i>}v~b(>zLSUc9LJ>70Q4j~#P+b`7i~Fy^vH?izUd>=$M>9=-kZGfj^z5OqnnQ& uJyK-jV(t@|eIJH7A|ToWkf+&Rl-&rhlWaWzKgu>E5S&He8+_wZ&;J4cTlVb$ diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/anchor.gif b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/anchor.gif deleted file mode 100644 index 606348c7f53dba169a9aca7279a2a973f4b07bdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53 zcmZ?wbhEHbWM^P!XkcUjg8%>jEB<5wG8q|kKzxu40~1eAV&{y5e`l1KFoiKNSOWkz C+YCGa diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/loader.gif b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/loader.gif deleted file mode 100644 index c69e937232b24ea30f01c68bbd2ebc798dcecfcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2608 zcmdVcdr(tX9tZGC9yiG~=H_*Q-0%n(kWqP*D#hw{AQu8;1%gl-Hrf&{2?48KX;hHy z3Ze*zEz4t3XdUFyLbNPUYlA`|B}P=N1fqtL1*}S;87#|-W9v<#G;ul(e%d3)N(^9c$d2Dz{7}?ErjNd;{EMKkCsk21~b9Gvg zDo<7L=3Z5HNbVlZUcm1eg#o#CZCJU`3IYHwM->zCd?uYrF3vKFeM}v?f+%s?E>ly|3W25ry9#NNbTx-}0ON58dTrs^ix{_1O0Wh~SVSBlH)Ajn zPn^Gbjz}PCtN@#keR&hK&Dhl-b$kZ8^S)x#dh0{7X=X%CCJk7P1PSO>T&S8I4{#Lg zb5#)o=;!ZP*1nM{cI4@(x7o27*SA()NHmrn67aN@Pmi~(i_SnrjYnwh36aG%!@i0d zqbvfa44f|?OG4ntP|nbjhEl1)Yp6ZN@yjy zy4==QmLy%t;ps3R?~f2KfTTI|2?q8dFd6^z5GF+Xa&Y)sjG)hxit80pPcOP zJ z*LW{SyGHD%hUotV+W%I}fBLAIx!8|7#}$;clKQ+{&FjDqGQ2ZNx(lYM3*%~}ILnao zM`aui55~ZFJlu^!5rdA9Q_7H68H_;##u{x(Yn-vSfIRCb^Nqsg zGRS!Egm>h+o<}LeV4&CLReo9FrDjDvs}8?JwC)#Qs|ie=r?~xUh)&*d`Fx>FG}%X# zNdtDHBKhLPC0wpooFDAQKL%*6T|ULH$=wX!NhcasgD3d;-d$I6yRK3yN+E~C1335_iLOt+*9uvSZ`>*KA}vm}08wRq=>5l|t*Na&jR z-C1&C`nkEk#sB|@yyt-#fXngP04My zm7u$Q%EJbHp`>~`5W&L{W!6`y&}LMS;jfUpgO~7TLVMRZ9IC)IZp0A${`yp0{&wco z#1nx@XMkhqeK%7?RE7JdLr1^nwFfaJ0Q&Lv?WNJ%9}VSJsNY2+UYs2%EU0J~ayFXv zi*?7KCXQHkD)O6!0Q%4N+HTODHxJ{kQSuQX$l-rSwkwh(zMkdfzxyGwl@yHC)C4p< z&n2%8#M?)Q@mgHL1ot8`SFdSEj9ye|jHy+U8#@HoUExG=@AVkRAe_qYm4EpzK6L*& zh`)26?V#f4#_h^P9G^%>h2-H3)$QP zQovu6J9qDvsxqweDdNNa!Lb?L4_UF{tLX_nN7r0U_vF14YKcGR-*Gl} zx3oG)bzf|65dBxD-;2ZCp??K;+TuQ9onnK?==5hzbkb^r_g>z4#D8mcv8(+XdoszA zCx-qhdgxMNMotj}SiL_6V(tLcsK7(M(r(%u<}QrVfOvyK6_;~NOTlPGfX@M7S5YQF z&*$(ylJMHJt^_aQeu{C6NaTE$G3HNN@_SnN8YcaKn%`)F@~L1x+ah7-gEJPpc6w%3 zyX}r+Qk$4RHZzfH){e~F*qJ{d*L8a6n4;U?+{de0-t)mal#TVxe)3F}^UBh+zd T)6_**#cgp_+?JL9(ew3BlNF>u diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/object.gif b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/img/object.gif deleted file mode 100644 index cccd7f023fb80908cb33bb7d9604236cd21b7ae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmV;J0B8S4Nk%w1VG#fg0J9GO<>lo+KR<78Z?v?uS65g4{r%Y3*xlXT%F4>`@9+2b z_ww@cot>Tk|Nk>HGXMYpA^8LW000jFEC2ui01*HU000C<(8)=wd#<&tyXIMjHBV`d zBSi|xsj3(;nD0kQ0aJq8eLH~x02P|t2!_J&Wqb%0io?#xD.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,0.2);border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window-body .mce-listbox{border-color:#ccc}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:transparent transparent transparent transparent;position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;background-color:#f0f0f0}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;border-color:#ccc}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#dbdbdb;border-color:#ccc}.mce-btn:active{background-color:#e0e0e0;border-color:#ccc}.mce-btn button{padding:4px 8px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px none}.mce-primary{min-width:50px;color:#fff;border:1px solid transparent;border-color:transparent;background-color:#2d8ac7}.mce-primary:hover,.mce-primary:focus{background-color:#257cb6;border-color:transparent}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#206ea1}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px none}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-btn-flat{border:0;background:transparent;filter:none}.mce-btn-flat:hover,.mce-btn-flat.mce-active,.mce-btn-flat:focus,.mce-btn-flat:active{border:0;background:#e6e6e6;filter:none}.mce-btn-has-text .mce-ico{padding-right:5px}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px;margin:0;margin-left:2px}.mce-btn-group:not(:first-child){border-left:1px solid #d9d9d9;padding-left:3px;margin-left:3px}.mce-btn-group .mce-first{margin-left:0}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-rtl .mce-btn-group .mce-btn{margin-left:0;margin-right:2px}.mce-rtl .mce-btn-group .mce-first{margin-right:0}.mce-rtl .mce-btn-group:not(:first-child){border-left:none;border-right:1px solid #d9d9d9;padding-right:4px;margin-right:4px}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;background-color:#f0f0f0;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-checkbox .mce-label{vertical-align:middle}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox .mce-btn{border:1px solid #c5c5c5;border-left:0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-colorbox i{border:1px solid #c5c5c5;width:14px;height:14px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:6px;padding-left:6px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-17px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;padding-right:4px;border-left:1px solid transparent}.mce-colorbutton:hover .mce-open{border-color:#ccc}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:3px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;padding-left:2px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px;border-left:0}.mce-colorpicker{position:relative;width:250px;height:220px}.mce-colorpicker-sv{position:absolute;top:0;left:0;width:90%;height:100%;border:1px solid #c5c5c5;cursor:crosshair;overflow:hidden}.mce-colorpicker-h-chunk{width:100%}.mce-colorpicker-overlay1,.mce-colorpicker-overlay2{width:100%;height:100%;position:absolute;top:0;left:0}.mce-colorpicker-overlay1{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr='#ffffff', endColorstr='#00ffffff');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff')";background:linear-gradient(to right, #fff, rgba(255,255,255,0))}.mce-colorpicker-overlay2{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#00000000', endColorstr='#000000');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00000000', endColorstr='#000000')";background:linear-gradient(to bottom, rgba(0,0,0,0), #000)}.mce-colorpicker-selector1{background:none;position:absolute;width:12px;height:12px;margin:-8px 0 0 -8px;border:1px solid black;border-radius:50%}.mce-colorpicker-selector2{position:absolute;width:10px;height:10px;border:1px solid white;border-radius:50%}.mce-colorpicker-h{position:absolute;top:0;right:0;width:6.5%;height:100%;border:1px solid #c5c5c5;cursor:crosshair}.mce-colorpicker-h-marker{margin-top:-4px;position:absolute;top:0;left:-1px;width:100%;border:1px solid #333;background:#fff;height:4px;z-index:100}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid rgba(0,0,0,0.2);width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;filter:none}.mce-menubar .mce-menubtn button{color:#333}.mce-menubar{border:1px solid rgba(217,217,217,0.52)}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:#ccc;background:#fff;filter:none}.mce-menubtn button{color:#333}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#3498db}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#fff}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#2d8ac7}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:transparent;border-bottom:1px solid rgba(0,0,0,0.1);cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:-1px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-slider{border:1px solid #aaa;background:#eee;width:100px;height:10px;position:relative;display:block}.mce-slider.mce-vertical{width:10px;height:100px}.mce-slider-handle{border:1px solid #bbb;background:#ddd;display:block;width:13px;height:13px;position:absolute;top:0;left:0;margin-left:-1px;margin-top:-2px}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#ccc}.mce-splitbtn button{padding-right:6px;padding-left:6px}.mce-splitbtn .mce-open{padding-right:4px;padding-left:4px}.mce-splitbtn .mce-open.mce-active{background-color:#dbdbdb;outline:1px solid #ccc}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:4px;padding-left:4px}.mce-rtl .mce-splitbtn .mce-open{border-left:0}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tabs,.mce-tabs+.mce-container-body{background:#fff}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#fff;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:#3498db}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce';font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333;-ie7-icon:' '}.mce-btn-small .mce-ico{font-family:'tinymce-small'}.mce-ico,i.mce-i-checkbox{zoom:expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = this.currentStyle['-ie7-icon'].substr(1, 1) + ' ')}.mce-i-save{-ie7-icon:"\e000"}.mce-i-newdocument{-ie7-icon:"\e001"}.mce-i-fullpage{-ie7-icon:"\e002"}.mce-i-alignleft{-ie7-icon:"\e003"}.mce-i-aligncenter{-ie7-icon:"\e004"}.mce-i-alignright{-ie7-icon:"\e005"}.mce-i-alignjustify{-ie7-icon:"\e006"}.mce-i-alignnone{-ie7-icon:"\e003"}.mce-i-cut{-ie7-icon:"\e007"}.mce-i-paste{-ie7-icon:"\e008"}.mce-i-searchreplace{-ie7-icon:"\e009"}.mce-i-bullist{-ie7-icon:"\e00a"}.mce-i-numlist{-ie7-icon:"\e00b"}.mce-i-indent{-ie7-icon:"\e00c"}.mce-i-outdent{-ie7-icon:"\e00d"}.mce-i-blockquote{-ie7-icon:"\e00e"}.mce-i-undo{-ie7-icon:"\e00f"}.mce-i-redo{-ie7-icon:"\e010"}.mce-i-link{-ie7-icon:"\e011"}.mce-i-unlink{-ie7-icon:"\e012"}.mce-i-anchor{-ie7-icon:"\e013"}.mce-i-image{-ie7-icon:"\e014"}.mce-i-media{-ie7-icon:"\e015"}.mce-i-help{-ie7-icon:"\e016"}.mce-i-code{-ie7-icon:"\e017"}.mce-i-insertdatetime{-ie7-icon:"\e018"}.mce-i-preview{-ie7-icon:"\e019"}.mce-i-forecolor{-ie7-icon:"\e01a"}.mce-i-backcolor{-ie7-icon:"\e01a"}.mce-i-table{-ie7-icon:"\e01b"}.mce-i-hr{-ie7-icon:"\e01c"}.mce-i-removeformat{-ie7-icon:"\e01d"}.mce-i-subscript{-ie7-icon:"\e01e"}.mce-i-superscript{-ie7-icon:"\e01f"}.mce-i-charmap{-ie7-icon:"\e020"}.mce-i-emoticons{-ie7-icon:"\e021"}.mce-i-print{-ie7-icon:"\e022"}.mce-i-fullscreen{-ie7-icon:"\e023"}.mce-i-spellchecker{-ie7-icon:"\e024"}.mce-i-nonbreaking{-ie7-icon:"\e025"}.mce-i-template{-ie7-icon:"\e026"}.mce-i-pagebreak{-ie7-icon:"\e027"}.mce-i-restoredraft{-ie7-icon:"\e028"}.mce-i-untitled{-ie7-icon:"\e029"}.mce-i-bold{-ie7-icon:"\e02a"}.mce-i-italic{-ie7-icon:"\e02b"}.mce-i-underline{-ie7-icon:"\e02c"}.mce-i-strikethrough{-ie7-icon:"\e02d"}.mce-i-visualchars{-ie7-icon:"\e02e"}.mce-i-ltr{-ie7-icon:"\e02f"}.mce-i-rtl{-ie7-icon:"\e030"}.mce-i-copy{-ie7-icon:"\e031"}.mce-i-resize{-ie7-icon:"\e032"}.mce-i-browse{-ie7-icon:"\e034"}.mce-i-pastetext{-ie7-icon:"\e035"}.mce-i-rotateleft{-ie7-icon:"\eaa8"}.mce-i-rotateright{-ie7-icon:"\eaa9"}.mce-i-crop{-ie7-icon:"\ee78"}.mce-i-editimage{-ie7-icon:"\e914"}.mce-i-options{-ie7-icon:"\ec6a"}.mce-i-flipv{-ie7-icon:"\eaaa"}.mce-i-fliph{-ie7-icon:"\eaac"}.mce-i-zoomin{-ie7-icon:"\eb35"}.mce-i-zoomout{-ie7-icon:"\eb36"}.mce-i-sun{-ie7-icon:"\eccc"}.mce-i-moon{-ie7-icon:"\eccd"}.mce-i-arrowleft{-ie7-icon:"\edc0"}.mce-i-arrowright{-ie7-icon:"\edb8"}.mce-i-drop{-ie7-icon:"\e934"}.mce-i-contrast{-ie7-icon:"\ecd4"}.mce-i-sharpen{-ie7-icon:"\eba7"}.mce-i-palette{-ie7-icon:"\e92a"}.mce-i-resize2{-ie7-icon:"\edf9"}.mce-i-orientation{-ie7-icon:"\e601"}.mce-i-invert{-ie7-icon:"\e602"}.mce-i-gamma{-ie7-icon:"\e600"}.mce-i-remove{-ie7-icon:"\ed6a"}.mce-i-checkbox,.mce-i-selected{-ie7-icon:"\e033"}.mce-i-selected{visibility:hidden}.mce-i-backcolor{background:#BBB} \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/skin.min.css b/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/skin.min.css deleted file mode 100644 index f314cd61f3..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/skins/lightgray/skin.min.css +++ /dev/null @@ -1 +0,0 @@ -.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:0 0;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:400;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container [unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:inherit!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid rgba(0,0,0,.2);width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td.mce-grid-cell div{border:1px solid #d6d6d6;width:15px;height:15px;margin:0;cursor:pointer}.mce-grid td.mce-grid-cell div:focus{border-color:#3498db}.mce-grid td.mce-grid-cell div[disabled]{cursor:not-allowed}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#3498db}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#3498db;background:#3498db}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%}.mce-colorbtn-trans div{text-align:center;vertical-align:middle;font-weight:700;font-size:20px;line-height:16px;color:#707070}.mce-toolbar-grp{padding:2px 0}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-croprect-container{position:absolute;top:0;left:0}.mce-croprect-handle{position:absolute;top:0;left:0;width:20px;height:20px;border:2px solid #fff}.mce-croprect-handle-nw{border-width:2px 0 0 2px;margin:-2px 0 0 -2px;cursor:nw-resize;top:100px;left:100px}.mce-croprect-handle-ne{border-width:2px 2px 0 0;margin:-2px 0 0 -20px;cursor:ne-resize;top:100px;left:200px}.mce-croprect-handle-sw{border-width:0 0 2px 2px;margin:-20px 2px 0 -2px;cursor:sw-resize;top:200px;left:100px}.mce-croprect-handle-se{border-width:0 2px 2px 0;margin:-20px 0 0 -20px;cursor:se-resize;top:200px;left:200px}.mce-croprect-handle-move{position:absolute;cursor:move;border:0}.mce-croprect-block{opacity:.3;filter:alpha(opacity=30);zoom:1;position:absolute;background:#000}.mce-imagepanel{overflow:auto;background:#000}.mce-imagepanel img{position:absolute}.mce-imagetool.mce-btn .mce-ico{display:block;width:20px;height:20px;text-align:center;line-height:20px;font-size:20px;padding:5px}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,.6);width:5px;height:100%}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1}.mce-scroll{position:relative}.mce-panel{border:0 solid #cacaca;border:0 solid rgba(0,0,0,.2);background-color:#f0f0f0}.mce-floatpanel{position:absolute}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background:0 0;top:0;left:0;background:#fff;border:1px solid rgba(0,0,0,.2);border:1px solid rgba(0,0,0,.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,.2);border-bottom-color:rgba(0,0,0,.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background:0 0;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:700;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:700;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window-body .mce-listbox{border-color:#ccc}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:transparent transparent transparent transparent;position:relative;text-shadow:0 1px 1px rgba(255,255,255,.75);display:inline-block;;;background-color:#f0f0f0}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;border-color:#ccc}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#dbdbdb;border-color:#ccc}.mce-btn:active{background-color:#e0e0e0;border-color:#ccc}.mce-btn button{padding:4px 8px;font-size:14px;line-height:20px;;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px none}.mce-primary{min-width:50px;color:#fff;border:1px solid transparent;border-color:transparent;background-color:#2d8ac7}.mce-primary:hover,.mce-primary:focus{background-color:#257cb6;border-color:transparent}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#206ea1}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px none}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;}.mce-btn-small i{line-height:20px;vertical-align:top;}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;;;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-btn-flat{border:0;background:0 0;filter:none}.mce-btn-flat:hover,.mce-btn-flat.mce-active,.mce-btn-flat:focus,.mce-btn-flat:active{border:0;background:#e6e6e6;filter:none}.mce-btn-has-text .mce-ico{padding-right:5px}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px;margin:0;margin-left:2px}.mce-btn-group:not(:first-child){border-left:1px solid #d9d9d9;padding-left:3px;margin-left:3px}.mce-btn-group .mce-first{margin-left:0}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-rtl .mce-btn-group .mce-btn{margin-left:0;margin-right:2px}.mce-rtl .mce-btn-group .mce-first{margin-right:0}.mce-rtl .mce-btn-group:not(:first-child){border-left:none;border-right:1px solid #d9d9d9;padding-right:4px;margin-right:4px}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;background-color:#f0f0f0;text-indent:-10em;;;;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,.8)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-checkbox .mce-label{vertical-align:middle}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-combobox{display:inline-block;;;}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox .mce-btn{border:1px solid #c5c5c5;border-left:0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-colorbox i{border:1px solid #c5c5c5;width:14px;height:14px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:6px;padding-left:6px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-17px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;padding-right:4px;border-left:1px solid transparent}.mce-colorbutton:hover .mce-open{border-color:#ccc}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:3px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;padding-left:2px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px;border-left:0}.mce-colorpicker{position:relative;width:250px;height:220px}.mce-colorpicker-sv{position:absolute;top:0;left:0;width:90%;height:100%;border:1px solid #c5c5c5;cursor:crosshair;overflow:hidden}.mce-colorpicker-h-chunk{width:100%}.mce-colorpicker-overlay1,.mce-colorpicker-overlay2{width:100%;height:100%;position:absolute;top:0;left:0}.mce-colorpicker-overlay1{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr='#ffffff', endColorstr='#00ffffff');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff')";background:linear-gradient(to right,#fff,rgba(255,255,255,0))}.mce-colorpicker-overlay2{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#00000000', endColorstr='#000000');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00000000', endColorstr='#000000')";background:linear-gradient(to bottom,rgba(0,0,0,0),#000)}.mce-colorpicker-selector1{background:0 0;position:absolute;width:12px;height:12px;margin:-8px 0 0 -8px;border:1px solid #000;border-radius:50%}.mce-colorpicker-selector2{position:absolute;width:10px;height:10px;border:1px solid #fff;border-radius:50%}.mce-colorpicker-h{position:absolute;top:0;right:0;width:6.5%;height:100%;border:1px solid #c5c5c5;cursor:crosshair}.mce-colorpicker-h-marker{margin-top:-4px;position:absolute;top:0;left:-1px;width:100%;border:1px solid #333;background:#fff;height:4px;z-index:100}.mce-path{display:inline-block;;;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;;;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;;}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;;}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid rgba(0,0,0,.2);width:100%;height:100%}.mce-label{display:inline-block;;;text-shadow:0 1px 1px rgba(255,255,255,.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:0 0;filter:none}.mce-menubar .mce-menubtn button{color:#333}.mce-menubar{border:1px solid rgba(217,217,217,.52)}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:#ccc;background:#fff;filter:none}.mce-menubtn button{color:#333}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:400;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;;;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#3498db}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#fff}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#2d8ac7}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:0 0;border-bottom:1px solid rgba(0,0,0,.1);cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background:0 0;z-index:1000;padding:5px 0 5px 0;margin:-1px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,.2);z-index:1002;max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-slider{border:1px solid #aaa;background:#eee;width:100px;height:10px;position:relative;display:block}.mce-slider.mce-vertical{width:10px;height:100px}.mce-slider-handle{border:1px solid #bbb;background:#ddd;display:block;width:13px;height:13px;position:absolute;top:0;left:0;margin-left:-1px;margin-top:-2px}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#ccc}.mce-splitbtn button{padding-right:6px;padding-left:6px}.mce-splitbtn .mce-open{padding-right:4px;padding-left:4px}.mce-splitbtn .mce-open.mce-active{background-color:#dbdbdb;outline:1px solid #ccc}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:4px;padding-left:4px}.mce-rtl .mce-splitbtn .mce-open{border-left:0}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tabs,.mce-tabs+.mce-container-body{background:#fff}.mce-tab{display:inline-block;;;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#fff;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:#3498db}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url(img/loader.gif) no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:tinymce;src:url(fonts/tinymce.eot);src:url(fonts/tinymce.eot?#iefix) format('embedded-opentype'),url(fonts/tinymce.woff) format('woff'),url(fonts/tinymce.ttf) format('truetype'),url(fonts/tinymce.svg#tinymce) format('svg');font-weight:400;font-style:normal}@font-face{font-family:tinymce-small;src:url(fonts/tinymce-small.eot);src:url(fonts/tinymce-small.eot?#iefix) format('embedded-opentype'),url(fonts/tinymce-small.woff) format('woff'),url(fonts/tinymce-small.ttf) format('truetype'),url(fonts/tinymce-small.svg#tinymce) format('svg');font-weight:400;font-style:normal}.mce-ico{font-family:tinymce,Arial;font-style:normal;font-weight:400;font-variant:normal;font-size:16px;line-height:16px;speak:none;vertical-align:text-top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;background:transparent center center;background-size:cover;width:16px;height:16px;color:#333}.mce-btn-small .mce-ico{font-family:tinymce-small,Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-alignnone:before{content:"\e003"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-insertdatetime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-rotateleft:before{content:"\eaa8"}.mce-i-rotateright:before{content:"\eaa9"}.mce-i-crop:before{content:"\ee78"}.mce-i-editimage:before{content:"\e914"}.mce-i-options:before{content:"\ec6a"}.mce-i-flipv:before{content:"\eaaa"}.mce-i-fliph:before{content:"\eaac"}.mce-i-zoomin:before{content:"\eb35"}.mce-i-zoomout:before{content:"\eb36"}.mce-i-sun:before{content:"\eccc"}.mce-i-moon:before{content:"\eccd"}.mce-i-arrowleft:before{content:"\edc0"}.mce-i-arrowright:before{content:"\edb8"}.mce-i-drop:before{content:"\e934"}.mce-i-contrast:before{content:"\ecd4"}.mce-i-sharpen:before{content:"\eba7"}.mce-i-palette:before{content:"\e92a"}.mce-i-resize2:before{content:"\edf9"}.mce-i-orientation:before{content:"\e601"}.mce-i-invert:before{content:"\e602"}.mce-i-gamma:before{content:"\e600"}.mce-i-remove:before{content:"\ed6a"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#bbb} \ No newline at end of file diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/tinymce.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/tinymce.min.js deleted file mode 100644 index f55021f21c..0000000000 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/tinymce.min.js +++ /dev/null @@ -1,12 +0,0 @@ -// 4.2.6 (2015-09-28) -!function(e,t){"use strict";function n(e,t){for(var n,r=[],i=0;ir;r++)if(o=n[r],o&&o.func.call(o.scope,e)===!1&&e.preventDefault(),e.isImmediatePropagationStopped())return}var a=this,s={},l,c,u,d,f;c=o+(+new Date).toString(32),d="onmouseenter"in document.documentElement,u="onfocusin"in document.documentElement,f={mouseenter:"mouseover",mouseleave:"mouseout"},l=1,a.domLoaded=!1,a.events=s,a.bind=function(t,o,h,p){function m(e){i(n(e||_.event),g)}var g,v,y,b,x,C,w,_=window;if(t&&3!==t.nodeType&&8!==t.nodeType){for(t[c]?g=t[c]:(g=l++,t[c]=g,s[g]={}),p=p||t,o=o.split(" "),y=o.length;y--;)b=o[y],C=m,x=w=!1,"DOMContentLoaded"===b&&(b="ready"),a.domLoaded&&"ready"===b&&"complete"==t.readyState?h.call(p,n({type:b})):(d||(x=f[b],x&&(C=function(e){var t,r;if(t=e.currentTarget,r=e.relatedTarget,r&&t.contains)r=t.contains(r);else for(;r&&r!==t;)r=r.parentNode;r||(e=n(e||_.event),e.type="mouseout"===e.type?"mouseleave":"mouseenter",e.target=t,i(e,g))})),u||"focusin"!==b&&"focusout"!==b||(w=!0,x="focusin"===b?"focus":"blur",C=function(e){e=n(e||_.event),e.type="focus"===e.type?"focusin":"focusout",i(e,g)}),v=s[g][b],v?"ready"===b&&a.domLoaded?h({type:b}):v.push({func:h,scope:p}):(s[g][b]=v=[{func:h,scope:p}],v.fakeName=x,v.capture=w,v.nativeHandler=C,"ready"===b?r(t,C,a):e(t,x||b,C,w)));return t=v=0,h}},a.unbind=function(e,n,r){var i,o,l,u,d,f;if(!e||3===e.nodeType||8===e.nodeType)return a;if(i=e[c]){if(f=s[i],n){for(n=n.split(" "),l=n.length;l--;)if(d=n[l],o=f[d]){if(r)for(u=o.length;u--;)if(o[u].func===r){var h=o.nativeHandler,p=o.fakeName,m=o.capture;o=o.slice(0,u).concat(o.slice(u+1)),o.nativeHandler=h,o.fakeName=p,o.capture=m,f[d]=o}r&&0!==o.length||(delete f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture))}}else{for(d in f)o=f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture);f={}}for(d in f)return a;delete s[i];try{delete e[c]}catch(g){e[c]=null}}return a},a.fire=function(e,t,r){var o;if(!e||3===e.nodeType||8===e.nodeType)return a;r=n(null,r),r.type=t,r.target=e;do o=e[c],o&&i(r,o),e=e.parentNode||e.ownerDocument||e.defaultView||e.parentWindow;while(e&&!r.isPropagationStopped());return a},a.clean=function(e){var t,n,r=a.unbind;if(!e||3===e.nodeType||8===e.nodeType)return a;if(e[c]&&r(e),e.getElementsByTagName||(e=e.document),e&&e.getElementsByTagName)for(r(e),n=e.getElementsByTagName("*"),t=n.length;t--;)e=n[t],e[c]&&r(e);return a},a.destroy=function(){s={}},a.cancel=function(e){return e&&(e.preventDefault(),e.stopImmediatePropagation()),!1}}var o="mce-data-",a=/^(?:mouse|contextmenu)|click/,s={keyLocation:1,layerX:1,layerY:1,returnValue:1,webkitMovementX:1,webkitMovementY:1};return i.Event=new i,i.Event.bind(window,"ready",function(){}),i}),r(c,[],function(){function e(e,t,n,r){var i,o,a,s,l,c,d,h,p,m;if((t?t.ownerDocument||t:z)!==D&&B(t),t=t||D,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(L&&!r){if(i=ve.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&I(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return Z.apply(n,t.getElementsByTagName(e)),n;if((a=i[3])&&C.getElementsByClassName)return Z.apply(n,t.getElementsByClassName(a)),n}if(C.qsa&&(!H||!H.test(e))){if(h=d=F,p=t,m=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){for(c=N(e),(d=t.getAttribute("id"))?h=d.replace(be,"\\$&"):t.setAttribute("id",h),h="[id='"+h+"'] ",l=c.length;l--;)c[l]=h+f(c[l]);p=ye.test(e)&&u(t.parentNode)||t,m=c.join(",")}if(m)try{return Z.apply(n,p.querySelectorAll(m)),n}catch(g){}finally{d||t.removeAttribute("id")}}}return k(e.replace(se,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>w.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[F]=!0,e}function i(e){var t=D.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=e.length;r--;)w.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||Y)-(~e.sourceIndex||Y);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function l(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function u(e){return e&&typeof e.getElementsByTagName!==K&&e}function d(){}function f(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function h(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=V++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[F]||(t[F]={}),(s=l[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(l[r]=c,c[2]=e(t,n,a))return!0}}}function p(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function m(t,n,r){for(var i=0,o=n.length;o>i;i++)e(t,n[i],r);return r}function g(e,t,n,r,i){for(var o,a=[],s=0,l=e.length,c=null!=t;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),c&&t.push(s));return a}function v(e,t,n,i,o,a){return i&&!i[F]&&(i=v(i)),o&&!o[F]&&(o=v(o,a)),r(function(r,a,s,l){var c,u,d,f=[],h=[],p=a.length,v=r||m(t||"*",s.nodeType?[s]:s,[]),y=!e||!r&&t?v:g(v,f,e,s,l),b=n?o||(r?e:p||i)?[]:a:y;if(n&&n(y,b,s,l),i)for(c=g(b,h),i(c,[],s,l),u=c.length;u--;)(d=c[u])&&(b[h[u]]=!(y[h[u]]=d));if(r){if(o||e){if(o){for(c=[],u=b.length;u--;)(d=b[u])&&c.push(y[u]=d);o(null,b=[],c,l)}for(u=b.length;u--;)(d=b[u])&&(c=o?te.call(r,d):f[u])>-1&&(r[c]=!(a[c]=d))}}else b=g(b===a?b.splice(p,b.length):b),o?o(null,a,b,l):Z.apply(a,b)})}function y(e){for(var t,n,r,i=e.length,o=w.relative[e[0].type],a=o||w.relative[" "],s=o?1:0,l=h(function(e){return e===t},a,!0),c=h(function(e){return te.call(t,e)>-1},a,!0),u=[function(e,n,r){return!o&&(r||n!==T)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];i>s;s++)if(n=w.relative[e[s].type])u=[h(p(u),n)];else{if(n=w.filter[e[s].type].apply(null,e[s].matches),n[F]){for(r=++s;i>r&&!w.relative[e[r].type];r++);return v(s>1&&p(u),s>1&&f(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(se,"$1"),n,r>s&&y(e.slice(s,r)),i>r&&y(e=e.slice(r)),i>r&&f(e))}u.push(n)}return p(u)}function b(t,n){var i=n.length>0,o=t.length>0,a=function(r,a,s,l,c){var u,d,f,h=0,p="0",m=r&&[],v=[],y=T,b=r||o&&w.find.TAG("*",c),x=W+=null==y?1:Math.random()||.1,C=b.length;for(c&&(T=a!==D&&a);p!==C&&null!=(u=b[p]);p++){if(o&&u){for(d=0;f=t[d++];)if(f(u,a,s)){l.push(u);break}c&&(W=x)}i&&((u=!f&&u)&&h--,r&&m.push(u))}if(h+=p,i&&p!==h){for(d=0;f=n[d++];)f(m,v,a,s);if(r){if(h>0)for(;p--;)m[p]||v[p]||(v[p]=J.call(l));v=g(v)}Z.apply(l,v),c&&!r&&v.length>0&&h+n.length>1&&e.uniqueSort(l)}return c&&(W=x,T=y),m};return i?r(a):a}var x,C,w,_,E,N,S,k,T,R,A,B,D,M,L,H,P,O,I,F="sizzle"+-new Date,z=window.document,W=0,V=0,U=n(),$=n(),q=n(),j=function(e,t){return e===t&&(A=!0),0},K=typeof t,Y=1<<31,G={}.hasOwnProperty,X=[],J=X.pop,Q=X.push,Z=X.push,ee=X.slice,te=X.indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(this[t]===e)return t;return-1},ne="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",re="[\\x20\\t\\r\\n\\f]",ie="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",oe="\\["+re+"*("+ie+")(?:"+re+"*([*^$|!~]?=)"+re+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+ie+"))|)"+re+"*\\]",ae=":("+ie+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+oe+")*)|.*)\\)|)",se=new RegExp("^"+re+"+|((?:^|[^\\\\])(?:\\\\.)*)"+re+"+$","g"),le=new RegExp("^"+re+"*,"+re+"*"),ce=new RegExp("^"+re+"*([>+~]|"+re+")"+re+"*"),ue=new RegExp("="+re+"*([^\\]'\"]*?)"+re+"*\\]","g"),de=new RegExp(ae),fe=new RegExp("^"+ie+"$"),he={ID:new RegExp("^#("+ie+")"),CLASS:new RegExp("^\\.("+ie+")"),TAG:new RegExp("^("+ie+"|[*])"),ATTR:new RegExp("^"+oe),PSEUDO:new RegExp("^"+ae),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+re+"*(even|odd|(([+-]|)(\\d*)n|)"+re+"*(?:([+-]|)"+re+"*(\\d+)|))"+re+"*\\)|)","i"),bool:new RegExp("^(?:"+ne+")$","i"),needsContext:new RegExp("^"+re+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+re+"*((?:-\\d)?\\d*)"+re+"*\\)|)(?=[^-]|$)","i")},pe=/^(?:input|select|textarea|button)$/i,me=/^h\d$/i,ge=/^[^{]+\{\s*\[native \w/,ve=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ye=/[+~]/,be=/'|\\/g,xe=new RegExp("\\\\([\\da-f]{1,6}"+re+"?|("+re+")|.)","ig"),Ce=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)};try{Z.apply(X=ee.call(z.childNodes),z.childNodes),X[z.childNodes.length].nodeType}catch(we){Z={apply:X.length?function(e,t){Q.apply(e,ee.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}C=e.support={},E=e.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},B=e.setDocument=function(e){var t,n=e?e.ownerDocument||e:z,r=n.defaultView;return n!==D&&9===n.nodeType&&n.documentElement?(D=n,M=n.documentElement,L=!E(n),r&&r!==r.top&&(r.addEventListener?r.addEventListener("unload",function(){B()},!1):r.attachEvent&&r.attachEvent("onunload",function(){B()})),C.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),C.getElementsByTagName=i(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),C.getElementsByClassName=ge.test(n.getElementsByClassName),C.getById=i(function(e){return M.appendChild(e).id=F,!n.getElementsByName||!n.getElementsByName(F).length}),C.getById?(w.find.ID=function(e,t){if(typeof t.getElementById!==K&&L){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},w.filter.ID=function(e){var t=e.replace(xe,Ce);return function(e){return e.getAttribute("id")===t}}):(delete w.find.ID,w.filter.ID=function(e){var t=e.replace(xe,Ce);return function(e){var n=typeof e.getAttributeNode!==K&&e.getAttributeNode("id");return n&&n.value===t}}),w.find.TAG=C.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==K?t.getElementsByTagName(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},w.find.CLASS=C.getElementsByClassName&&function(e,t){return L?t.getElementsByClassName(e):void 0},P=[],H=[],(C.qsa=ge.test(n.querySelectorAll))&&(i(function(e){e.innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&H.push("[*^$]="+re+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||H.push("\\["+re+"*(?:value|"+ne+")"),e.querySelectorAll(":checked").length||H.push(":checked")}),i(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&H.push("name"+re+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||H.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),H.push(",.*:")})),(C.matchesSelector=ge.test(O=M.matches||M.webkitMatchesSelector||M.mozMatchesSelector||M.oMatchesSelector||M.msMatchesSelector))&&i(function(e){C.disconnectedMatch=O.call(e,"div"),O.call(e,"[s!='']:x"),P.push("!=",ae)}),H=H.length&&new RegExp(H.join("|")),P=P.length&&new RegExp(P.join("|")),t=ge.test(M.compareDocumentPosition),I=t||ge.test(M.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return A=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r?r:(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&r||!C.sortDetached&&t.compareDocumentPosition(e)===r?e===n||e.ownerDocument===z&&I(z,e)?-1:t===n||t.ownerDocument===z&&I(z,t)?1:R?te.call(R,e)-te.call(R,t):0:4&r?-1:1)}:function(e,t){if(e===t)return A=!0,0;var r,i=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(!o||!s)return e===n?-1:t===n?1:o?-1:s?1:R?te.call(R,e)-te.call(R,t):0;if(o===s)return a(e,t);for(r=e;r=r.parentNode;)l.unshift(r);for(r=t;r=r.parentNode;)c.unshift(r);for(;l[i]===c[i];)i++;return i?a(l[i],c[i]):l[i]===z?-1:c[i]===z?1:0},n):D},e.matches=function(t,n){return e(t,null,null,n)},e.matchesSelector=function(t,n){if((t.ownerDocument||t)!==D&&B(t),n=n.replace(ue,"='$1']"),C.matchesSelector&&L&&(!P||!P.test(n))&&(!H||!H.test(n)))try{var r=O.call(t,n);if(r||C.disconnectedMatch||t.document&&11!==t.document.nodeType)return r}catch(i){}return e(n,D,null,[t]).length>0},e.contains=function(e,t){return(e.ownerDocument||e)!==D&&B(e),I(e,t)},e.attr=function(e,n){(e.ownerDocument||e)!==D&&B(e);var r=w.attrHandle[n.toLowerCase()],i=r&&G.call(w.attrHandle,n.toLowerCase())?r(e,n,!L):t;return i!==t?i:C.attributes||!L?e.getAttribute(n):(i=e.getAttributeNode(n))&&i.specified?i.value:null},e.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},e.uniqueSort=function(e){var t,n=[],r=0,i=0;if(A=!C.detectDuplicates,R=!C.sortStable&&e.slice(0),e.sort(j),A){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return R=null,e},_=e.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=_(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=_(t);return n},w=e.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,Ce),e[3]=(e[3]||e[4]||e[5]||"").replace(xe,Ce),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||e.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&e.error(t[0]),t},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&de.test(n)&&(t=N(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,Ce).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+" "];return t||(t=new RegExp("(^|"+re+")"+e+"("+re+"|$)"))&&U(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==K&&e.getAttribute("class")||"")})},ATTR:function(t,n,r){return function(i){var o=e.attr(i,t);return null==o?"!="===n:n?(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o+" ").indexOf(r)>-1:"|="===n?o===r||o.slice(0,r.length+1)===r+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,h,p,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!l&&!s;if(g){if(o){for(;m;){for(d=t;d=d[m];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;p=m="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?g.firstChild:g.lastChild],a&&y){for(u=g[F]||(g[F]={}),c=u[e]||[],h=c[0]===W&&c[1],f=c[0]===W&&c[2],d=h&&g.childNodes[h];d=++h&&d&&d[m]||(f=h=0)||p.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[W,h,f];break}}else if(y&&(c=(t[F]||(t[F]={}))[e])&&c[0]===W)f=c[1];else for(;(d=++h&&d&&d[m]||(f=h=0)||p.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||(y&&((d[F]||(d[F]={}))[e]=[W,f]),d!==t)););return f-=i,f===r||f%r===0&&f/r>=0}}},PSEUDO:function(t,n){var i,o=w.pseudos[t]||w.setFilters[t.toLowerCase()]||e.error("unsupported pseudo: "+t);return o[F]?o(n):o.length>1?(i=[t,t,"",n],w.setFilters.hasOwnProperty(t.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=te.call(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=S(e.replace(se,"$1"));return i[F]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),!n.pop()}}),has:r(function(t){return function(n){return e(t,n).length>0}}),contains:r(function(e){return e=e.replace(xe,Ce),function(t){return(t.textContent||t.innerText||_(t)).indexOf(e)>-1}}),lang:r(function(t){return fe.test(t||"")||e.error("unsupported lang: "+t),t=t.replace(xe,Ce).toLowerCase(),function(e){var n;do if(n=L?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return n=n.toLowerCase(),n===t||0===n.indexOf(t+"-");while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=window.location&&window.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===M},focus:function(e){return e===D.activeElement&&(!D.hasFocus||D.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!w.pseudos.empty(e)},header:function(e){return me.test(e.nodeName)},input:function(e){return pe.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[0>n?n+t:n]}),even:c(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=0>n?n+t:n;++r2&&"ID"===(a=o[0]).type&&C.getById&&9===t.nodeType&&L&&w.relative[o[1].type]){if(t=(w.find.ID(a.matches[0].replace(xe,Ce),t)||[])[0],!t)return n;c&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=he.needsContext.test(e)?0:o.length;i--&&(a=o[i],!w.relative[s=a.type]);)if((l=w.find[s])&&(r=l(a.matches[0].replace(xe,Ce),ye.test(o[0].type)&&u(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&f(o),!e)return Z.apply(n,r),n;break}}return(c||S(e,d))(r,t,!L,n,ye.test(e)&&u(t.parentNode)||t),n},C.sortStable=F.split("").sort(j).join("")===F,C.detectDuplicates=!!A,B(),C.sortDetached=i(function(e){return 1&e.compareDocumentPosition(D.createElement("div"))}),i(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){return n?void 0:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),C.attributes&&i(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?void 0:e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(ne,function(e,t,n){var r;return n?void 0:e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),e}),r(u,[],function(){var e=navigator,t=e.userAgent,n,r,i,o,a,s,l,c,u,d;n=window.opera&&window.opera.buildNumber,u=/Android/.test(t),r=/WebKit/.test(t),i=!r&&!n&&/MSIE/gi.test(t)&&/Explorer/gi.test(e.appName),i=i&&/MSIE (\w+)\./.exec(t)[1],o=-1==t.indexOf("Trident/")||-1==t.indexOf("rv:")&&-1==e.appName.indexOf("Netscape")?!1:11,a=-1==t.indexOf("Edge/")||i||o?!1:12,i=i||o||a,s=!r&&!o&&/Gecko/.test(t),l=-1!=t.indexOf("Mac"),c=/(iPad|iPhone)/.test(t),d="FormData"in window&&"FileReader"in window&&"URL"in window&&!!URL.createObjectURL,a&&(r=!1);var f=!c||d||t.match(/AppleWebKit\/(\d*)/)[1]>=534;return{opera:n,webkit:r,ie:i,gecko:s,mac:l,iOS:c,android:u,contentEditable:f,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=i,range:window.getSelection&&"Range"in window,documentMode:i&&!a?document.documentMode||7:10,fileApi:d}}),r(d,[],function(){function e(e){var t=e,n,r;if(!s(e))for(t=[],n=0,r=e.length;r>n;n++)t[n]=e[n];return t}function n(e,n,r){var i,o;if(!e)return 0;if(r=r||e,e.length!==t){for(i=0,o=e.length;o>i;i++)if(n.call(r,e[i],i,e)===!1)return 0}else for(i in e)if(e.hasOwnProperty(i)&&n.call(r,e[i],i,e)===!1)return 0;return 1}function r(e,t){var r=[];return n(e,function(n,i){r.push(t(n,i,e))}),r}function i(e,t){var r=[];return n(e,function(e){(!t||t(e))&&r.push(e)}),r}function o(e,t){var n,r;if(e)for(n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}function a(e,t,n,r){var i=0;for(arguments.length<3&&(n=e[0],i=1);ir;r++){n=a[r];for(o in n)n.hasOwnProperty(o)&&(s=n[o],s!==t&&(e[o]=s))}return e}function l(e,t,r,i){i=i||this,e&&(r&&(e=e[r]),n.each(e,function(e,n){return t.call(i,e,n,r)===!1?!1:void l(e,t,r,i)}))}function c(e,t){var n,r;for(t=t||window,e=e.split("."),n=0;nn&&(t=t[e[n]],t);n++);return t}function d(e,t){return!e||i(e,"array")?e:n.map(e.split(t||","),r)}function f(t){var n=e.cacheSuffix;return n&&(t+=(-1===t.indexOf("?")?"?":"&")+n),t}var h=/^\s*|\s*$/g;return{trim:r,isArray:n.isArray,is:i,toArray:n.toArray,makeMap:o,each:n.each,map:n.map,grep:n.filter,inArray:n.indexOf,extend:s,create:a,walk:l,createNS:c,resolve:u,explode:d,_addCacheSuffix:f}}),r(h,[l,c,f,u],function(e,n,r,i){function o(e){return"undefined"!=typeof e}function a(e){return"string"==typeof e}function s(e){return e&&e==e.window}function l(e,t){var n,r,i;for(t=t||w,i=t.createElement("div"),n=t.createDocumentFragment(),i.innerHTML=e;r=i.firstChild;)n.appendChild(r);return n}function c(e,t,n,r){var i;if(a(t))t=l(t,v(e[0]));else if(t.length&&!t.nodeType){if(t=f.makeArray(t),r)for(i=t.length-1;i>=0;i--)c(e,t[i],n,r);else for(i=0;ii&&(a=e[i],t.call(a,i,a)!==!1);i++);return e}function g(e,t){var n=[];return m(e,function(e,r){t(r,e)&&n.push(r)}),n}function v(e){return e?9==e.nodeType?e:e.ownerDocument:w}function y(e,n,r){var i=[],o=e[n];for("string"!=typeof r&&r instanceof f&&(r=r[0]);o&&9!==o.nodeType;){if(r!==t){if(o===r)break;if("string"==typeof r&&f(o).is(r))break}1===o.nodeType&&i.push(o),o=o[n]}return i}function b(e,n,r,i){var o=[];for(i instanceof f&&(i=i[0]);e;e=e[n])if(!r||e.nodeType===r){if(i!==t){if(e===i)break;if("string"==typeof i&&f(e).is(i))break}o.push(e)}return o}function x(e,t,n){for(e=e[t];e;e=e[t])if(e.nodeType==n)return e;return null}function C(e,t,n){m(n,function(n,r){e[n]=e[n]||{},e[n][t]=r})}var w=document,_=Array.prototype.push,E=Array.prototype.slice,N=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,S=e.Event,k,T=r.makeMap("children,contents,next,prev"),R=r.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," "),A=r.makeMap("checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected"," "),B={ -"for":"htmlFor","class":"className",readonly:"readOnly"},D={"float":"cssFloat"},M={},L={},H=/^\s*|\s*$/g;return f.fn=f.prototype={constructor:f,selector:"",context:null,length:0,init:function(e,t){var n=this,r,i;if(!e)return n;if(e.nodeType)return n.context=n[0]=e,n.length=1,n;if(t&&t.nodeType)n.context=t;else{if(t)return f(e).attr(t);n.context=t=document}if(a(e)){if(n.selector=e,r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!r)return f(t).find(e);if(r[1])for(i=l(e,v(t)).firstChild;i;)_.call(n,i),i=i.nextSibling;else{if(i=v(t).getElementById(r[2]),!i)return n;if(i.id!==r[2])return n.find(e);n.length=1,n[0]=i}}else this.add(e,!1);return n},toArray:function(){return r.toArray(this)},add:function(e,t){var n=this,r,i;if(a(e))return n.add(f(e));if(t!==!1)for(r=f.unique(n.toArray().concat(f.makeArray(e))),n.length=r.length,i=0;it;t++)f.find(e,this[t],r);return f(r)},filter:function(e){return f("function"==typeof e?g(this.toArray(),function(t,n){return e(n,t)}):f.filter(e,this.toArray()))},closest:function(e){var t=[];return e instanceof f&&(e=e[0]),this.each(function(n,r){for(;r;){if("string"==typeof e&&f(r).is(e)){t.push(r);break}if(r==e){t.push(r);break}r=r.parentNode}}),f(t)},offset:function(e){var t,n,r,i=0,o=0,a;return e?this.css(e):(t=this[0],t&&(n=t.ownerDocument,r=n.documentElement,t.getBoundingClientRect&&(a=t.getBoundingClientRect(),i=a.left+(r.scrollLeft||n.body.scrollLeft)-r.clientLeft,o=a.top+(r.scrollTop||n.body.scrollTop)-r.clientTop)),{left:i,top:o})},push:_,sort:[].sort,splice:[].splice},r.extend(f,{extend:r.extend,makeArray:function(e){return s(e)||e.nodeType?[e]:r.toArray(e)},inArray:h,isArray:r.isArray,each:m,trim:p,grep:g,find:n,expr:n.selectors,unique:n.uniqueSort,text:n.getText,contains:n.contains,filter:function(e,t,n){var r=t.length;for(n&&(e=":not("+e+")");r--;)1!=t[r].nodeType&&t.splice(r,1);return t=1===t.length?f.find.matchesSelector(t[0],e)?[t[0]]:[]:f.find.matches(e,t)}}),m({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return y(e,"parentNode")},next:function(e){return x(e,"nextSibling",1)},prev:function(e){return x(e,"previousSibling",1)},children:function(e){return b(e.firstChild,"nextSibling",1)},contents:function(e){return r.toArray(("iframe"===e.nodeName?e.contentDocument||e.contentWindow.document:e).childNodes)}},function(e,t){f.fn[e]=function(n){var r=this,i=[];return r.each(function(){var e=t.call(i,this,n,i);e&&(f.isArray(e)?i.push.apply(i,e):i.push(e))}),this.length>1&&(T[e]||(i=f.unique(i)),0===e.indexOf("parents")&&(i=i.reverse())),i=f(i),n?i.filter(n):i}}),m({parentsUntil:function(e,t){return y(e,"parentNode",t)},nextUntil:function(e,t){return b(e,"nextSibling",1,t).slice(1)},prevUntil:function(e,t){return b(e,"previousSibling",1,t).slice(1)}},function(e,t){f.fn[e]=function(n,r){var i=this,o=[];return i.each(function(){var e=t.call(o,this,n,o);e&&(f.isArray(e)?o.push.apply(o,e):o.push(e))}),this.length>1&&(o=f.unique(o),(0===e.indexOf("parents")||"prevUntil"===e)&&(o=o.reverse())),o=f(o),r?o.filter(r):o}}),f.fn.is=function(e){return!!e&&this.filter(e).length>0},f.fn.init.prototype=f.fn,f.overrideDefaults=function(e){function t(r,i){return n=n||e(),0===arguments.length&&(r=n.element),i||(i=n.context),new t.fn.init(r,i)}var n;return f.extend(t,this),t},i.ie&&i.ie<8&&(C(M,"get",{maxlength:function(e){var t=e.maxLength;return 2147483647===t?k:t},size:function(e){var t=e.size;return 20===t?k:t},"class":function(e){return e.className},style:function(e){var t=e.style.cssText;return 0===t.length?k:t}}),C(M,"set",{"class":function(e,t){e.className=t},style:function(e,t){e.style.cssText=t}})),i.ie&&i.ie<9&&(D["float"]="styleFloat",C(L,"set",{opacity:function(e,t){var n=e.style;null===t||""===t?n.removeAttribute("filter"):(n.zoom=1,n.filter="alpha(opacity="+100*t+")")}})),f.attrHooks=M,f.cssHooks=L,f}),r(p,[],function(){return function(e,t){function n(e,t,n,r){function i(e){return e=parseInt(e,10).toString(16),e.length>1?e:"0"+e}return"#"+i(t)+i(n)+i(r)}var r=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,o=/\s*([^:]+):\s*([^;]+);?/g,a=/\s+$/,s,l,c={},u,d,f,h="\ufeff";for(e=e||{},t&&(d=t.getValidStyles(),f=t.getInvalidStyles()),u=("\\\" \\' \\; \\: ; : "+h).split(" "),l=0;l-1&&n||(m[e+t]=-1==l?s[0]:s.join(" "),delete m[e+"-top"+t],delete m[e+"-right"+t],delete m[e+"-bottom"+t],delete m[e+"-left"+t])}}function u(e){var t=m[e],n;if(t){for(t=t.split(" "),n=t.length;n--;)if(t[n]!==t[0])return!1;return m[e]=t[0],!0}}function d(e,t,n,r){u(t)&&u(n)&&u(r)&&(m[e]=m[t]+" "+m[n]+" "+m[r],delete m[t],delete m[n],delete m[r])}function f(e){return b=!0,c[e]}function h(e,t){return b&&(e=e.replace(/\uFEFF[0-9]/g,function(e){return c[e]})),t||(e=e.replace(/\\([\'\";:])/g,"$1")),e}function p(t,n,r,i,o,a){if(o=o||a)return o=h(o),"'"+o.replace(/\'/g,"\\'")+"'";if(n=h(n||r||i),!e.allow_script_urls){var s=n.replace(/[\s\r\n]+/,"");if(/(java|vb)script:/i.test(s))return"";if(!e.allow_svg_data_urls&&/^data:image\/svg/i.test(s))return""}return x&&(n=x.call(C,n,"style")),"url('"+n.replace(/\'/g,"\\'")+"')"}var m={},g,v,y,b,x=e.url_converter,C=e.url_converter_scope||this;if(t){for(t=t.replace(/[\u0000-\u001F]/g,""),t=t.replace(/\\[\"\';:\uFEFF]/g,f).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(e){return e.replace(/[;:]/g,f)});g=o.exec(t);){if(v=g[1].replace(a,"").toLowerCase(),y=g[2].replace(a,""),y=y.replace(/\\[0-9a-f]+/g,function(e){return String.fromCharCode(parseInt(e.substr(1),16))}),v&&y.length>0){if(!e.allow_script_urls&&("behavior"==v||/expression\s*\(|\/\*|\*\//.test(y)))continue;"font-weight"===v&&"700"===y?y="bold":("color"===v||"background-color"===v)&&(y=y.toLowerCase()),y=y.replace(r,n),y=y.replace(i,p),m[v]=b?h(y,!0):y}o.lastIndex=g.index+g[0].length}s("border","",!0),s("border","-width"),s("border","-color"),s("border","-style"),s("padding",""),s("margin",""),d("border","border-width","border-style","border-color"),"medium none"===m.border&&delete m.border,"none"===m["border-image"]&&delete m["border-image"]}return m},serialize:function(e,t){function n(t){var n,r,o,a;if(n=d[t])for(r=0,o=n.length;o>r;r++)t=n[r],a=e[t],a!==s&&a.length>0&&(i+=(i.length>0?" ":"")+t+": "+a+";")}function r(e,t){var n;return n=f["*"],n&&n[e]?!1:(n=f[t],n&&n[e]?!1:!0)}var i="",o,a;if(t&&d)n("*"),n(t);else for(o in e)a=e[o],a!==s&&a.length>0&&(!f||r(o,t))&&(i+=(i.length>0?" ":"")+o+": "+a+";");return i}}}}),r(m,[],function(){return function(e,t){function n(e,n,r,i){var o,a;if(e){if(!i&&e[n])return e[n];if(e!=t){if(o=e[r])return o;for(a=e.parentNode;a&&a!=t;a=a.parentNode)if(o=a[r])return o}}}var r=e;this.current=function(){return r},this.next=function(e){return r=n(r,"firstChild","nextSibling",e)},this.prev=function(e){return r=n(r,"lastChild","previousSibling",e)}}}),r(g,[f],function(e){function t(n){function r(){return H.createDocumentFragment()}function i(e,t){_(F,e,t)}function o(e,t){_(z,e,t)}function a(e){i(e.parentNode,j(e))}function s(e){i(e.parentNode,j(e)+1)}function l(e){o(e.parentNode,j(e))}function c(e){o(e.parentNode,j(e)+1)}function u(e){e?(L[U]=L[V],L[$]=L[W]):(L[V]=L[U],L[W]=L[$]),L.collapsed=F}function d(e){a(e),c(e)}function f(e){i(e,0),o(e,1===e.nodeType?e.childNodes.length:e.nodeValue.length)}function h(e,t){var n=L[V],r=L[W],i=L[U],o=L[$],a=t.startContainer,s=t.startOffset,l=t.endContainer,c=t.endOffset;return 0===e?w(n,r,a,s):1===e?w(i,o,a,s):2===e?w(i,o,l,c):3===e?w(n,r,l,c):void 0}function p(){E(I)}function m(){return E(P)}function g(){return E(O)}function v(e){var t=this[V],r=this[W],i,o;3!==t.nodeType&&4!==t.nodeType||!t.nodeValue?(t.childNodes.length>0&&(o=t.childNodes[r]),o?t.insertBefore(e,o):3==t.nodeType?n.insertAfter(e,t):t.appendChild(e)):r?r>=t.nodeValue.length?n.insertAfter(e,t):(i=t.splitText(r),t.parentNode.insertBefore(e,i)):t.parentNode.insertBefore(e,t)}function y(e){var t=L.extractContents();L.insertNode(e),e.appendChild(t),L.selectNode(e)}function b(){return q(new t(n),{startContainer:L[V],startOffset:L[W],endContainer:L[U],endOffset:L[$],collapsed:L.collapsed,commonAncestorContainer:L.commonAncestorContainer})}function x(e,t){var n;if(3==e.nodeType)return e;if(0>t)return e;for(n=e.firstChild;n&&t>0;)--t,n=n.nextSibling;return n?n:e}function C(){return L[V]==L[U]&&L[W]==L[$]}function w(e,t,r,i){var o,a,s,l,c,u;if(e==r)return t==i?0:i>t?-1:1;for(o=r;o&&o.parentNode!=e;)o=o.parentNode;if(o){for(a=0,s=e.firstChild;s!=o&&t>a;)a++,s=s.nextSibling;return a>=t?-1:1}for(o=e;o&&o.parentNode!=r;)o=o.parentNode;if(o){for(a=0,s=r.firstChild;s!=o&&i>a;)a++,s=s.nextSibling;return i>a?-1:1}for(l=n.findCommonAncestor(e,r),c=e;c&&c.parentNode!=l;)c=c.parentNode;for(c||(c=l),u=r;u&&u.parentNode!=l;)u=u.parentNode;if(u||(u=l),c==u)return 0;for(s=l.firstChild;s;){if(s==c)return-1;if(s==u)return 1;s=s.nextSibling}}function _(e,t,r){var i,o;for(e?(L[V]=t,L[W]=r):(L[U]=t,L[$]=r),i=L[U];i.parentNode;)i=i.parentNode;for(o=L[V];o.parentNode;)o=o.parentNode;o==i?w(L[V],L[W],L[U],L[$])>0&&L.collapse(e):L.collapse(e),L.collapsed=C(),L.commonAncestorContainer=n.findCommonAncestor(L[V],L[U])}function E(e){var t,n=0,r=0,i,o,a,s,l,c;if(L[V]==L[U])return N(e);for(t=L[U],i=t.parentNode;i;t=i,i=i.parentNode){if(i==L[V])return S(t,e);++n}for(t=L[V],i=t.parentNode;i;t=i,i=i.parentNode){if(i==L[U])return k(t,e);++r}for(o=r-n,a=L[V];o>0;)a=a.parentNode,o--;for(s=L[U];0>o;)s=s.parentNode,o++;for(l=a.parentNode,c=s.parentNode;l!=c;l=l.parentNode,c=c.parentNode)a=l,s=c;return T(a,s,e)}function N(e){var t,n,i,o,a,s,l,c,u;if(e!=I&&(t=r()),L[W]==L[$])return t;if(3==L[V].nodeType){if(n=L[V].nodeValue,i=n.substring(L[W],L[$]),e!=O&&(o=L[V],c=L[W],u=L[$]-L[W],0===c&&u>=o.nodeValue.length-1?o.parentNode.removeChild(o):o.deleteData(c,u),L.collapse(F)),e==I)return;return i.length>0&&t.appendChild(H.createTextNode(i)),t}for(o=x(L[V],L[W]),a=L[$]-L[W];o&&a>0;)s=o.nextSibling,l=D(o,e),t&&t.appendChild(l),--a,o=s;return e!=O&&L.collapse(F),t}function S(e,t){var n,i,o,a,s,l;if(t!=I&&(n=r()),i=R(e,t),n&&n.appendChild(i),o=j(e),a=o-L[W],0>=a)return t!=O&&(L.setEndBefore(e),L.collapse(z)),n;for(i=e.previousSibling;a>0;)s=i.previousSibling,l=D(i,t),n&&n.insertBefore(l,n.firstChild),--a,i=s;return t!=O&&(L.setEndBefore(e),L.collapse(z)),n}function k(e,t){var n,i,o,a,s,l;for(t!=I&&(n=r()),o=A(e,t),n&&n.appendChild(o),i=j(e),++i,a=L[$]-i,o=e.nextSibling;o&&a>0;)s=o.nextSibling,l=D(o,t),n&&n.appendChild(l),--a,o=s;return t!=O&&(L.setStartAfter(e),L.collapse(F)),n}function T(e,t,n){var i,o,a,s,l,c,u;for(n!=I&&(o=r()),i=A(e,n),o&&o.appendChild(i),a=j(e),s=j(t),++a,l=s-a,c=e.nextSibling;l>0;)u=c.nextSibling,i=D(c,n),o&&o.appendChild(i),c=u,--l;return i=R(t,n),o&&o.appendChild(i),n!=O&&(L.setStartAfter(e),L.collapse(F)),o}function R(e,t){var n=x(L[U],L[$]-1),r,i,o,a,s,l=n!=L[U];if(n==e)return B(n,l,z,t);for(r=n.parentNode,i=B(r,z,z,t);r;){for(;n;)o=n.previousSibling,a=B(n,l,z,t),t!=I&&i.insertBefore(a,i.firstChild),l=F,n=o;if(r==e)return i;n=r.previousSibling,r=r.parentNode,s=B(r,z,z,t),t!=I&&s.appendChild(i),i=s}}function A(e,t){var n=x(L[V],L[W]),r=n!=L[V],i,o,a,s,l;if(n==e)return B(n,r,F,t);for(i=n.parentNode,o=B(i,z,F,t);i;){for(;n;)a=n.nextSibling,s=B(n,r,F,t),t!=I&&o.appendChild(s),r=F,n=a;if(i==e)return o;n=i.nextSibling,i=i.parentNode,l=B(i,z,F,t),t!=I&&l.appendChild(o),o=l}}function B(e,t,r,i){var o,a,s,l,c;if(t)return D(e,i);if(3==e.nodeType){if(o=e.nodeValue,r?(l=L[W],a=o.substring(l),s=o.substring(0,l)):(l=L[$],a=o.substring(0,l),s=o.substring(l)),i!=O&&(e.nodeValue=s),i==I)return;return c=n.clone(e,z),c.nodeValue=a,c}if(i!=I)return n.clone(e,z)}function D(e,t){return t!=I?t==O?n.clone(e,F):e:void e.parentNode.removeChild(e)}function M(){return n.create("body",null,g()).outerText}var L=this,H=n.doc,P=0,O=1,I=2,F=!0,z=!1,W="startOffset",V="startContainer",U="endContainer",$="endOffset",q=e.extend,j=n.nodeIndex;return q(L,{startContainer:H,startOffset:0,endContainer:H,endOffset:0,collapsed:F,commonAncestorContainer:H,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:i,setEnd:o,setStartBefore:a,setStartAfter:s,setEndBefore:l,setEndAfter:c,collapse:u,selectNode:d,selectNodeContents:f,compareBoundaryPoints:h,deleteContents:p,extractContents:m,cloneContents:g,insertNode:v,surroundContents:y,cloneRange:b,toStringIE:M}),L}return t.prototype.toString=function(){return this.toStringIE()},t}),r(v,[f],function(e){function t(e){var t;return t=document.createElement("div"),t.innerHTML=e,t.textContent||t.innerText||e}function n(e,t){var n,r,i,a={};if(e){for(e=e.split(","),t=t||10,n=0;n\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,l=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,c=/[<>&\"\']/g,u=/&#([a-z0-9]+);?|&([a-z0-9]+);/gi,d={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};o={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},a={"<":"<",">":">","&":"&",""":'"',"'":"'"},i=n("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var f={encodeRaw:function(e,t){return e.replace(t?s:l,function(e){return o[e]||e})},encodeAllRaw:function(e){return(""+e).replace(c,function(e){return o[e]||e})},encodeNumeric:function(e,t){return e.replace(t?s:l,function(e){return e.length>1?"&#"+(1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320)+65536)+";":o[e]||"&#"+e.charCodeAt(0)+";"})},encodeNamed:function(e,t,n){return n=n||i,e.replace(t?s:l,function(e){return o[e]||n[e]||e})},getEncodeFunc:function(e,t){function a(e,n){return e.replace(n?s:l,function(e){return o[e]||t[e]||"&#"+e.charCodeAt(0)+";"||e})}function c(e,n){return f.encodeNamed(e,n,t)}return t=n(t)||i,e=r(e.replace(/\+/g,",")),e.named&&e.numeric?a:e.named?t?c:f.encodeNamed:e.numeric?f.encodeNumeric:f.encodeRaw},decode:function(e){return e.replace(u,function(e,n){return n?(n="x"===n.charAt(0).toLowerCase()?parseInt(n.substr(1),16):parseInt(n,10),n>65535?(n-=65536,String.fromCharCode(55296+(n>>10),56320+(1023&n))):d[n]||String.fromCharCode(n)):a[e]||i[e]||t(e)})}};return f}),r(y,[f],function(e){return function(t,n){function r(e){t.getElementsByTagName("head")[0].appendChild(e)}function i(n,i,l){function c(){for(var e=y.passed,t=e.length;t--;)e[t]();y.status=2,y.passed=[],y.failed=[]}function u(){for(var e=y.failed,t=e.length;t--;)e[t]();y.status=3,y.passed=[],y.failed=[]}function d(){var e=navigator.userAgent.match(/WebKit\/(\d*)/);return!!(e&&e[1]<536)}function f(e,t){e()||((new Date).getTime()-v0)return g=t.createElement("style"),g.textContent='@import "'+n+'"',p(),void r(g);h()}r(m),m.href=n}}var o=0,a={},s;n=n||{},s=n.maxLoadTime||5e3,this.load=i}}),r(b,[c,h,p,l,m,g,v,u,f,y],function(e,n,r,i,o,a,s,l,c,u){function d(e,t){var n={},r=t.keep_values,i;return i={set:function(n,r,i){t.url_converter&&(r=t.url_converter.call(t.url_converter_scope||e,r,i,n[0])),n.attr("data-mce-"+i,r).attr(i,r)},get:function(e,t){return e.attr("data-mce-"+t)||e.attr(t)}},n={style:{set:function(e,t){return null!==t&&"object"==typeof t?void e.css(t):(r&&e.attr("data-mce-style",t),void e.attr("style",t))},get:function(t){var n=t.attr("data-mce-style")||t.attr("style");return n=e.serializeStyle(e.parseStyle(n),t[0].nodeName)}}},r&&(n.href=n.src=i),n}function f(e,t){var n=t.attr("style");n=e.serializeStyle(e.parseStyle(n),t[0].nodeName),n||(n=null),t.attr("data-mce-style",n)}function h(e,t){var o=this,a;o.doc=e,o.win=window,o.files={},o.counter=0,o.stdMode=!y||e.documentMode>=8,o.boxModel=!y||"CSS1Compat"==e.compatMode||o.stdMode,o.styleSheetLoader=new u(e),o.boundEvents=[],o.settings=t=t||{},o.schema=t.schema,o.styles=new r({url_converter:t.url_converter,url_converter_scope:t.url_converter_scope},t.schema),o.fixDoc(e),o.events=t.ownEvents?new i(t.proxy):i.Event,o.attrHooks=d(o,t),a=t.schema?t.schema.getBlockElements():{},o.$=n.overrideDefaults(function(){return{context:e,element:o.getRoot()}}),o.isBlock=function(e){if(!e)return!1;var t=e.nodeType;return t?!(1!==t||!a[e.nodeName]):!!a[e]}}var p=c.each,m=c.is,g=c.grep,v=c.trim,y=l.ie,b=/^([a-z0-9],?)+$/i,x=/^[ \t\r\n]*$/;return h.prototype={$$:function(e){return"string"==typeof e&&(e=this.get(e)),this.$(e)},root:null,fixDoc:function(e){var t=this.settings,n;if(y&&t.schema){"abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video".replace(/\w+/g,function(t){e.createElement(t)});for(n in t.schema.getCustomElements())e.createElement(n)}},clone:function(e,t){var n=this,r,i;return!y||1!==e.nodeType||t?e.cloneNode(t):(i=n.doc,t?r.firstChild:(r=i.createElement(e.nodeName),p(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),r))},getRoot:function(){var e=this;return e.settings.root_element||e.doc.body},getViewPort:function(e){var t,n;return e=e?e:this.win,t=e.document,n=this.boxModel?t.documentElement:t.body,{x:e.pageXOffset||n.scrollLeft,y:e.pageYOffset||n.scrollTop,w:e.innerWidth||n.clientWidth,h:e.innerHeight||n.clientHeight}},getRect:function(e){var t=this,n,r;return e=t.get(e),n=t.getPos(e),r=t.getSize(e),{x:n.x,y:n.y,w:r.w,h:r.h}},getSize:function(e){var t=this,n,r;return e=t.get(e),n=t.getStyle(e,"width"),r=t.getStyle(e,"height"),-1===n.indexOf("px")&&(n=0),-1===r.indexOf("px")&&(r=0),{w:parseInt(n,10)||e.offsetWidth||e.clientWidth,h:parseInt(r,10)||e.offsetHeight||e.clientHeight}},getParent:function(e,t,n){return this.getParents(e,t,n,!1)},getParents:function(e,n,r,i){var o=this,a,s=[];for(e=o.get(e),i=i===t,r=r||("BODY"!=o.getRoot().nodeName?o.getRoot().parentNode:null),m(n,"string")&&(a=n,n="*"===n?function(e){return 1==e.nodeType}:function(e){return o.is(e,a)});e&&e!=r&&e.nodeType&&9!==e.nodeType;){if(!n||n(e)){if(!i)return e;s.push(e)}e=e.parentNode}return i?s:null},get:function(e){var t;return e&&this.doc&&"string"==typeof e&&(t=e,e=this.doc.getElementById(e),e&&e.id!==t)?this.doc.getElementsByName(t)[1]:e},getNext:function(e,t){return this._findSib(e,t,"nextSibling")},getPrev:function(e,t){return this._findSib(e,t,"previousSibling")},select:function(t,n){var r=this;return e(t,r.get(n)||r.settings.root_element||r.doc,[])},is:function(n,r){var i;if(n.length===t){if("*"===r)return 1==n.nodeType;if(b.test(r)){for(r=r.toLowerCase().split(/,/),n=n.nodeName.toLowerCase(),i=r.length-1;i>=0;i--)if(r[i]==n)return!0;return!1}}if(n.nodeType&&1!=n.nodeType)return!1;var o=n.nodeType?[n]:n;return e(r,o[0].ownerDocument||o[0],null,o).length>0},add:function(e,t,n,r,i){var o=this;return this.run(e,function(e){var a;return a=m(t,"string")?o.doc.createElement(t):t,o.setAttribs(a,n),r&&(r.nodeType?a.appendChild(r):o.setHTML(a,r)),i?a:e.appendChild(a)})},create:function(e,t,n){return this.add(this.doc.createElement(e),e,t,n,1)},createHTML:function(e,t,n){var r="",i;r+="<"+e;for(i in t)t.hasOwnProperty(i)&&null!==t[i]&&"undefined"!=typeof t[i]&&(r+=" "+i+'="'+this.encode(t[i])+'"');return"undefined"!=typeof n?r+">"+n+"":r+" />"},createFragment:function(e){var t,n,r=this.doc,i;for(i=r.createElement("div"),t=r.createDocumentFragment(),e&&(i.innerHTML=e);n=i.firstChild;)t.appendChild(n);return t},remove:function(e,t){return e=this.$$(e),t?e.each(function(){for(var e;e=this.firstChild;)3==e.nodeType&&0===e.data.length?this.removeChild(e):this.parentNode.insertBefore(e,this)}).remove():e.remove(),e.length>1?e.toArray():e[0]},setStyle:function(e,t,n){e=this.$$(e).css(t,n),this.settings.update_styles&&f(this,e)},getStyle:function(e,n,r){return e=this.$$(e),r?e.css(n):(n=n.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"float"==n&&(n=l.ie&&l.ie<12?"styleFloat":"cssFloat"),e[0]&&e[0].style?e[0].style[n]:t)},setStyles:function(e,t){e=this.$$(e).css(t),this.settings.update_styles&&f(this,e)},removeAllAttribs:function(e){return this.run(e,function(e){var t,n=e.attributes;for(t=n.length-1;t>=0;t--)e.removeAttributeNode(n.item(t))})},setAttrib:function(e,t,n){var r=this,i,o,a=r.settings;""===n&&(n=null),e=r.$$(e),i=e.attr(t),e.length&&(o=r.attrHooks[t],o&&o.set?o.set(e,n,t):e.attr(t,n),i!=n&&a.onSetAttrib&&a.onSetAttrib({attrElm:e,attrName:t,attrValue:n}))},setAttribs:function(e,t){var n=this;n.$$(e).each(function(e,r){p(t,function(e,t){n.setAttrib(r,t,e)})})},getAttrib:function(e,t,n){var r=this,i,o;return e=r.$$(e),e.length&&(i=r.attrHooks[t],o=i&&i.get?i.get(e,t):e.attr(t)),"undefined"==typeof o&&(o=n||""),o},getPos:function(e,t){var r=this,i=0,o=0,a,s=r.doc,l=s.body,c;if(e=r.get(e),t=t||l,e){if(t===l&&e.getBoundingClientRect&&"static"===n(l).css("position"))return c=e.getBoundingClientRect(),t=r.boxModel?s.documentElement:l,i=c.left+(s.documentElement.scrollLeft||l.scrollLeft)-t.clientLeft,o=c.top+(s.documentElement.scrollTop||l.scrollTop)-t.clientTop,{x:i,y:o};for(a=e;a&&a!=t&&a.nodeType;)i+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=e.parentNode;a&&a!=t&&a.nodeType;)i-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode}return{x:i,y:o}},parseStyle:function(e){return this.styles.parse(e)},serializeStyle:function(e,t){return this.styles.serialize(e,t)},addStyle:function(e){var t=this,n=t.doc,r,i;if(t!==h.DOM&&n===document){var o=h.DOM.addedStyles;if(o=o||[],o[e])return;o[e]=!0,h.DOM.addedStyles=o}i=n.getElementById("mceDefaultStyles"),i||(i=n.createElement("style"),i.id="mceDefaultStyles",i.type="text/css",r=n.getElementsByTagName("head")[0],r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i)),i.styleSheet?i.styleSheet.cssText+=e:i.appendChild(n.createTextNode(e))},loadCSS:function(e){var t=this,n=t.doc,r;return t!==h.DOM&&n===document?void h.DOM.loadCSS(e):(e||(e=""),r=n.getElementsByTagName("head")[0],void p(e.split(","),function(e){var i;e=c._addCacheSuffix(e),t.files[e]||(t.files[e]=!0,i=t.create("link",{rel:"stylesheet",href:e}),y&&n.documentMode&&n.recalc&&(i.onload=function(){n.recalc&&n.recalc(),i.onload=null}),r.appendChild(i))}))},addClass:function(e,t){this.$$(e).addClass(t)},removeClass:function(e,t){this.toggleClass(e,t,!1)},hasClass:function(e,t){return this.$$(e).hasClass(t)},toggleClass:function(e,t,r){this.$$(e).toggleClass(t,r).each(function(){""===this.className&&n(this).attr("class",null)})},show:function(e){this.$$(e).show()},hide:function(e){this.$$(e).hide()},isHidden:function(e){return"none"==this.$$(e).css("display")},uniqueId:function(e){return(e?e:"mce_")+this.counter++},setHTML:function(e,t){e=this.$$(e),y?e.each(function(e,r){if(r.canHaveHTML!==!1){for(;r.firstChild;)r.removeChild(r.firstChild);try{r.innerHTML="
"+t,r.removeChild(r.firstChild)}catch(i){n("
").html("
"+t).contents().slice(1).appendTo(r)}return t}}):e.html(t)},getOuterHTML:function(e){return e=this.get(e),1==e.nodeType&&"outerHTML"in e?e.outerHTML:n("
").append(n(e).clone()).html()},setOuterHTML:function(e,t){var r=this;r.$$(e).each(function(){try{if("outerHTML"in this)return void(this.outerHTML=t)}catch(e){}r.remove(n(this).html(t),!0)})},decode:s.decode,encode:s.encodeAllRaw,insertAfter:function(e,t){return t=this.get(t),this.run(e,function(e){var n,r;return n=t.parentNode,r=t.nextSibling,r?n.insertBefore(e,r):n.appendChild(e),e})},replace:function(e,t,n){var r=this;return r.run(t,function(t){return m(t,"array")&&(e=e.cloneNode(!0)),n&&p(g(t.childNodes),function(t){e.appendChild(t)}),t.parentNode.replaceChild(e,t)})},rename:function(e,t){var n=this,r;return e.nodeName!=t.toUpperCase()&&(r=n.create(t),p(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),n.replace(r,e,1)),r||e},findCommonAncestor:function(e,t){for(var n=e,r;n;){for(r=t;r&&n!=r;)r=r.parentNode;if(n==r)break;n=n.parentNode}return!n&&e.ownerDocument?e.ownerDocument.documentElement:n},toHex:function(e){return this.styles.toHex(c.trim(e))},run:function(e,t,n){var r=this,i;return"string"==typeof e&&(e=r.get(e)),e?(n=n||this,e.nodeType||!e.length&&0!==e.length?t.call(n,e):(i=[],p(e,function(e,o){e&&("string"==typeof e&&(e=r.get(e)),i.push(t.call(n,e,o)))}),i)):!1},getAttribs:function(e){var t;if(e=this.get(e),!e)return[];if(y){if(t=[],"OBJECT"==e.nodeName)return e.attributes;"OPTION"===e.nodeName&&this.getAttrib(e,"selected")&&t.push({specified:1,nodeName:"selected"});var n=/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;return e.cloneNode(!1).outerHTML.replace(n,"").replace(/[\w:\-]+/gi,function(e){t.push({specified:1,nodeName:e})}),t}return e.attributes},isEmpty:function(e,t){ -var n=this,r,i,a,s,l,c=0;if(e=e.firstChild){s=new o(e,e.parentNode),t=t||(n.schema?n.schema.getNonEmptyElements():null);do{if(a=e.nodeType,1===a){if(e.getAttribute("data-mce-bogus"))continue;if(l=e.nodeName.toLowerCase(),t&&t[l]){if("br"===l){c++;continue}return!1}for(i=n.getAttribs(e),r=i.length;r--;)if(l=i[r].nodeName,"name"===l||"data-mce-bookmark"===l)return!1}if(8==a)return!1;if(3===a&&!x.test(e.nodeValue))return!1}while(e=s.next())}return 1>=c},createRng:function(){var e=this.doc;return e.createRange?e.createRange():new a(this)},nodeIndex:function(e,t){var n=0,r,i;if(e)for(r=e.nodeType,e=e.previousSibling;e;e=e.previousSibling)i=e.nodeType,(!t||3!=i||i!=r&&e.nodeValue.length)&&(n++,r=i);return n},split:function(e,t,n){function r(e){function t(e){var t=e.previousSibling&&"SPAN"==e.previousSibling.nodeName,n=e.nextSibling&&"SPAN"==e.nextSibling.nodeName;return t&&n}var n,o=e.childNodes,a=e.nodeType;if(1!=a||"bookmark"!=e.getAttribute("data-mce-type")){for(n=o.length-1;n>=0;n--)r(o[n]);if(9!=a){if(3==a&&e.nodeValue.length>0){var s=v(e.nodeValue).length;if(!i.isBlock(e.parentNode)||s>0||0===s&&t(e))return}else if(1==a&&(o=e.childNodes,1==o.length&&o[0]&&1==o[0].nodeType&&"bookmark"==o[0].getAttribute("data-mce-type")&&e.parentNode.insertBefore(o[0],e),o.length||/^(br|hr|input|img)$/i.test(e.nodeName)))return;i.remove(e)}return e}}var i=this,o=i.createRng(),a,s,l;return e&&t?(o.setStart(e.parentNode,i.nodeIndex(e)),o.setEnd(t.parentNode,i.nodeIndex(t)),a=o.extractContents(),o=i.createRng(),o.setStart(t.parentNode,i.nodeIndex(t)+1),o.setEnd(e.parentNode,i.nodeIndex(e)+1),s=o.extractContents(),l=e.parentNode,l.insertBefore(r(a),e),n?l.replaceChild(n,t):l.insertBefore(t,e),l.insertBefore(r(s),e),i.remove(e),n||t):void 0},bind:function(e,t,n,r){var i=this;if(c.isArray(e)){for(var o=e.length;o--;)e[o]=i.bind(e[o],t,n,r);return e}return!i.settings.collect||e!==i.doc&&e!==i.win||i.boundEvents.push([e,t,n,r]),i.events.bind(e,t,n,r||i)},unbind:function(e,t,n){var r=this,i;if(c.isArray(e)){for(i=e.length;i--;)e[i]=r.unbind(e[i],t,n);return e}if(r.boundEvents&&(e===r.doc||e===r.win))for(i=r.boundEvents.length;i--;){var o=r.boundEvents[i];e!=o[0]||t&&t!=o[1]||n&&n!=o[2]||this.events.unbind(o[0],o[1],o[2])}return this.events.unbind(e,t,n)},fire:function(e,t,n){return this.events.fire(e,t,n)},getContentEditable:function(e){var t;return e&&1==e.nodeType?(t=e.getAttribute("data-mce-contenteditable"),t&&"inherit"!==t?t:"inherit"!==e.contentEditable?e.contentEditable:null):null},getContentEditableParent:function(e){for(var t=this.getRoot(),n=null;e&&e!==t&&(n=this.getContentEditable(e),null===n);e=e.parentNode);return n},destroy:function(){var t=this;if(t.boundEvents){for(var n=t.boundEvents.length;n--;){var r=t.boundEvents[n];this.events.unbind(r[0],r[1],r[2])}t.boundEvents=null}e.setDocument&&e.setDocument(),t.win=t.doc=t.root=t.events=t.frag=null},isChildOf:function(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1},dumpRng:function(e){return"startContainer: "+e.startContainer.nodeName+", startOffset: "+e.startOffset+", endContainer: "+e.endContainer.nodeName+", endOffset: "+e.endOffset},_findSib:function(e,t,n){var r=this,i=t;if(e)for("string"==typeof i&&(i=function(e){return r.is(e,t)}),e=e[n];e;e=e[n])if(i(e))return e;return null}},h.DOM=new h(document),h}),r(x,[b,f],function(e,t){function n(){function e(e,n){function i(){a.remove(l),s&&(s.onreadystatechange=s.onload=s=null),n()}function o(){"undefined"!=typeof console&&console.log&&console.log("Failed to load: "+e)}var a=r,s,l;l=a.uniqueId(),s=document.createElement("script"),s.id=l,s.type="text/javascript",s.src=t._addCacheSuffix(e),"onreadystatechange"in s?s.onreadystatechange=function(){/loaded|complete/.test(s.readyState)&&i()}:s.onload=i,s.onerror=o,(document.getElementsByTagName("head")[0]||document.body).appendChild(s)}var n=0,a=1,s=2,l={},c=[],u={},d=[],f=0,h;this.isDone=function(e){return l[e]==s},this.markDone=function(e){l[e]=s},this.add=this.load=function(e,t,r){var i=l[e];i==h&&(c.push(e),l[e]=n),t&&(u[e]||(u[e]=[]),u[e].push({func:t,scope:r||this}))},this.loadQueue=function(e,t){this.loadScripts(c,e,t)},this.loadScripts=function(t,n,r){function c(e){i(u[e],function(e){e.func.call(e.scope)}),u[e]=h}var p;d.push({func:n,scope:r||this}),(p=function(){var n=o(t);t.length=0,i(n,function(t){return l[t]==s?void c(t):void(l[t]!=a&&(l[t]=a,f++,e(t,function(){l[t]=s,f--,c(t),p()})))}),f||(i(d,function(e){e.func.call(e.scope)}),d.length=0)})()}}var r=e.DOM,i=t.each,o=t.grep;return n.ScriptLoader=new n,n}),r(C,[x,f],function(e,n){function r(){var e=this;e.items=[],e.urls={},e.lookup={}}var i=n.each;return r.prototype={get:function(e){return this.lookup[e]?this.lookup[e].instance:t},dependencies:function(e){var t;return this.lookup[e]&&(t=this.lookup[e].dependencies),t||[]},requireLangPack:function(t,n){var i=r.language;if(i&&r.languageLoad!==!1){if(n)if(n=","+n+",",-1!=n.indexOf(","+i.substr(0,2)+","))i=i.substr(0,2);else if(-1==n.indexOf(","+i+","))return;e.ScriptLoader.add(this.urls[t]+"/langs/"+i+".js")}},add:function(e,t,n){return this.items.push(t),this.lookup[e]={instance:t,dependencies:n},t},createUrl:function(e,t){return"object"==typeof t?t:{prefix:e.prefix,resource:t,suffix:e.suffix}},addComponents:function(t,n){var r=this.urls[t];i(n,function(t){e.ScriptLoader.add(r+"/"+t)})},load:function(n,o,a,s){function l(){var r=c.dependencies(n);i(r,function(e){var n=c.createUrl(o,e);c.load(n.resource,n,t,t)}),a&&(s?a.call(s):a.call(e))}var c=this,u=o;c.urls[n]||("object"==typeof o&&(u=o.prefix+o.resource+o.suffix),0!==u.indexOf("/")&&-1==u.indexOf("://")&&(u=r.baseURL+"/"+u),c.urls[n]=u.substring(0,u.lastIndexOf("/")),c.lookup[n]?l():e.ScriptLoader.add(u,l,s))}},r.PluginManager=new r,r.ThemeManager=new r,r}),r(w,[f,m],function(e,t){function n(e,t){var n=e.childNodes;return t--,t>n.length-1?t=n.length-1:0>t&&(t=0),n[t]||e}function r(e){this.walk=function(t,r){function o(e){var t;return t=e[0],3===t.nodeType&&t===c&&u>=t.nodeValue.length&&e.splice(0,1),t=e[e.length-1],0===f&&e.length>0&&t===d&&3===t.nodeType&&e.splice(e.length-1,1),e}function a(e,t,n){for(var r=[];e&&e!=n;e=e[t])r.push(e);return r}function s(e,t){do{if(e.parentNode==t)return e;e=e.parentNode}while(e)}function l(e,t,n){var i=n?"nextSibling":"previousSibling";for(g=e,v=g.parentNode;g&&g!=t;g=v)v=g.parentNode,y=a(g==e?g:g[i],i),y.length&&(n||y.reverse(),r(o(y)))}var c=t.startContainer,u=t.startOffset,d=t.endContainer,f=t.endOffset,h,p,m,g,v,y,b;if(b=e.select("td.mce-item-selected,th.mce-item-selected"),b.length>0)return void i(b,function(e){r([e])});if(1==c.nodeType&&c.hasChildNodes()&&(c=c.childNodes[u]),1==d.nodeType&&d.hasChildNodes()&&(d=n(d,f)),c==d)return r(o([c]));for(h=e.findCommonAncestor(c,d),g=c;g;g=g.parentNode){if(g===d)return l(c,h,!0);if(g===h)break}for(g=d;g;g=g.parentNode){if(g===c)return l(d,h);if(g===h)break}p=s(c,h)||c,m=s(d,h)||d,l(c,p,!0),y=a(p==c?p:p.nextSibling,"nextSibling",m==d?m.nextSibling:m),y.length&&r(o(y)),l(d,m)},this.split=function(e){function t(e,t){return e.splitText(t)}var n=e.startContainer,r=e.startOffset,i=e.endContainer,o=e.endOffset;return n==i&&3==n.nodeType?r>0&&rr?(o-=r,n=i=t(i,o).previousSibling,o=i.nodeValue.length,r=0):o=0):(3==n.nodeType&&r>0&&r0&&o0)return c=h,u=n?h.nodeValue.length:0,void(i=!0);if(e.isBlock(h)||p[h.nodeName.toLowerCase()])return;s=h}o&&s&&(c=s,i=!0,u=0)}var c,u,d,f=e.getRoot(),h,p,m,g;if(c=n[(r?"start":"end")+"Container"],u=n[(r?"start":"end")+"Offset"],g=1==c.nodeType&&u===c.childNodes.length,p=e.schema.getNonEmptyElements(),m=r,1==c.nodeType&&u>c.childNodes.length-1&&(m=!1),9===c.nodeType&&(c=e.getRoot(),u=0),c===f){if(m&&(h=c.childNodes[u>0?u-1:0],h&&(p[h.nodeName]||"TABLE"==h.nodeName)))return;if(c.hasChildNodes()&&(u=Math.min(!m&&u>0?u-1:u,c.childNodes.length-1),c=c.childNodes[u],u=0,c.hasChildNodes()&&!/TABLE/.test(c.nodeName))){h=c,d=new t(c,f);do{if(3===h.nodeType&&h.nodeValue.length>0){u=m?0:h.nodeValue.length,c=h,i=!0;break}if(p[h.nodeName.toLowerCase()]){u=e.nodeIndex(h),c=h.parentNode,"IMG"!=h.nodeName||m||u++,i=!0;break}}while(h=m?d.next():d.prev())}}o&&(3===c.nodeType&&0===u&&l(!0),1===c.nodeType&&(h=c.childNodes[u],h||(h=c.childNodes[u-1]),!h||"BR"!==h.nodeName||s(h,"A")||a(h)||a(h,!0)||l(!0,h))),m&&!o&&3===c.nodeType&&u===c.nodeValue.length&&l(!1),i&&n["set"+(r?"Start":"End")](c,u)}var i,o;return o=n.collapsed,r(!0),o||r(),i&&o&&n.collapse(!0),i}}var i=e.each;return r.compareRanges=function(e,t){if(e&&t){if(!e.item&&!e.duplicate)return e.startContainer==t.startContainer&&e.startOffset==t.startOffset;if(e.item&&t.item&&e.item(0)===t.item(0))return!0;if(e.isEqual&&t.isEqual&&t.isEqual(e))return!0}return!1},r.getCaretRangeFromPoint=function(e,t,n){var r,i;if(n.caretPositionFromPoint)i=n.caretPositionFromPoint(e,t),r=n.createRange(),r.setStart(i.offsetNode,i.offset),r.collapse(!0);else if(n.caretRangeFromPoint)r=n.caretRangeFromPoint(e,t);else if(n.body.createTextRange){r=n.body.createTextRange();try{r.moveToPoint(e,t),r.collapse(!0)}catch(o){r.collapse(t=e.childNodes.length&&(t=e.childNodes.length-1),e=e.childNodes[t]),e},r}),r(_,[w,u],function(e,t){return function(n){function r(e){var t,r;if(r=n.$(e).parentsUntil(n.getBody()).add(e),r.length===o.length){for(t=r.length;t>=0&&r[t]===o[t];t--);if(-1===t)return o=r,!0}return o=r,!1}var i,o=[];"onselectionchange"in n.getDoc()||n.on("NodeChange Click MouseUp KeyUp Focus",function(t){var r,o;r=n.selection.getRng(),o={startContainer:r.startContainer,startOffset:r.startOffset,endContainer:r.endContainer,endOffset:r.endOffset},"nodechange"!=t.type&&e.compareRanges(o,i)||n.fire("SelectionChange"),i=o}),n.on("contextmenu",function(){n.fire("SelectionChange")}),n.on("SelectionChange",function(){var e=n.selection.getStart(!0);(t.range||!n.selection.isCollapsed())&&!r(e)&&n.dom.isChildOf(e,n.getBody())&&n.nodeChanged({selectionChange:!0})}),n.on("MouseUp",function(e){e.isDefaultPrevented()||("IMG"==n.selection.getNode().nodeName?setTimeout(function(){n.nodeChanged()},0):n.nodeChanged())}),this.nodeChanged=function(e){var t=n.selection,r,i,o;n.initialized&&t&&!n.settings.disable_nodechange&&!n.settings.readonly&&(o=n.getBody(),r=t.getStart()||o,r=r.ownerDocument!=n.getDoc()?n.getBody():r,"IMG"==r.nodeName&&t.isCollapsed()&&(r=r.parentNode),i=[],n.dom.getParent(r,function(e){return e===o?!0:void i.push(e)}),e=e||{},e.element=r,e.parents=i,n.fire("NodeChange",e))}}}),r(E,[],function(){function e(e,t,n){var r,i,o=n?"lastChild":"firstChild",a=n?"prev":"next";if(e[o])return e[o];if(e!==t){if(r=e[a])return r;for(i=e.parent;i&&i!==t;i=i.parent)if(r=i[a])return r}}function t(e,t){this.name=e,this.type=t,1===t&&(this.attributes=[],this.attributes.map={})}var n=/^[ \t\r\n]*$/,r={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};return t.prototype={replace:function(e){var t=this;return e.parent&&e.remove(),t.insert(e,t),t.remove(),t},attr:function(e,t){var n=this,r,i,o;if("string"!=typeof e){for(i in e)n.attr(i,e[i]);return n}if(r=n.attributes){if(t!==o){if(null===t){if(e in r.map)for(delete r.map[e],i=r.length;i--;)if(r[i].name===e)return r=r.splice(i,1),n;return n}if(e in r.map){for(i=r.length;i--;)if(r[i].name===e){r[i].value=t;break}}else r.push({name:e,value:t});return r.map[e]=t,n}return r.map[e]}},clone:function(){var e=this,n=new t(e.name,e.type),r,i,o,a,s;if(o=e.attributes){for(s=[],s.map={},r=0,i=o.length;i>r;r++)a=o[r],"id"!==a.name&&(s[s.length]={name:a.name,value:a.value},s.map[a.name]=a.value);n.attributes=s}return n.value=e.value,n.shortEnded=e.shortEnded,n},wrap:function(e){var t=this;return t.parent.insert(e,t),e.append(t),t},unwrap:function(){var e=this,t,n;for(t=e.firstChild;t;)n=t.next,e.insert(t,e,!0),t=n;e.remove()},remove:function(){var e=this,t=e.parent,n=e.next,r=e.prev;return t&&(t.firstChild===e?(t.firstChild=n,n&&(n.prev=null)):r.next=n,t.lastChild===e?(t.lastChild=r,r&&(r.next=null)):n.prev=r,e.parent=e.next=e.prev=null),e},append:function(e){var t=this,n;return e.parent&&e.remove(),n=t.lastChild,n?(n.next=e,e.prev=n,t.lastChild=e):t.lastChild=t.firstChild=e,e.parent=t,e},insert:function(e,t,n){var r;return e.parent&&e.remove(),r=t.parent||this,n?(t===r.firstChild?r.firstChild=e:t.prev.next=e,e.prev=t.prev,e.next=t,t.prev=e):(t===r.lastChild?r.lastChild=e:t.next.prev=e,e.next=t.next,e.prev=t,t.next=e),e.parent=r,e},getAll:function(t){var n=this,r,i=[];for(r=n.firstChild;r;r=e(r,n))r.name===t&&i.push(r);return i},empty:function(){var t=this,n,r,i;if(t.firstChild){for(n=[],i=t.firstChild;i;i=e(i,t))n.push(i);for(r=n.length;r--;)i=n[r],i.parent=i.firstChild=i.lastChild=i.next=i.prev=null}return t.firstChild=t.lastChild=null,t},isEmpty:function(t){var r=this,i=r.firstChild,o,a;if(i)do{if(1===i.type){if(i.attributes.map["data-mce-bogus"])continue;if(t[i.name])return!1;for(o=i.attributes.length;o--;)if(a=i.attributes[o].name,"name"===a||0===a.indexOf("data-mce-bookmark"))return!1}if(8===i.type)return!1;if(3===i.type&&!n.test(i.value))return!1}while(i=e(i,r));return!0},walk:function(t){return e(this,null,t)}},t.create=function(e,n){var i,o;if(i=new t(e,r[e]||1),n)for(o in n)i.attr(o,n[o]);return i},t}),r(N,[f],function(e){function t(e,t){return e?e.split(t||" "):[]}function n(e){function n(e,n,r){function i(e,t){var n={},r,i;for(r=0,i=e.length;i>r;r++)n[e[r]]=t||{};return n}var s,c,u,d=arguments;for(r=r||[],n=n||"","string"==typeof r&&(r=t(r)),c=3;co;o++)i.attributes[n[o]]={},i.attributesOrder.push(n[o])}var a={},l,c,u,d,f,h;return i[e]?i[e]:(l=t("id accesskey class dir lang style tabindex title"),c=t("address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul"),u=t("a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd label map noscript object q s samp script select small span strong sub sup textarea u var #text #comment"),"html4"!=e&&(l.push.apply(l,t("contenteditable contextmenu draggable dropzone hidden spellcheck translate")),c.push.apply(c,t("article aside details dialog figure header footer hgroup section nav")),u.push.apply(u,t("audio canvas command datalist mark meter output picture progress time wbr video ruby bdi keygen"))),"html5-strict"!=e&&(l.push("xml:lang"),h=t("acronym applet basefont big font strike tt"),u.push.apply(u,h),s(h,function(e){n(e,"",u)}),f=t("center dir isindex noframes"),c.push.apply(c,f),d=[].concat(c,u),s(f,function(e){n(e,"",d)})),d=d||[].concat(c,u),n("html","manifest","head body"),n("head","","base command link meta noscript script style title"),n("title hr noscript br"),n("base","href target"),n("link","href rel media hreflang type sizes hreflang"),n("meta","name http-equiv content charset"),n("style","media type scoped"),n("script","src async defer type charset"),n("body","onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onscroll onstorage onunload",d),n("address dt dd div caption","",d),n("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn","",u),n("blockquote","cite",d),n("ol","reversed start type","li"),n("ul","","li"),n("li","value",d),n("dl","","dt dd"),n("a","href target rel media hreflang type",u),n("q","cite",u),n("ins del","cite datetime",d),n("img","src sizes srcset alt usemap ismap width height"),n("iframe","src name width height",d),n("embed","src type width height"),n("object","data type typemustmatch name usemap form width height",d,"param"),n("param","name value"),n("map","name",d,"area"),n("area","alt coords shape href target rel media hreflang type"),n("table","border","caption colgroup thead tfoot tbody tr"+("html4"==e?" col":"")),n("colgroup","span","col"),n("col","span"),n("tbody thead tfoot","","tr"),n("tr","","td th"),n("td","colspan rowspan headers",d),n("th","colspan rowspan headers scope abbr",d),n("form","accept-charset action autocomplete enctype method name novalidate target",d),n("fieldset","disabled form name",d,"legend"),n("label","form for",u),n("input","accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"),n("button","disabled form formaction formenctype formmethod formnovalidate formtarget name type value","html4"==e?d:u),n("select","disabled form multiple name required size","option optgroup"),n("optgroup","disabled label","option"),n("option","disabled label selected value"),n("textarea","cols dirname disabled form maxlength name readonly required rows wrap"),n("menu","type label",d,"li"),n("noscript","",d),"html4"!=e&&(n("wbr"),n("ruby","",u,"rt rp"),n("figcaption","",d),n("mark rt rp summary bdi","",u),n("canvas","width height",d),n("video","src crossorigin poster preload autoplay mediagroup loop muted controls width height buffered",d,"track source"),n("audio","src crossorigin preload autoplay mediagroup loop muted controls buffered volume",d,"track source"),n("picture","","img source"),n("source","src srcset type media sizes"),n("track","kind src srclang label default"),n("datalist","",u,"option"),n("article section nav aside header footer","",d),n("hgroup","","h1 h2 h3 h4 h5 h6"),n("figure","",d,"figcaption"),n("time","datetime",u),n("dialog","open",d),n("command","type label icon disabled checked radiogroup command"),n("output","for form name",u),n("progress","value max",u),n("meter","value min max low high optimum",u),n("details","open",d,"summary"),n("keygen","autofocus challenge disabled form keytype name")),"html5-strict"!=e&&(r("script","language xml:space"),r("style","xml:space"),r("object","declare classid code codebase codetype archive standby align border hspace vspace"),r("embed","align name hspace vspace"),r("param","valuetype type"),r("a","charset name rev shape coords"),r("br","clear"),r("applet","codebase archive code object alt name width height align hspace vspace"),r("img","name longdesc align border hspace vspace"),r("iframe","longdesc frameborder marginwidth marginheight scrolling align"),r("font basefont","size color face"),r("input","usemap align"),r("select","onchange"),r("textarea"),r("h1 h2 h3 h4 h5 h6 div p legend caption","align"),r("ul","type compact"),r("li","type"),r("ol dl menu dir","compact"),r("pre","width xml:space"),r("hr","align noshade size width"),r("isindex","prompt"),r("table","summary width frame rules cellspacing cellpadding align bgcolor"),r("col","width align char charoff valign"),r("colgroup","width align char charoff valign"),r("thead","align char charoff valign"),r("tr","align char charoff valign bgcolor"),r("th","axis align char charoff valign nowrap bgcolor width height"),r("form","accept"),r("td","abbr axis scope align char charoff valign nowrap bgcolor width height"),r("tfoot","align char charoff valign"),r("tbody","align char charoff valign"),r("area","nohref"),r("body","background bgcolor text link vlink alink")),"html4"!=e&&(r("input button select textarea","autofocus"),r("input textarea","placeholder"),r("a","download"),r("link script img","crossorigin"),r("iframe","sandbox seamless allowfullscreen")),s(t("a form meter progress dfn"),function(e){a[e]&&delete a[e].children[e]}),delete a.caption.children.table,delete a.script,i[e]=a,a)}function r(e,t){var n;return e&&(n={},"string"==typeof e&&(e={"*":e}),s(e,function(e,r){n[r]=n[r.toUpperCase()]="map"==t?a(e,/[, ]/):c(e,/[, ]/)})),n}var i={},o={},a=e.makeMap,s=e.each,l=e.extend,c=e.explode,u=e.inArray;return function(e){function o(t,n,r){var o=e[t];return o?o=a(o,/[, ]/,a(o.toUpperCase(),/[, ]/)):(o=i[t],o||(o=a(n," ",a(n.toUpperCase()," ")),o=l(o,r),i[t]=o)),o}function d(e){return new RegExp("^"+e.replace(/([?+*])/g,".$1")+"$")}function f(e){var n,r,i,o,s,l,c,f,h,p,m,g,v,b,C,w,_,E,N,S=/^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/,k=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,T=/[*?+]/;if(e)for(e=t(e,","),y["@"]&&(w=y["@"].attributes,_=y["@"].attributesOrder),n=0,r=e.length;r>n;n++)if(s=S.exec(e[n])){if(b=s[1],h=s[2],C=s[3],f=s[5],g={},v=[],l={attributes:g,attributesOrder:v},"#"===b&&(l.paddEmpty=!0),"-"===b&&(l.removeEmpty=!0),"!"===s[4]&&(l.removeEmptyAttrs=!0),w){for(E in w)g[E]=w[E];v.push.apply(v,_)}if(f)for(f=t(f,"|"),i=0,o=f.length;o>i;i++)if(s=k.exec(f[i])){if(c={},m=s[1],p=s[2].replace(/::/g,":"),b=s[3],N=s[4],"!"===m&&(l.attributesRequired=l.attributesRequired||[],l.attributesRequired.push(p),c.required=!0),"-"===m){delete g[p],v.splice(u(v,p),1);continue}b&&("="===b&&(l.attributesDefault=l.attributesDefault||[],l.attributesDefault.push({name:p,value:N}),c.defaultValue=N),":"===b&&(l.attributesForced=l.attributesForced||[],l.attributesForced.push({name:p,value:N}),c.forcedValue=N),"<"===b&&(c.validValues=a(N,"?"))),T.test(p)?(l.attributePatterns=l.attributePatterns||[],c.pattern=d(p),l.attributePatterns.push(c)):(g[p]||v.push(p),g[p]=c)}w||"@"!=h||(w=g,_=v),C&&(l.outputName=h,y[C]=l),T.test(h)?(l.pattern=d(h),x.push(l)):y[h]=l}}function h(e){y={},x=[],f(e),s(_,function(e,t){b[t]=e.children})}function p(e){var n=/^(~)?(.+)$/;e&&(i.text_block_elements=i.block_elements=null,s(t(e,","),function(e){var t=n.exec(e),r="~"===t[1],i=r?"span":"div",o=t[2];if(b[o]=b[i],L[o]=i,r||(R[o.toUpperCase()]={},R[o]={}),!y[o]){var a=y[i];a=l({},a),delete a.removeEmptyAttrs,delete a.removeEmpty,y[o]=a}s(b,function(e,t){e[i]&&(b[t]=e=l({},b[t]),e[o]=e[i])})}))}function m(n){var r=/^([+\-]?)(\w+)\[([^\]]+)\]$/;i[e.schema]=null,n&&s(t(n,","),function(e){var n=r.exec(e),i,o;n&&(o=n[1],i=o?b[n[2]]:b[n[2]]={"#comment":{}},i=b[n[2]],s(t(n[3],"|"),function(e){"-"===o?delete i[e]:i[e]={}}))})}function g(e){var t=y[e],n;if(t)return t;for(n=x.length;n--;)if(t=x[n],t.pattern.test(e))return t}var v=this,y={},b={},x=[],C,w,_,E,N,S,k,T,R,A,B,D,M,L={},H={};e=e||{},_=n(e.schema),e.verify_html===!1&&(e.valid_elements="*[*]"),C=r(e.valid_styles),w=r(e.invalid_styles,"map"),T=r(e.valid_classes,"map"),E=o("whitespace_elements","pre script noscript style textarea video audio iframe object"),N=o("self_closing_elements","colgroup dd dt li option p td tfoot th thead tr"),S=o("short_ended_elements","area base basefont br col frame hr img input isindex link meta param embed source wbr track"),k=o("boolean_attributes","checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls"),A=o("non_empty_elements","td th iframe video audio object script",S),B=o("move_caret_before_on_enter_elements","table",A),D=o("text_block_elements","h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure"),R=o("block_elements","hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex option datalist select optgroup",D),M=o("text_inline_elements","span strong b em i font strike u var cite dfn code mark q sup sub samp"),s((e.special||"script noscript style textarea").split(" "),function(e){H[e]=new RegExp("]*>","gi")}),e.valid_elements?h(e.valid_elements):(s(_,function(e,t){y[t]={attributes:e.attributes,attributesOrder:e.attributesOrder},b[t]=e.children}),"html5"!=e.schema&&s(t("strong/b em/i"),function(e){e=t(e,"/"),y[e[1]].outputName=e[0]}),y.img.attributesDefault=[{name:"alt",value:""}],s(t("ol ul sub sup blockquote span font a table tbody tr strong em b i"),function(e){y[e]&&(y[e].removeEmpty=!0)}),s(t("p h1 h2 h3 h4 h5 h6 th td pre div address caption"),function(e){y[e].paddEmpty=!0}),s(t("span"),function(e){y[e].removeEmptyAttrs=!0})),p(e.custom_elements),m(e.valid_children),f(e.extended_valid_elements),m("+ol[ul|ol],+ul[ul|ol]"),e.invalid_elements&&s(c(e.invalid_elements),function(e){y[e]&&delete y[e]}),g("span")||f("span[!data-mce-type|*]"),v.children=b,v.getValidStyles=function(){return C},v.getInvalidStyles=function(){return w},v.getValidClasses=function(){return T},v.getBoolAttrs=function(){return k},v.getBlockElements=function(){return R},v.getTextBlockElements=function(){return D},v.getTextInlineElements=function(){return M},v.getShortEndedElements=function(){return S},v.getSelfClosingElements=function(){return N},v.getNonEmptyElements=function(){return A},v.getMoveCaretBeforeOnEnterElements=function(){return B},v.getWhiteSpaceElements=function(){return E},v.getSpecialElements=function(){return H},v.isValidChild=function(e,t){var n=b[e];return!(!n||!n[t])},v.isValid=function(e,t){var n,r,i=g(e);if(i){if(!t)return!0;if(i.attributes[t])return!0;if(n=i.attributePatterns)for(r=n.length;r--;)if(n[r].pattern.test(e))return!0}return!1},v.getElementRule=g,v.getCustomElements=function(){return L},v.addValidElements=f,v.setValidElements=h,v.addCustomElements=p,v.addValidChildren=m,v.elements=y}}),r(S,[N,v,f],function(e,t,n){function r(e,t,n){var r=1,i,o,a,s;for(s=e.getShortEndedElements(),a=/<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g,a.lastIndex=i=n;o=a.exec(t);){if(i=a.lastIndex,"/"===o[1])r--;else if(!o[1]){if(o[2]in s)continue;r++}if(0===r)break}return i}function i(i,a){function s(){}var l=this;i=i||{},l.schema=a=a||new e,i.fix_self_closing!==!1&&(i.fix_self_closing=!0),o("comment cdata text start end pi doctype".split(" "),function(e){e&&(l[e]=i[e]||s)}),l.parse=function(e){function o(e){var t,n;for(t=h.length;t--&&h[t].name!==e;);if(t>=0){for(n=h.length-1;n>=t;n--)e=h[n],e.valid&&l.end(e.name);h.length=t}}function s(e,t,n,r,o){var a,s,l=/[\s\u0000-\u001F]+/g;if(t=t.toLowerCase(),n=t in C?t:z(n||r||o||""),_&&!y&&0!==t.indexOf("data-")){if(a=T[t],!a&&R){for(s=R.length;s--&&(a=R[s],!a.pattern.test(t)););-1===s&&(a=null)}if(!a)return;if(a.validValues&&!(n in a.validValues))return}if(V[t]&&!i.allow_script_urls){var c=n.replace(l,"");try{c=decodeURIComponent(c)}catch(u){c=unescape(c)}if(U.test(c))return;if(!i.allow_html_data_urls&&$.test(c)&&!/^data:image\//i.test(c))return}p.map[t]=n,p.push({name:t,value:n})}var l=this,c,u=0,d,f,h=[],p,m,g,v,y,b,x,C,w,_,E,N,S,k,T,R,A,B,D,M,L,H,P,O,I,F=0,z=t.decode,W,V=n.makeMap("src,href,data,background,formaction,poster"),U=/((java|vb)script|mhtml):/i,$=/^data:/i;for(H=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-_\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))","g"),P=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g,x=a.getShortEndedElements(),L=i.self_closing_elements||a.getSelfClosingElements(),C=a.getBoolAttrs(),_=i.validate,b=i.remove_internals,W=i.fix_self_closing,O=a.getSpecialElements();c=H.exec(e);){if(u0&&h[h.length-1].name===d&&o(d),!_||(E=a.getElementRule(d))){if(N=!0,_&&(T=E.attributes,R=E.attributePatterns),(k=c[8])?(y=-1!==k.indexOf("data-mce-type"),y&&b&&(N=!1),p=[],p.map={},k.replace(P,s)):(p=[],p.map={}),_&&!y){if(A=E.attributesRequired,B=E.attributesDefault,D=E.attributesForced,M=E.removeEmptyAttrs,M&&!p.length&&(N=!1),D)for(m=D.length;m--;)S=D[m],v=S.name,I=S.value,"{$uid}"===I&&(I="mce_"+F++),p.map[v]=I,p.push({name:v,value:I});if(B)for(m=B.length;m--;)S=B[m],v=S.name,v in p.map||(I=S.value,"{$uid}"===I&&(I="mce_"+F++),p.map[v]=I,p.push({name:v,value:I}));if(A){for(m=A.length;m--&&!(A[m]in p.map););-1===m&&(N=!1)}if(S=p.map["data-mce-bogus"]){if("all"===S){u=r(a,e,H.lastIndex),H.lastIndex=u;continue}N=!1}}N&&l.start(d,p,w)}else N=!1;if(f=O[d]){f.lastIndex=u=c.index+c[0].length,(c=f.exec(e))?(N&&(g=e.substr(u,c.index-u)),u=c.index+c[0].length):(g=e.substr(u),u=e.length),N&&(g.length>0&&l.text(g,!0),l.end(d)),H.lastIndex=u;continue}w||(k&&k.indexOf("/")==k.length-1?N&&l.end(d):h.push({name:d,valid:N}))}else(d=c[1])?(">"===d.charAt(0)&&(d=" "+d),i.allow_conditional_comments||"[if"!==d.substr(0,3)||(d=" "+d),l.comment(d)):(d=c[2])?l.cdata(d):(d=c[3])?l.doctype(d):(d=c[4])&&l.pi(d,c[5]);u=c.index+c[0].length}for(u=0;m--)d=h[m],d.valid&&l.end(d.name)}}var o=n.each;return i.findEndTag=r,i}),r(k,[E,N,S,f],function(e,t,n,r){var i=r.makeMap,o=r.each,a=r.explode,s=r.extend;return function(r,l){function c(t){var n,r,o,a,s,c,d,f,h,p,m,g,v,y,b;for(m=i("tr,td,th,tbody,thead,tfoot,table"),p=l.getNonEmptyElements(),g=l.getTextBlockElements(),v=l.getSpecialElements(),n=0;n1){for(a.reverse(),s=c=u.filterNode(a[0].clone()),h=0;h0)return void(t.value=r);if(n=t.next){if(3==n.type&&n.value.length){t=t.prev;continue}if(!o[n.name]&&"script"!=n.name&&"style"!=n.name){ -t=t.prev;continue}}i=t.prev,t.remove(),t=i}}function g(e){var t,n={};for(t in e)"li"!==t&&"p"!=t&&(n[t]=e[t]);return n}var v,y,b,x,C,w,_,E,N,S,k,T,R,A=[],B,D,M,L,H,P,O,I;if(o=o||{},h={},p={},T=s(i("script,style,head,html,body,title,meta,param"),l.getBlockElements()),O=l.getNonEmptyElements(),P=l.children,k=r.validate,I="forced_root_block"in o?o.forced_root_block:r.forced_root_block,H=l.getWhiteSpaceElements(),R=/^[ \t\r\n]+/,D=/[ \t\r\n]+$/,M=/[ \t\r\n]+/g,L=/^[ \t\r\n]+$/,v=new n({validate:k,allow_script_urls:r.allow_script_urls,allow_conditional_comments:r.allow_conditional_comments,self_closing_elements:g(l.getSelfClosingElements()),cdata:function(e){b.append(u("#cdata",4)).value=e},text:function(e,t){var n;B||(e=e.replace(M," "),b.lastChild&&T[b.lastChild.name]&&(e=e.replace(R,""))),0!==e.length&&(n=u("#text",3),n.raw=!!t,b.append(n).value=e)},comment:function(e){b.append(u("#comment",8)).value=e},pi:function(e,t){b.append(u(e,7)).value=t,m(b)},doctype:function(e){var t;t=b.append(u("#doctype",10)),t.value=e,m(b)},start:function(e,t,n){var r,i,o,a,s;if(o=k?l.getElementRule(e):{}){for(r=u(o.outputName||e,1),r.attributes=t,r.shortEnded=n,b.append(r),s=P[b.name],s&&P[r.name]&&!s[r.name]&&A.push(r),i=f.length;i--;)a=f[i].name,a in t.map&&(N=p[a],N?N.push(r):p[a]=[r]);T[e]&&m(r),n||(b=r),!B&&H[e]&&(B=!0)}},end:function(t){var n,r,i,o,a;if(r=k?l.getElementRule(t):{}){if(T[t]&&!B){if(n=b.firstChild,n&&3===n.type)if(i=n.value.replace(R,""),i.length>0)n.value=i,n=n.next;else for(o=n.next,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.next,(0===i.length||L.test(i))&&(n.remove(),n=o),n=o;if(n=b.lastChild,n&&3===n.type)if(i=n.value.replace(D,""),i.length>0)n.value=i,n=n.prev;else for(o=n.prev,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.prev,(0===i.length||L.test(i))&&(n.remove(),n=o),n=o}if(B&&H[t]&&(B=!1),(r.removeEmpty||r.paddEmpty)&&b.isEmpty(O))if(r.paddEmpty)b.empty().append(new e("#text","3")).value="\xa0";else if(!b.attributes.map.name&&!b.attributes.map.id)return a=b.parent,T[b.name]?b.empty().remove():b.unwrap(),void(b=a);b=b.parent}}},l),y=b=new e(o.context||r.root_name,11),v.parse(t),k&&A.length&&(o.context?o.invalid=!0:c(A)),I&&("body"==y.name||o.isRootContent)&&a(),!o.invalid){for(S in h){for(N=d[S],x=h[S],_=x.length;_--;)x[_].parent||x.splice(_,1);for(C=0,w=N.length;w>C;C++)N[C](x,S,o)}for(C=0,w=f.length;w>C;C++)if(N=f[C],N.name in p){for(x=p[N.name],_=x.length;_--;)x[_].parent||x.splice(_,1);for(_=0,E=N.callbacks.length;E>_;_++)N.callbacks[_](x,N.name,o)}}return y},r.remove_trailing_brs&&u.addNodeFilter("br",function(t){var n,r=t.length,i,o=s({},l.getBlockElements()),a=l.getNonEmptyElements(),c,u,d,f,h,p;for(o.body=1,n=0;r>n;n++)if(i=t[n],c=i.parent,o[i.parent.name]&&i===c.lastChild){for(d=i.prev;d;){if(f=d.name,"span"!==f||"bookmark"!==d.attr("data-mce-type")){if("br"!==f)break;if("br"===f){i=null;break}}d=d.prev}i&&(i.remove(),c.isEmpty(a)&&(h=l.getElementRule(c.name),h&&(h.removeEmpty?c.remove():h.paddEmpty&&(c.empty().append(new e("#text",3)).value="\xa0"))))}else{for(u=i;c&&c.firstChild===u&&c.lastChild===u&&(u=c,!o[c.name]);)c=c.parent;u===c&&(p=new e("#text",3),p.value="\xa0",i.replace(p))}}),r.allow_html_in_named_anchor||u.addAttributeFilter("id,name",function(e){for(var t=e.length,n,r,i,o;t--;)if(o=e[t],"a"===o.name&&o.firstChild&&!o.attr("href")){i=o.parent,n=o.lastChild;do r=n.prev,i.insert(n,o),n=r;while(n)}}),r.validate&&l.getValidClasses()&&u.addAttributeFilter("class",function(e){for(var t=e.length,n,r,i,o,a,s=l.getValidClasses(),c,u;t--;){for(n=e[t],r=n.attr("class").split(" "),a="",i=0;i0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n")),r.push("<",e),t)for(c=0,u=t.length;u>c;c++)d=t[c],r.push(" ",d.name,'="',s(d.value,!0),'"');!n||l?r[r.length]=">":r[r.length]=" />",n&&i&&a[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n"))},end:function(e){var t;r.push(""),i&&a[e]&&r.length>0&&(t=r[r.length-1],t.length>0&&"\n"!==t&&r.push("\n"))},text:function(e,t){e.length>0&&(r[r.length]=t?e:s(e))},cdata:function(e){r.push("")},comment:function(e){r.push("")},pi:function(e,t){t?r.push(""):r.push(""),i&&r.push("\n")},doctype:function(e){r.push("",i?"\n":"")},reset:function(){r.length=0},getContent:function(){return r.join("").replace(/\n$/,"")}}}}),r(R,[T,N],function(e,t){return function(n,r){var i=this,o=new e(n);n=n||{},n.validate="validate"in n?n.validate:!0,i.schema=r=r||new t,i.writer=o,i.serialize=function(e){function t(e){var n=i[e.type],s,l,c,u,d,f,h,p,m;if(n)n(e);else{if(s=e.name,l=e.shortEnded,c=e.attributes,a&&c&&c.length>1){for(f=[],f.map={},m=r.getElementRule(e.name),h=0,p=m.attributesOrder.length;p>h;h++)u=m.attributesOrder[h],u in c.map&&(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));for(h=0,p=c.length;p>h;h++)u=c[h].name,u in f.map||(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));c=f}if(o.start(e.name,c,l),!l){if(e=e.firstChild)do t(e);while(e=e.next);o.end(s)}}}var i,a;return a=n.validate,i={3:function(e){o.text(e.value,e.raw)},8:function(e){o.comment(e.value)},7:function(e){o.pi(e.name,e.value)},10:function(e){o.doctype(e.value)},4:function(e){o.cdata(e.value)},11:function(e){if(e=e.firstChild)do t(e);while(e=e.next)}},o.reset(),1!=e.type||n.inner?i[11](e):t(e),o.getContent()}}}),r(A,[b,k,v,R,E,N,u,f],function(e,t,n,r,i,o,a,s){function l(e){function t(e){return e&&"br"===e.name}var n,r;n=e.lastChild,t(n)&&(r=n.prev,t(r)&&(n.remove(),r.remove()))}var c=s.each,u=s.trim,d=e.DOM;return function(e,i){var s,f,h;return i&&(s=i.dom,f=i.schema),s=s||d,f=f||new o(e),e.entity_encoding=e.entity_encoding||"named",e.remove_trailing_brs="remove_trailing_brs"in e?e.remove_trailing_brs:!0,h=new t(e,f),h.addAttributeFilter("data-mce-tabindex",function(e,t){for(var n=e.length,r;n--;)r=e[n],r.attr("tabindex",r.attributes.map["data-mce-tabindex"]),r.attr(t,null)}),h.addAttributeFilter("src,href,style",function(t,n){for(var r=t.length,i,o,a="data-mce-"+n,l=e.url_converter,c=e.url_converter_scope,u;r--;)i=t[r],o=i.attributes.map[a],o!==u?(i.attr(n,o.length>0?o:null),i.attr(a,null)):(o=i.attributes.map[n],"style"===n?o=s.serializeStyle(s.parseStyle(o),i.name):l&&(o=l.call(c,o,n,i.name)),i.attr(n,o.length>0?o:null))}),h.addAttributeFilter("class",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.attr("class"),r&&(r=n.attr("class").replace(/(?:^|\s)mce-item-\w+(?!\S)/g,""),n.attr("class",r.length>0?r:null))}),h.addAttributeFilter("data-mce-type",function(e,t,n){for(var r=e.length,i;r--;)i=e[r],"bookmark"!==i.attributes.map["data-mce-type"]||n.cleanup||i.remove()}),h.addNodeFilter("noscript",function(e){for(var t=e.length,r;t--;)r=e[t].firstChild,r&&(r.value=n.decode(r.value))}),h.addNodeFilter("script,style",function(e,t){function n(e){return e.replace(/()/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*(()?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}for(var r=e.length,i,o,a;r--;)i=e[r],o=i.firstChild?i.firstChild.value:"","script"===t?(a=i.attr("type"),a&&i.attr("type","mce-no/type"==a?null:a.replace(/^mce\-/,"")),o.length>0&&(i.firstChild.value="// ")):o.length>0&&(i.firstChild.value="")}),h.addNodeFilter("#comment",function(e){for(var t=e.length,n;t--;)n=e[t],0===n.value.indexOf("[CDATA[")?(n.name="#cdata",n.type=4,n.value=n.value.replace(/^\[CDATA\[|\]\]$/g,"")):0===n.value.indexOf("mce:protected ")&&(n.name="#text",n.type=3,n.raw=!0,n.value=unescape(n.value).substr(14))}),h.addNodeFilter("xml:namespace,input",function(e,t){for(var n=e.length,r;n--;)r=e[n],7===r.type?r.remove():1===r.type&&("input"!==t||"type"in r.attributes.map||r.attr("type","text"))}),e.fix_list_elements&&h.addNodeFilter("ul,ol",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.parent,("ul"===r.name||"ol"===r.name)&&n.prev&&"li"===n.prev.name&&n.prev.append(n)}),h.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style,data-mce-selected,data-mce-expando,data-mce-type,data-mce-resize",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),{schema:f,addNodeFilter:h.addNodeFilter,addAttributeFilter:h.addAttributeFilter,serialize:function(t,n){var i=this,o,d,p,m,g,v;return a.ie&&s.select("script,style,select,map").length>0?(g=t.innerHTML,t=t.cloneNode(!1),s.setHTML(t,g)):t=t.cloneNode(!0),o=t.ownerDocument.implementation,o.createHTMLDocument&&(d=o.createHTMLDocument(""),c("BODY"==t.nodeName?t.childNodes:[t],function(e){d.body.appendChild(d.importNode(e,!0))}),t="BODY"!=t.nodeName?d.body.firstChild:d.body,p=s.doc,s.doc=d),n=n||{},n.format=n.format||"html",n.selection&&(n.forced_root_block=""),n.no_events||(n.node=t,i.onPreProcess(n)),v=h.parse(u(n.getInner?t.innerHTML:s.getOuterHTML(t)),n),l(v),m=new r(e,f),n.content=m.serialize(v),n.cleanup||(n.content=n.content.replace(/\uFEFF/g,"")),n.no_events||i.onPostProcess(n),p&&(s.doc=p),n.node=null,n.content},addRules:function(e){f.addValidElements(e)},setRules:function(e){f.setValidElements(e)},onPreProcess:function(e){i&&i.fire("PreProcess",e)},onPostProcess:function(e){i&&i.fire("PostProcess",e)}}}}),r(B,[],function(){function e(e){function t(t,n){var r,i=0,o,a,s,l,c,u,d=-1,f;if(r=t.duplicate(),r.collapse(n),f=r.parentElement(),f.ownerDocument===e.dom.doc){for(;"false"===f.contentEditable;)f=f.parentNode;if(!f.hasChildNodes())return{node:f,inside:1};for(s=f.children,o=s.length-1;o>=i;)if(u=Math.floor((i+o)/2),l=s[u],r.moveToElementText(l),d=r.compareEndPoints(n?"StartToStart":"EndToEnd",t),d>0)o=u-1;else{if(!(0>d))return{node:l};i=u+1}if(0>d)for(l?r.collapse(!1):(r.moveToElementText(f),r.collapse(!0),l=f,a=!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",1)&&f==r.parentElement();)c++;else for(r.collapse(!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",-1)&&f==r.parentElement();)c++;return{node:l,position:d,offset:c,inside:a}}}function n(){function n(e){var n=t(o,e),r,i,s=0,l,c,u;if(r=n.node,i=n.offset,n.inside&&!r.hasChildNodes())return void a[e?"setStart":"setEnd"](r,0);if(i===c)return void a[e?"setStartBefore":"setEndAfter"](r);if(n.position<0){if(l=n.inside?r.firstChild:r.nextSibling,!l)return void a[e?"setStartAfter":"setEndAfter"](r);if(!i)return void(3==l.nodeType?a[e?"setStart":"setEnd"](l,0):a[e?"setStartBefore":"setEndBefore"](l));for(;l;){if(3==l.nodeType&&(u=l.nodeValue,s+=u.length,s>=i)){r=l,s-=i,s=u.length-s;break}l=l.nextSibling}}else{if(l=r.previousSibling,!l)return a[e?"setStartBefore":"setEndBefore"](r);if(!i)return void(3==r.nodeType?a[e?"setStart":"setEnd"](l,r.nodeValue.length):a[e?"setStartAfter":"setEndAfter"](l));for(;l;){if(3==l.nodeType&&(s+=l.nodeValue.length,s>=i)){r=l,s-=i;break}l=l.previousSibling}}a[e?"setStart":"setEnd"](r,s)}var o=e.getRng(),a=i.createRng(),s,l,c,u,d;if(s=o.item?o.item(0):o.parentElement(),s.ownerDocument!=i.doc)return a;if(l=e.isCollapsed(),o.item)return a.setStart(s.parentNode,i.nodeIndex(s)),a.setEnd(a.startContainer,a.startOffset+1),a;try{n(!0),l||n()}catch(f){if(-2147024809!=f.number)throw f;d=r.getBookmark(2),c=o.duplicate(),c.collapse(!0),s=c.parentElement(),l||(c=o.duplicate(),c.collapse(!1),u=c.parentElement(),u.innerHTML=u.innerHTML),s.innerHTML=s.innerHTML,r.moveToBookmark(d),o=e.getRng(),n(!0),l||n()}return a}var r=this,i=e.dom,o=!1;this.getBookmark=function(n){function r(e){var t,n,r,o,a=[];for(t=e.parentNode,n=i.getRoot().parentNode;t!=n&&9!==t.nodeType;){for(r=t.children,o=r.length;o--;)if(e===r[o]){a.push(o);break}e=t,t=t.parentNode}return a}function o(e){var n;return n=t(a,e),n?{position:n.position,offset:n.offset,indexes:r(n.node),inside:n.inside}:void 0}var a=e.getRng(),s={};return 2===n&&(a.item?s.start={ctrl:!0,indexes:r(a.item(0))}:(s.start=o(!0),e.isCollapsed()||(s.end=o()))),s},this.moveToBookmark=function(e){function t(e){var t,n,r,o;for(t=i.getRoot(),n=e.length-1;n>=0;n--)o=t.children,r=e[n],r<=o.length-1&&(t=o[r]);return t}function n(n){var i=e[n?"start":"end"],a,s,l,c;i&&(a=i.position>0,s=o.createTextRange(),s.moveToElementText(t(i.indexes)),c=i.offset,c!==l?(s.collapse(i.inside||a),s.moveStart("character",a?-c:c)):s.collapse(n),r.setEndPoint(n?"StartToStart":"EndToStart",s),n&&r.collapse(!0))}var r,o=i.doc.body;e.start&&(e.start.ctrl?(r=o.createControlRange(),r.addElement(t(e.start.indexes)),r.select()):(r=o.createTextRange(),n(!0),n(),r.select()))},this.addRange=function(t){function n(e){var t,n,a,d,p;a=i.create("a"),t=e?s:c,n=e?l:u,d=r.duplicate(),(t==f||t==f.documentElement)&&(t=h,n=0),3==t.nodeType?(t.parentNode.insertBefore(a,t),d.moveToElementText(a),d.moveStart("character",n),i.remove(a),r.setEndPoint(e?"StartToStart":"EndToEnd",d)):(p=t.childNodes,p.length?(n>=p.length?i.insertAfter(a,p[p.length-1]):t.insertBefore(a,p[n]),d.moveToElementText(a)):t.canHaveHTML&&(t.innerHTML="",a=t.firstChild,d.moveToElementText(a),d.collapse(o)),r.setEndPoint(e?"StartToStart":"EndToEnd",d),i.remove(a))}var r,a,s,l,c,u,d,f=e.dom.doc,h=f.body,p,m;if(s=t.startContainer,l=t.startOffset,c=t.endContainer,u=t.endOffset,r=h.createTextRange(),s==c&&1==s.nodeType){if(l==u&&!s.hasChildNodes()){if(s.canHaveHTML)return d=s.previousSibling,d&&!d.hasChildNodes()&&i.isBlock(d)?d.innerHTML="":d=null,s.innerHTML="",r.moveToElementText(s.lastChild),r.select(),i.doc.selection.clear(),s.innerHTML="",void(d&&(d.innerHTML=""));l=i.nodeIndex(s),s=s.parentNode}if(l==u-1)try{if(m=s.childNodes[l],a=h.createControlRange(),a.addElement(m),a.select(),p=e.getRng(),p.item&&m===p.item(0))return}catch(g){}}n(!0),n(),r.select()},this.getRangeAt=n}return e}),r(D,[u],function(e){return{BACKSPACE:8,DELETE:46,DOWN:40,ENTER:13,LEFT:37,RIGHT:39,SPACEBAR:32,TAB:9,UP:38,modifierPressed:function(e){return e.shiftKey||e.ctrlKey||e.altKey||this.metaKeyPressed(e)},metaKeyPressed:function(t){return e.mac?t.metaKey:t.ctrlKey&&!t.altKey}}}),r(M,[D,f,u],function(e,t,n){return function(r,i){function o(e){var t=i.settings.object_resizing;return t===!1||n.iOS?!1:("string"!=typeof t&&(t="table,img,div"),"false"===e.getAttribute("data-mce-resize")?!1:i.dom.is(e,t))}function a(t){var n,r,o,a,s;n=t.screenX-T,r=t.screenY-R,P=n*S[2]+D,O=r*S[3]+M,P=5>P?5:P,O=5>O?5:O,o="IMG"==w.nodeName&&i.settings.resize_img_proportional!==!1?!e.modifierPressed(t):e.modifierPressed(t)||"IMG"==w.nodeName&&S[2]*S[3]!==0,o&&(W(n)>W(r)?(O=V(P*L),P=V(O/L)):(P=V(O/L),O=V(P*L))),x.setStyles(_,{width:P,height:O}),a=S.startPos.x+n,s=S.startPos.y+r,a=a>0?a:0,s=s>0?s:0,x.setStyles(E,{left:a,top:s,display:"block"}),E.innerHTML=P+" × "+O,S[2]<0&&_.clientWidth<=P&&x.setStyle(_,"left",A+(D-P)),S[3]<0&&_.clientHeight<=O&&x.setStyle(_,"top",B+(M-O)),n=U.scrollWidth-$,r=U.scrollHeight-q,n+r!==0&&x.setStyles(E,{left:a-n,top:s-r}),H||(i.fire("ObjectResizeStart",{target:w,width:D,height:M}),H=!0)}function s(){function e(e,t){t&&(w.style[e]||!i.schema.isValid(w.nodeName.toLowerCase(),e)?x.setStyle(w,e,t):x.setAttrib(w,e,t))}H=!1,e("width",P),e("height",O),x.unbind(I,"mousemove",a),x.unbind(I,"mouseup",s),F!=I&&(x.unbind(F,"mousemove",a),x.unbind(F,"mouseup",s)),x.remove(_),x.remove(E),z&&"TABLE"!=w.nodeName||l(w),i.fire("ObjectResized",{target:w,width:P,height:O}),x.setAttrib(w,"style",x.getAttrib(w,"style")),i.nodeChanged()}function l(e,t,r){var l,u,d,f,h;g(),l=x.getPos(e,U),A=l.x,B=l.y,h=e.getBoundingClientRect(),u=h.width||h.right-h.left,d=h.height||h.bottom-h.top,w!=e&&(m(),w=e,P=O=0),f=i.fire("ObjectSelected",{target:e}),o(e)&&!f.isDefaultPrevented()?C(N,function(e,i){function o(t){T=t.screenX,R=t.screenY,D=w.clientWidth,M=w.clientHeight,L=M/D,S=e,e.startPos={x:u*e[0]+A,y:d*e[1]+B},$=U.scrollWidth,q=U.scrollHeight,_=w.cloneNode(!0),x.addClass(_,"mce-clonedresizable"),x.setAttrib(_,"data-mce-bogus","all"),_.contentEditable=!1,_.unSelectabe=!0,x.setStyles(_,{left:A,top:B,margin:0}),_.removeAttribute("data-mce-selected"),U.appendChild(_),x.bind(I,"mousemove",a),x.bind(I,"mouseup",s),F!=I&&(x.bind(F,"mousemove",a),x.bind(F,"mouseup",s)),E=x.add(U,"div",{"class":"mce-resize-helper","data-mce-bogus":"all"},D+" × "+M)}var l;return t?void(i==t&&o(r)):(l=x.get("mceResizeHandle"+i),l&&x.remove(l),l=x.add(U,"div",{id:"mceResizeHandle"+i,"data-mce-bogus":"all","class":"mce-resizehandle",unselectable:!0,style:"cursor:"+i+"-resize; margin:0; padding:0"}),n.ie&&(l.contentEditable=!1),x.bind(l,"mousedown",function(e){e.stopImmediatePropagation(),e.preventDefault(),o(e)}),e.elm=l,void x.setStyles(l,{left:u*e[0]+A-l.offsetWidth/2,top:d*e[1]+B-l.offsetHeight/2}))}):c(),w.setAttribute("data-mce-selected","1")}function c(){var e,t;g(),w&&w.removeAttribute("data-mce-selected");for(e in N)t=x.get("mceResizeHandle"+e),t&&(x.unbind(t),x.remove(t))}function u(e){function t(e,t){if(e)do if(e===t)return!0;while(e=e.parentNode)}var n,o;if(!H&&!i.removed)return C(x.select("img[data-mce-selected],hr[data-mce-selected]"),function(e){e.removeAttribute("data-mce-selected")}),o="mousedown"==e.type?e.target:r.getNode(),o=x.$(o).closest(z?"table":"table,img,hr")[0],t(o,U)&&(v(),n=r.getStart(!0),t(n,o)&&t(r.getEnd(!0),o)&&(!z||o!=n&&"IMG"!==n.nodeName))?void l(o):void c()}function d(e,t,n){e&&e.attachEvent&&e.attachEvent("on"+t,n)}function f(e,t,n){e&&e.detachEvent&&e.detachEvent("on"+t,n)}function h(e){var t=e.srcElement,n,r,o,a,s,c,u;n=t.getBoundingClientRect(),c=k.clientX-n.left,u=k.clientY-n.top;for(r in N)if(o=N[r],a=t.offsetWidth*o[0],s=t.offsetHeight*o[1],W(a-c)<8&&W(s-u)<8){S=o;break}H=!0,i.fire("ObjectResizeStart",{target:w,width:w.clientWidth,height:w.clientHeight}),i.getDoc().selection.empty(),l(t,r,k)}function p(e){var t=e.srcElement;if(t!=w){if(i.fire("ObjectSelected",{target:t}),m(),0===t.id.indexOf("mceResizeHandle"))return void(e.returnValue=!1);("IMG"==t.nodeName||"TABLE"==t.nodeName)&&(c(),w=t,d(t,"resizestart",h))}}function m(){f(w,"resizestart",h)}function g(){for(var e in N){var t=N[e];t.elm&&(x.unbind(t.elm),delete t.elm)}}function v(){try{i.getDoc().execCommand("enableObjectResizing",!1,!1)}catch(e){}}function y(e){var t;if(z){t=I.body.createControlRange();try{return t.addElement(e),t.select(),!0}catch(n){}}}function b(){w=_=null,z&&(m(),f(U,"controlselect",p))}var x=i.dom,C=t.each,w,_,E,N,S,k,T,R,A,B,D,M,L,H,P,O,I=i.getDoc(),F=document,z=n.ie&&n.ie<11,W=Math.abs,V=Math.round,U=i.getBody(),$,q;N={nw:[0,0,-1,-1],ne:[1,0,1,-1],se:[1,1,1,1],sw:[0,1,-1,1]};var j=".mce-content-body";return i.contentStyles.push(j+" div.mce-resizehandle {position: absolute;border: 1px solid black;background: #FFF;width: 7px;height: 7px;z-index: 10000}"+j+" .mce-resizehandle:hover {background: #000}"+j+" img[data-mce-selected], hr[data-mce-selected] {outline: 1px solid black;resize: none}"+j+" .mce-clonedresizable {position: absolute;"+(n.gecko?"":"outline: 1px dashed black;")+"opacity: .5;filter: alpha(opacity=50);z-index: 10000}"+j+" .mce-resize-helper {background: #555;background: rgba(0,0,0,0.75);border-radius: 3px;border: 1px;color: white;display: none;font-family: sans-serif;font-size: 12px;white-space: nowrap;line-height: 14px;margin: 5px 10px;padding: 5px;position: absolute;z-index: 10001}"),i.on("init",function(){z?(i.on("ObjectResized",function(e){"TABLE"!=e.target.nodeName&&(c(),y(e.target))}),d(U,"controlselect",p),i.on("mousedown",function(e){k=e})):(v(),n.ie>=11&&(i.on("mousedown click",function(e){var t=e.target.nodeName;!H&&/^(TABLE|IMG|HR)$/.test(t)&&(i.selection.select(e.target,"TABLE"==t),"mousedown"==e.type&&i.nodeChanged())}),i.dom.bind(U,"mscontrolselect",function(e){/^(TABLE|IMG|HR)$/.test(e.target.nodeName)&&(e.preventDefault(),"IMG"==e.target.tagName&&window.setTimeout(function(){i.selection.select(e.target)},0))}))),i.on("nodechange ResizeEditor ResizeWindow drop",function(e){window.requestAnimationFrame?window.requestAnimationFrame(function(){u(e)}):u(e)}),i.on("keydown keyup",function(e){w&&"TABLE"==w.nodeName&&u(e)}),i.on("hide blur",c)}),i.on("remove",g),{isResizable:o,showResizeRect:l,hideResizeRect:c,updateResizeRect:u,controlSelect:y,destroy:b}}}),r(L,[u,f],function(e,t){function n(n){var r=n.dom;this.getBookmark=function(e,i){function o(e,n){var i=0;return t.each(r.select(e),function(e,t){e==n&&(i=t)}),i}function a(e){function t(t){var n,r,i,o=t?"start":"end";n=e[o+"Container"],r=e[o+"Offset"],1==n.nodeType&&"TR"==n.nodeName&&(i=n.childNodes,n=i[Math.min(t?r:r-1,i.length-1)],n&&(r=t?0:n.childNodes.length,e["set"+(t?"Start":"End")](n,r)))}return t(!0),t(),e}function s(){function e(e,t){var n=e[t?"startContainer":"endContainer"],a=e[t?"startOffset":"endOffset"],s=[],l,c,u=0;if(3==n.nodeType){if(i)for(l=n.previousSibling;l&&3==l.nodeType;l=l.previousSibling)a+=l.nodeValue.length;s.push(a)}else c=n.childNodes,a>=c.length&&c.length&&(u=1,a=Math.max(0,c.length-1)),s.push(r.nodeIndex(c[a],i)+u);for(;n&&n!=o;n=n.parentNode)s.push(r.nodeIndex(n,i));return s}var t=n.getRng(!0),o=r.getRoot(),a={};return a.start=e(t,!0),n.isCollapsed()||(a.end=e(t)),a}var l,c,u,d,f,h,p="",m;if(2==e)return h=n.getNode(),f=h?h.nodeName:null,"IMG"==f?{name:f,index:o(f,h)}:n.tridentSel?n.tridentSel.getBookmark(e):s();if(e)return{rng:n.getRng()};if(l=n.getRng(),u=r.uniqueId(),d=n.isCollapsed(),m="overflow:hidden;line-height:0px",l.duplicate||l.item){if(l.item)return h=l.item(0),f=h.nodeName,{name:f,index:o(f,h)};c=l.duplicate();try{l.collapse(),l.pasteHTML(''+p+""),d||(c.collapse(!1),l.moveToElementText(c.parentElement()),0===l.compareEndPoints("StartToEnd",c)&&c.move("character",-1),c.pasteHTML(''+p+""))}catch(g){return null}}else{if(h=n.getNode(),f=h.nodeName,"IMG"==f)return{name:f,index:o(f,h)};c=a(l.cloneRange()),d||(c.collapse(!1),c.insertNode(r.create("span",{"data-mce-type":"bookmark",id:u+"_end",style:m},p))),l=a(l),l.collapse(!0),l.insertNode(r.create("span",{"data-mce-type":"bookmark",id:u+"_start",style:m},p))}return n.moveToBookmark({id:u,keep:1}),{id:u}},this.moveToBookmark=function(i){function o(e){var t=i[e?"start":"end"],n,r,o,a;if(t){for(o=t[0],r=c,n=t.length-1;n>=1;n--){if(a=r.childNodes,t[n]>a.length-1)return;r=a[t[n]]}3===r.nodeType&&(o=Math.min(t[0],r.nodeValue.length)),1===r.nodeType&&(o=Math.min(t[0],r.childNodes.length)),e?l.setStart(r,o):l.setEnd(r,o)}return!0}function a(n){var o=r.get(i.id+"_"+n),a,s,l,c,p=i.keep;if(o&&(a=o.parentNode,"start"==n?(p?(a=o.firstChild,s=1):s=r.nodeIndex(o),u=d=a,f=h=s):(p?(a=o.firstChild,s=1):s=r.nodeIndex(o),d=a,h=s),!p)){for(c=o.previousSibling,l=o.nextSibling,t.each(t.grep(o.childNodes),function(e){3==e.nodeType&&(e.nodeValue=e.nodeValue.replace(/\uFEFF/g,""))});o=r.get(i.id+"_"+n);)r.remove(o,1);c&&l&&c.nodeType==l.nodeType&&3==c.nodeType&&!e.opera&&(s=c.nodeValue.length,c.appendData(l.nodeValue),r.remove(l),"start"==n?(u=d=c,f=h=s):(d=c,h=s))}}function s(t){return!r.isBlock(t)||t.innerHTML||e.ie||(t.innerHTML='
'),t}var l,c,u,d,f,h;if(i)if(i.start){if(l=r.createRng(),c=r.getRoot(),n.tridentSel)return n.tridentSel.moveToBookmark(i);o(!0)&&o()&&n.setRng(l)}else i.id?(a("start"),a("end"),u&&(l=r.createRng(),l.setStart(s(u),f),l.setEnd(s(d),h),n.setRng(l))):i.name?n.select(r.select(i.name)[i.index]):i.rng&&n.setRng(i.rng)}}return n.isBookmarkNode=function(e){return e&&"SPAN"===e.tagName&&"bookmark"===e.getAttribute("data-mce-type")},n}),r(H,[m,B,M,w,L,u,f],function(e,n,r,i,o,a,s){function l(e,t,i,a){var s=this;s.dom=e,s.win=t,s.serializer=i,s.editor=a,s.bookmarkManager=new o(s),s.controlSelection=new r(s,a),s.win.getSelection||(s.tridentSel=new n(s))}var c=s.each,u=s.trim,d=a.ie;return l.prototype={setCursorLocation:function(e,t){var n=this,r=n.dom.createRng();e?(r.setStart(e,t),r.setEnd(e,t),n.setRng(r),n.collapse(!1)):(n._moveEndPoint(r,n.editor.getBody(),!0),n.setRng(r))},getContent:function(e){var n=this,r=n.getRng(),i=n.dom.create("body"),o=n.getSel(),a,s,l;return e=e||{},a=s="",e.get=!0,e.format=e.format||"html",e.selection=!0,n.editor.fire("BeforeGetContent",e),"text"==e.format?n.isCollapsed()?"":r.text||(o.toString?o.toString():""):(r.cloneContents?(l=r.cloneContents(),l&&i.appendChild(l)):r.item!==t||r.htmlText!==t?(i.innerHTML="
"+(r.item?r.item(0).outerHTML:r.htmlText),i.removeChild(i.firstChild)):i.innerHTML=r.toString(),/^\s/.test(i.innerHTML)&&(a=" "),/\s+$/.test(i.innerHTML)&&(s=" "),e.getInner=!0,e.content=n.isCollapsed()?"":a+n.serializer.serialize(i,e)+s,n.editor.fire("GetContent",e),e.content)},setContent:function(e,t){var n=this,r=n.getRng(),i,o=n.win.document,a,s;if(t=t||{format:"html"},t.set=!0,t.selection=!0,e=t.content=e,t.no_events||n.editor.fire("BeforeSetContent",t),e=t.content,r.insertNode){e+='_',r.startContainer==o&&r.endContainer==o?o.body.innerHTML=e:(r.deleteContents(),0===o.body.childNodes.length?o.body.innerHTML=e:r.createContextualFragment?r.insertNode(r.createContextualFragment(e)):(a=o.createDocumentFragment(),s=o.createElement("div"),a.appendChild(s),s.outerHTML=e,r.insertNode(a))),i=n.dom.get("__caret"),r=o.createRange(),r.setStartBefore(i),r.setEndBefore(i),n.setRng(r),n.dom.remove("__caret");try{n.setRng(r)}catch(l){}}else r.item&&(o.execCommand("Delete",!1,null),r=n.getRng()),/^\s+/.test(e)?(r.pasteHTML('_'+e),n.dom.remove("__mce_tmp")):r.pasteHTML(e);t.no_events||n.editor.fire("SetContent",t)},getStart:function(e){var t=this,n=t.getRng(),r,i,o,a;if(n.duplicate||n.item){if(n.item)return n.item(0);for(o=n.duplicate(),o.collapse(1),r=o.parentElement(),r.ownerDocument!==t.dom.doc&&(r=t.dom.getRoot()),i=a=n.parentElement();a=a.parentNode;)if(a==r){r=i;break}return r}return r=n.startContainer,1==r.nodeType&&r.hasChildNodes()&&(e&&n.collapsed||(r=r.childNodes[Math.min(r.childNodes.length-1,n.startOffset)])),r&&3==r.nodeType?r.parentNode:r},getEnd:function(e){var t=this,n=t.getRng(),r,i;return n.duplicate||n.item?n.item?n.item(0):(n=n.duplicate(),n.collapse(0),r=n.parentElement(),r.ownerDocument!==t.dom.doc&&(r=t.dom.getRoot()),r&&"BODY"==r.nodeName?r.lastChild||r:r):(r=n.endContainer,i=n.endOffset,1==r.nodeType&&r.hasChildNodes()&&(e&&n.collapsed||(r=r.childNodes[i>0?i-1:i])),r&&3==r.nodeType?r.parentNode:r)},getBookmark:function(e,t){return this.bookmarkManager.getBookmark(e,t)},moveToBookmark:function(e){return this.bookmarkManager.moveToBookmark(e)},select:function(e,t){var n=this,r=n.dom,i=r.createRng(),o;if(n.lastFocusBookmark=null,e){if(!t&&n.controlSelection.controlSelect(e))return;o=r.nodeIndex(e),i.setStart(e.parentNode,o),i.setEnd(e.parentNode,o+1),t&&(n._moveEndPoint(i,e,!0),n._moveEndPoint(i,e)),n.setRng(i)}return e},isCollapsed:function(){var e=this,t=e.getRng(),n=e.getSel();return!t||t.item?!1:t.compareEndPoints?0===t.compareEndPoints("StartToEnd",t):!n||t.collapsed},collapse:function(e){var t=this,n=t.getRng(),r;n.item&&(r=n.item(0),n=t.win.document.body.createTextRange(),n.moveToElementText(r)),n.collapse(!!e),t.setRng(n)},getSel:function(){var e=this.win;return e.getSelection?e.getSelection():e.document.selection},getRng:function(e){function t(e,t,n){try{return t.compareBoundaryPoints(e,n)}catch(r){return-1}}var n=this,r,i,o,a=n.win.document,s;if(!e&&n.lastFocusBookmark){var l=n.lastFocusBookmark;return l.startContainer?(i=a.createRange(),i.setStart(l.startContainer,l.startOffset),i.setEnd(l.endContainer,l.endOffset)):i=l,i}if(e&&n.tridentSel)return n.tridentSel.getRangeAt(0);try{(r=n.getSel())&&(i=r.rangeCount>0?r.getRangeAt(0):r.createRange?r.createRange():a.createRange())}catch(c){}if(d&&i&&i.setStart&&a.selection){try{s=a.selection.createRange()}catch(c){}s&&s.item&&(o=s.item(0),i=a.createRange(),i.setStartBefore(o),i.setEndAfter(o))}return i||(i=a.createRange?a.createRange():a.body.createTextRange()),i.setStart&&9===i.startContainer.nodeType&&i.collapsed&&(o=n.dom.getRoot(),i.setStart(o,0),i.setEnd(o,0)),n.selectedRange&&n.explicitRange&&(0===t(i.START_TO_START,i,n.selectedRange)&&0===t(i.END_TO_END,i,n.selectedRange)?i=n.explicitRange:(n.selectedRange=null,n.explicitRange=null)),i},setRng:function(e,t){var n=this,r,i;if(e)if(e.select)try{e.select()}catch(o){}else if(n.tridentSel){if(e.cloneRange)try{return void n.tridentSel.addRange(e)}catch(o){}}else{if(r=n.getSel()){n.explicitRange=e;try{r.removeAllRanges(),r.addRange(e)}catch(o){}t===!1&&r.extend&&(r.collapse(e.endContainer,e.endOffset),r.extend(e.startContainer,e.startOffset)),n.selectedRange=r.rangeCount>0?r.getRangeAt(0):null}e.collapsed||e.startContainer!=e.endContainer||!r.setBaseAndExtent||a.ie||e.endOffset-e.startOffset<2&&e.startContainer.hasChildNodes()&&(i=e.startContainer.childNodes[e.startOffset],i&&"IMG"==i.tagName&&n.getSel().setBaseAndExtent(i,0,i,1))}},setNode:function(e){var t=this;return t.setContent(t.dom.getOuterHTML(e)),e},getNode:function(){function e(e,t){for(var n=e;e&&3===e.nodeType&&0===e.length;)e=t?e.nextSibling:e.previousSibling;return e||n}var t=this,n=t.getRng(),r,i=n.startContainer,o=n.endContainer,a=n.startOffset,s=n.endOffset,l=t.dom.getRoot();return n?n.setStart?(r=n.commonAncestorContainer,!n.collapsed&&(i==o&&2>s-a&&i.hasChildNodes()&&(r=i.childNodes[a]),3===i.nodeType&&3===o.nodeType&&(i=i.length===a?e(i.nextSibling,!0):i.parentNode,o=0===s?e(o.previousSibling,!1):o.parentNode,i&&i===o))?i:r&&3==r.nodeType?r.parentNode:r):(r=n.item?n.item(0):n.parentElement(),r.ownerDocument!==t.win.document&&(r=l),r):l},getSelectedBlocks:function(t,n){var r=this,i=r.dom,o,a,s=[];if(a=i.getRoot(),t=i.getParent(t||r.getStart(),i.isBlock),n=i.getParent(n||r.getEnd(),i.isBlock),t&&t!=a&&s.push(t),t&&n&&t!=n){o=t;for(var l=new e(t,a);(o=l.next())&&o!=n;)i.isBlock(o)&&s.push(o)}return n&&t!=n&&n!=a&&s.push(n),s},isForward:function(){var e=this.dom,t=this.getSel(),n,r;return t&&t.anchorNode&&t.focusNode?(n=e.createRng(),n.setStart(t.anchorNode,t.anchorOffset),n.collapse(!0),r=e.createRng(),r.setStart(t.focusNode,t.focusOffset),r.collapse(!0),n.compareBoundaryPoints(n.START_TO_START,r)<=0):!0},normalize:function(){var e=this,t=e.getRng();return a.range&&new i(e.dom).normalize(t)&&e.setRng(t,e.isForward()),t},selectorChanged:function(e,t){var n=this,r;return n.selectorChangedData||(n.selectorChangedData={},r={},n.editor.on("NodeChange",function(e){var t=e.element,i=n.dom,o=i.getParents(t,null,i.getRoot()),a={};c(n.selectorChangedData,function(e,t){c(o,function(n){return i.is(n,t)?(r[t]||(c(e,function(e){e(!0,{node:n,selector:t,parents:o})}),r[t]=e),a[t]=e,!1):void 0})}),c(r,function(e,n){a[n]||(delete r[n],c(e,function(e){e(!1,{node:t,selector:n,parents:o})}))})})),n.selectorChangedData[e]||(n.selectorChangedData[e]=[]),n.selectorChangedData[e].push(t),n},getScrollContainer:function(){for(var e,t=this.dom.getRoot();t&&"BODY"!=t.nodeName;){if(t.scrollHeight>t.clientHeight){e=t;break}t=t.parentNode}return e},scrollIntoView:function(e){function t(e){for(var t=0,n=0,r=e;r&&r.nodeType;)t+=r.offsetLeft||0,n+=r.offsetTop||0,r=r.offsetParent;return{x:t,y:n}}var n,r,i=this,o=i.dom,a=o.getRoot(),s,l;if("BODY"!=a.nodeName){var c=i.getScrollContainer();if(c)return n=t(e).y-t(c).y,l=c.clientHeight,s=c.scrollTop,void((s>n||n+25>s+l)&&(c.scrollTop=s>n?n:n-l+25))}r=o.getViewPort(i.editor.getWin()),n=o.getPos(e).y,s=r.y,l=r.h,(ns+l)&&i.editor.getWin().scrollTo(0,s>n?n:n-l+25)},placeCaretAt:function(e,t){var n=this.editor.getDoc(),r,i;if(n.caretPositionFromPoint)i=n.caretPositionFromPoint(e,t),r=n.createRange(),r.setStart(i.offsetNode,i.offset),r.collapse(!0);else if(n.caretRangeFromPoint)r=n.caretRangeFromPoint(e,t);else if(n.body.createTextRange){ -r=n.body.createTextRange();try{r.moveToPoint(e,t),r.collapse(!0)}catch(o){r.collapse(t=e;e++)a.addShortcut("access+"+e,"",["FormatBlock",!1,"h"+e]);a.addShortcut("access+7","",["FormatBlock",!1,"p"]),a.addShortcut("access+8","",["FormatBlock",!1,"div"]),a.addShortcut("access+9","",["FormatBlock",!1,"address"])}function p(e){return e?$[e]:$}function m(e,t){e&&("string"!=typeof e?le(e,function(e,t){m(t,e)}):(t=t.length?t:[t],le(t,function(e){e.deep===re&&(e.deep=!e.selector),e.split===re&&(e.split=!e.selector||e.inline),e.remove===re&&e.selector&&!e.inline&&(e.remove="none"),e.selector&&e.inline&&(e.mixed=!0,e.block_expand=!0),"string"==typeof e.classes&&(e.classes=e.classes.split(/\s+/))}),$[e]=t))}function g(e){return e&&$[e]&&delete $[e],$}function v(e){var t;return a.dom.getParent(e,function(e){return t=a.dom.getStyle(e,"text-decoration"),t&&"none"!==t}),t}function y(e){var t;1===e.nodeType&&e.parentNode&&1===e.parentNode.nodeType&&(t=v(e.parentNode),a.dom.getStyle(e,"color")&&t?a.dom.setStyle(e,"text-decoration",t):a.dom.getStyle(e,"text-decoration")===t&&a.dom.setStyle(e,"text-decoration",null))}function b(t,n,r){function i(e,t){if(t=t||u,e){if(t.onformat&&t.onformat(e,t,n,r),le(t.styles,function(t,r){q.setStyle(e,r,D(t,n))}),t.styles){var i=q.getAttrib(e,"style");i&&e.setAttribute("data-mce-style",i)}le(t.attributes,function(t,r){q.setAttrib(e,r,D(t,n))}),le(t.classes,function(t){t=D(t,n),q.hasClass(e,t)||q.addClass(e,t)})}}function o(){function t(t,n){var i=new e(n);for(r=i.current();r;r=i.prev())if(r.childNodes.length>1||r==t||"BR"==r.tagName)return r}var n=a.selection.getRng(),i=n.startContainer,o=n.endContainer;if(i!=o&&0===n.endOffset){var s=t(i,o),l=3==s.nodeType?s.length:s.childNodes.length;n.setEnd(s,l)}return n}function l(e,r,o){var a=[],l,f,h=!0;l=u.inline||u.block,f=q.create(l),i(f),K.walk(e,function(e){function r(e){var g,v,y,b,x;return x=h,g=e.nodeName.toLowerCase(),v=e.parentNode.nodeName.toLowerCase(),1===e.nodeType&&ie(e)&&(x=h,h="true"===ie(e),b=!0),R(g,"br")?(p=0,void(u.block&&q.remove(e))):u.wrapper&&w(e,t,n)?void(p=0):h&&!b&&u.block&&!u.wrapper&&s(g)&&Y(v,l)?(e=q.rename(e,l),i(e),a.push(e),void(p=0)):u.selector&&(le(c,function(t){"collapsed"in t&&t.collapsed!==m||q.is(e,t.selector)&&!d(e)&&(i(e,t),y=!0)}),!u.inline||y)?void(p=0):void(!h||b||!Y(l,g)||!Y(v,l)||!o&&3===e.nodeType&&1===e.nodeValue.length&&65279===e.nodeValue.charCodeAt(0)||d(e)||u.inline&&G(e)?(p=0,le(ce(e.childNodes),r),b&&(h=x),p=0):(p||(p=q.clone(f,ee),e.parentNode.insertBefore(p,e),a.push(p)),p.appendChild(e)))}var p;le(e,r)}),u.links===!0&&le(a,function(e){function t(e){"A"===e.nodeName&&i(e,u),le(ce(e.childNodes),t)}t(e)}),le(a,function(e){function r(e){var t=0;return le(e.childNodes,function(e){M(e)||se(e)||t++}),t}function o(e){var t,n;return le(e.childNodes,function(e){return 1!=e.nodeType||se(e)||d(e)?void 0:(t=e,ee)}),t&&!se(t)&&T(t,u)&&(n=q.clone(t,ee),i(n),q.replace(n,e,te),q.remove(t,1)),n||e}var s;if(s=r(e),(a.length>1||!G(e))&&0===s)return void q.remove(e,1);if(u.inline||u.wrapper){if(u.exact||1!==s||(e=o(e)),le(c,function(t){le(q.select(t.inline,e),function(e){se(e)||O(t,n,e,t.exact?e:null)})}),w(e.parentNode,t,n))return q.remove(e,1),e=0,te;u.merge_with_parents&&q.getParent(e.parentNode,function(r){return w(r,t,n)?(q.remove(e,1),e=0,te):void 0}),e&&u.merge_siblings!==!1&&(e=z(F(e),e),e=z(e,F(e,te)))}})}var c=p(t),u=c[0],f,h,m=!r&&j.isCollapsed();if(u)if(r)r.nodeType?(h=q.createRng(),h.setStartBefore(r),h.setEndAfter(r),l(H(h,c),null,!0)):l(r,null,!0);else if(m&&u.inline&&!q.select("td.mce-item-selected,th.mce-item-selected").length)V("apply",t,n);else{var g=a.selection.getNode();X||!c[0].defaultBlock||q.getParent(g,q.isBlock)||b(c[0].defaultBlock),a.selection.setRng(o()),f=j.getBookmark(),l(H(j.getRng(te),c),f),u.styles&&(u.styles.color||u.styles.textDecoration)&&(ue(g,y,"childNodes"),y(g)),j.moveToBookmark(f),U(j.getRng(te)),a.nodeChanged()}}function x(e,t,n,r){function i(e){var n,r,o,a,s;if(1===e.nodeType&&ie(e)&&(a=b,b="true"===ie(e),s=!0),n=ce(e.childNodes),b&&!s)for(r=0,o=h.length;o>r&&!O(h[r],t,e,e);r++);if(m.deep&&n.length){for(r=0,o=n.length;o>r;r++)i(n[r]);s&&(b=a)}}function o(n){var i;return le(u(n.parentNode).reverse(),function(n){var o;i||"_start"==n.id||"_end"==n.id||(o=w(n,e,t,r),o&&o.split!==!1&&(i=n))}),i}function s(e,n,r,i){var o,a,s,l,c,u;if(e){for(u=e.parentNode,o=n.parentNode;o&&o!=u;o=o.parentNode){for(a=q.clone(o,ee),c=0;c=0;o--){if(a=t[o].selector,!a||t[o].defaultBlock)return te;for(i=r.length-1;i>=0;i--)if(q.is(r[i],a))return te}return ee}function S(e,t,n){var r;return ne||(ne={},r={},a.on("NodeChange",function(e){var t=u(e.element),n={};t=i.grep(t,function(e){return 1==e.nodeType&&!e.getAttribute("data-mce-bogus")}),le(ne,function(e,i){le(t,function(o){return w(o,i,{},e.similar)?(r[i]||(le(e,function(e){e(!0,{node:o,format:i,parents:t})}),r[i]=e),n[i]=e,!1):void 0})}),le(r,function(i,o){n[o]||(delete r[o],le(i,function(n){n(!1,{node:e.element,format:o,parents:t})}))})})),le(e.split(","),function(e){ne[e]||(ne[e]=[],ne[e].similar=n),ne[e].push(t)}),this}function k(e){return o.getCssText(a,e)}function T(e,t){return R(e,t.inline)?te:R(e,t.block)?te:t.selector?1==e.nodeType&&q.is(e,t.selector):void 0}function R(e,t){return e=e||"",t=t||"",e=""+(e.nodeName||e),t=""+(t.nodeName||t),e.toLowerCase()==t.toLowerCase()}function A(e,t){return B(q.getStyle(e,t),t)}function B(e,t){return("color"==t||"backgroundColor"==t)&&(e=q.toHex(e)),"fontWeight"==t&&700==e&&(e="bold"),"fontFamily"==t&&(e=e.replace(/[\'\"]/g,"").replace(/,\s+/g,",")),""+e}function D(e,t){return"string"!=typeof e?e=e(t):t&&(e=e.replace(/%(\w+)/g,function(e,n){return t[n]||e})),e}function M(e){return e&&3===e.nodeType&&/^([\t \r\n]+|)$/.test(e.nodeValue)}function L(e,t,n){var r=q.create(t,n);return e.parentNode.insertBefore(r,e),r.appendChild(e),r}function H(t,n,r){function i(e){function t(e){return"BR"==e.nodeName&&e.getAttribute("data-mce-bogus")&&!e.nextSibling}var r,i,o,a,s;if(r=i=e?g:y,a=e?"previousSibling":"nextSibling",s=q.getRoot(),3==r.nodeType&&!M(r)&&(e?v>0:bo?n:o,-1===n||r||n++):(n=a.indexOf(" ",t),o=a.indexOf("\xa0",t),n=-1!==n&&(-1===o||o>n)?n:o),n}var s,l,c,u;if(3===t.nodeType){if(c=o(t,n),-1!==c)return{container:t,offset:c};u=t}for(s=new e(t,q.getParent(t,G)||a.getBody());l=s[i?"prev":"next"]();)if(3===l.nodeType){if(u=l,c=o(l),-1!==c)return{container:l,offset:c}}else if(G(l))break;return u?(n=i?0:u.length,{container:u,offset:n}):void 0}function d(e,r){var i,o,a,s;for(3==e.nodeType&&0===e.nodeValue.length&&e[r]&&(e=e[r]),i=u(e),o=0;oh?h:v],3==g.nodeType&&(v=0)),1==y.nodeType&&y.hasChildNodes()&&(h=y.childNodes.length-1,y=y.childNodes[b>h?h:b-1],3==y.nodeType&&(b=y.nodeValue.length)),g=l(g),y=l(y),(se(g.parentNode)||se(g))&&(g=se(g)?g:g.parentNode,g=g.nextSibling||g,3==g.nodeType&&(v=0)),(se(y.parentNode)||se(y))&&(y=se(y)?y:y.parentNode,y=y.previousSibling||y,3==y.nodeType&&(b=y.length)),n[0].inline&&(t.collapsed&&(m=c(g,v,!0),m&&(g=m.container,v=m.offset),m=c(y,b),m&&(y=m.container,b=m.offset)),p=o(y,b),p.node)){for(;p.node&&0===p.offset&&p.node.previousSibling;)p=o(p.node.previousSibling);p.node&&p.offset>0&&3===p.node.nodeType&&" "===p.node.nodeValue.charAt(p.offset-1)&&p.offset>1&&(y=p.node,y.splitText(p.offset-1))}return(n[0].inline||n[0].block_expand)&&(n[0].inline&&3==g.nodeType&&0!==v||(g=i(!0)),n[0].inline&&3==y.nodeType&&b!==y.nodeValue.length||(y=i())),n[0].selector&&n[0].expand!==ee&&!n[0].inline&&(g=d(g,"previousSibling"),y=d(y,"nextSibling")),(n[0].block||n[0].selector)&&(g=f(g,"previousSibling"),y=f(y,"nextSibling"),n[0].block&&(G(g)||(g=i(!0)),G(y)||(y=i()))),1==g.nodeType&&(v=J(g),g=g.parentNode),1==y.nodeType&&(b=J(y)+1,y=y.parentNode),{startContainer:g,startOffset:v,endContainer:y,endOffset:b}}function P(e,t){return t.links&&"A"==e.tagName}function O(e,t,n,r){var i,o,a;if(!T(n,e)&&!P(n,e))return ee;if("all"!=e.remove)for(le(e.styles,function(i,o){i=B(D(i,t),o),"number"==typeof o&&(o=i,r=0),(e.remove_similar||!r||R(A(r,o),i))&&q.setStyle(n,o,""),a=1}),a&&""===q.getAttrib(n,"style")&&(n.removeAttribute("style"),n.removeAttribute("data-mce-style")),le(e.attributes,function(e,i){var o;if(e=D(e,t),"number"==typeof i&&(i=e,r=0),!r||R(q.getAttrib(r,i),e)){if("class"==i&&(e=q.getAttrib(n,i),e&&(o="",le(e.split(/\s+/),function(e){/mce\-\w+/.test(e)&&(o+=(o?" ":"")+e)}),o)))return void q.setAttrib(n,i,o);"class"==i&&n.removeAttribute("className"),Z.test(i)&&n.removeAttribute("data-mce-"+i),n.removeAttribute(i)}}),le(e.classes,function(e){e=D(e,t),(!r||q.hasClass(r,e))&&q.removeClass(n,e)}),o=q.getAttribs(n),i=0;io?o:i]),3===r.nodeType&&n&&i>=r.nodeValue.length&&(r=new e(r,a.getBody()).next()||r),3!==r.nodeType||n||0!==i||(r=new e(r,a.getBody()).prev()||r),r}function V(t,n,r,i){function o(e){var t=q.create("span",{id:g,"data-mce-bogus":!0,style:v?"color:red":""});return e&&t.appendChild(a.getDoc().createTextNode(Q)),t}function l(e,t){for(;e;){if(3===e.nodeType&&e.nodeValue!==Q||e.childNodes.length>1)return!1;t&&1===e.nodeType&&t.push(e),e=e.firstChild}return!0}function c(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function u(t){var n;if(t)for(n=new e(t,t),t=n.current();t;t=n.next())if(3===t.nodeType)return t}function d(e,t){var n,r;if(e)r=j.getRng(!0),l(e)?(t!==!1&&(r.setStartBefore(e),r.setEndBefore(e)),q.remove(e)):(n=u(e),n.nodeValue.charAt(0)===Q&&(n.deleteData(0,1),r.startContainer==n&&r.startOffset>0&&r.setStart(n,r.startOffset-1),r.endContainer==n&&r.endOffset>0&&r.setEnd(n,r.endOffset-1)),q.remove(e,1)),j.setRng(r);else if(e=c(j.getStart()),!e)for(;e=q.get(g);)d(e,!1)}function f(){var e,t,i,a,s,l,d;e=j.getRng(!0),a=e.startOffset,l=e.startContainer,d=l.nodeValue,t=c(j.getStart()),t&&(i=u(t)),d&&a>0&&a=0;h--)u.appendChild(q.clone(f[h],!1)),u=u.firstChild;u.appendChild(q.doc.createTextNode(Q)),u=u.firstChild;var g=q.getParent(d,s);g&&q.isEmpty(g)?d.parentNode.replaceChild(m,d):q.insertAfter(m,d),j.setCursorLocation(u,1),q.isEmpty(d)&&q.remove(d)}}function m(){var e;e=c(j.getStart()),e&&!q.isEmpty(e)&&ue(e,function(e){1!=e.nodeType||e.id===g||q.isEmpty(e)||q.setAttrib(e,"data-mce-bogus",null)},"childNodes")}var g="_mce_caret",v=a.settings.caret_debug;a._hasCaretEvents||(ae=function(){var e=[],t;if(l(c(j.getStart()),e))for(t=e.length;t--;)q.setAttrib(e[t],"data-mce-bogus","1")},oe=function(e){var t=e.keyCode;d(),(8==t&&j.isCollapsed()||37==t||39==t)&&d(c(j.getStart())),m()},a.on("SetContent",function(e){e.selection&&m()}),a._hasCaretEvents=!0),"apply"==t?f():h()}function U(t){var n=t.startContainer,r=t.startOffset,i,o,a,s,l;if((t.startContainer!=t.endContainer||!c(t.startContainer.childNodes[t.startOffset]))&&(3==n.nodeType&&r>=n.nodeValue.length&&(r=J(n),n=n.parentNode,i=!0),1==n.nodeType))for(s=n.childNodes,n=s[Math.min(r,s.length-1)],o=new e(n,q.getParent(n,q.isBlock)),(r>s.length-1||i)&&o.next(),a=o.current();a;a=o.next())if(3==a.nodeType&&!M(a))return l=q.create("a",{"data-mce-bogus":"all"},Q),a.parentNode.insertBefore(l,a),t.setStart(a,0),j.setRng(t),void q.remove(l)}var $={},q=a.dom,j=a.selection,K=new t(q),Y=a.schema.isValidChild,G=q.isBlock,X=a.settings.forced_root_block,J=q.nodeIndex,Q="\ufeff",Z=/^(src|href|style)$/,ee=!1,te=!0,ne,re,ie=q.getContentEditable,oe,ae,se=n.isBookmarkNode,le=i.each,ce=i.grep,ue=i.walk,de=i.extend;de(this,{get:p,register:m,unregister:g,apply:b,remove:x,toggle:C,match:_,matchAll:E,matchNode:w,canApply:N,formatChanged:S,getCssText:k}),f(),h(),a.on("BeforeGetContent",function(e){ae&&"raw"!=e.format&&ae()}),a.on("mouseup keydown",function(e){oe&&oe(e)})}}),r(F,[D,u,f,S],function(e,t,n,r){var i=n.trim,o;return o=new RegExp(["]+data-mce-bogus[^>]+>[\u200b\ufeff]+<\\/span>",'\\s?data-mce-selected="[^"]+"'].join("|"),"gi"),function(e){function n(){var t=e.getContent({format:"raw",no_events:1}),n=/<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g,a,s,l,c,u,d=e.schema;for(t=t.replace(o,""),u=d.getShortEndedElements();c=n.exec(t);)s=n.lastIndex,l=c[0].length,a=u[c[1]]?s:r.findEndTag(d,t,s),t=t.substring(0,s-l)+t.substring(a),n.lastIndex=s-l;return i(t)}function a(t){e.isNotDirty=!t}function s(e){l.typing=!1,l.add({},e)}var l=this,c=0,u=[],d,f,h=0;return e.on("init",function(){l.add()}),e.on("BeforeExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&l.beforeChange()}),e.on("ExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&s(e)}),e.on("ObjectResizeStart Cut",function(){l.beforeChange()}),e.on("SaveContent ObjectResized blur",s),e.on("DragEnd",s),e.on("KeyUp",function(r){var i=r.keyCode;r.isDefaultPrevented()||((i>=33&&36>=i||i>=37&&40>=i||45==i||13==i||r.ctrlKey)&&(s(),e.nodeChanged()),(46==i||8==i||t.mac&&(91==i||93==i))&&e.nodeChanged(),f&&l.typing&&(e.isDirty()||(a(u[0]&&n()!=u[0].content),e.isNotDirty||e.fire("change",{level:u[0],lastLevel:null})),e.fire("TypingUndo"),f=!1,e.nodeChanged()))}),e.on("KeyDown",function(e){var t=e.keyCode;if(!e.isDefaultPrevented()){if(t>=33&&36>=t||t>=37&&40>=t||45==t)return void(l.typing&&s(e));var n=e.ctrlKey&&!e.altKey||e.metaKey;!(16>t||t>20)||224==t||91==t||l.typing||n||(l.beforeChange(),l.typing=!0,l.add({},e),f=!0)}}),e.on("MouseDown",function(e){l.typing&&s(e)}),e.addShortcut("meta+z","","Undo"),e.addShortcut("meta+y,meta+shift+z","","Redo"),e.on("AddUndo Undo Redo ClearUndos",function(t){t.isDefaultPrevented()||e.nodeChanged()}),l={data:u,typing:!1,beforeChange:function(){h||(d=e.selection.getBookmark(2,!0))},add:function(t,r){var i,o=e.settings,s;if(t=t||{},t.content=n(),h||e.removed)return null;if(s=u[c],e.fire("BeforeAddUndo",{level:t,lastLevel:s,originalEvent:r}).isDefaultPrevented())return null;if(s&&s.content==t.content)return null;if(u[c]&&(u[c].beforeBookmark=d),o.custom_undo_redo_levels&&u.length>o.custom_undo_redo_levels){for(i=0;i0&&(a(!0),e.fire("change",l)),t},undo:function(){var t;return l.typing&&(l.add(),l.typing=!1),c>0&&(t=u[--c],0===c&&a(!1),e.setContent(t.content,{format:"raw"}),e.selection.moveToBookmark(t.beforeBookmark),e.fire("undo",{level:t})),t},redo:function(){var t;return c0||l.typing&&u[0]&&n()!=u[0].content},hasRedo:function(){return cL)&&(u=a.create("br"),t.parentNode.insertBefore(u,t)),l.setStartBefore(t),l.setEndBefore(t)):(l.setStartAfter(t),l.setEndAfter(t)):(l.setStart(t,0),l.setEnd(t,0));s.setRng(l),a.remove(u),s.scrollIntoView(t)}}function v(e){var t=l.forced_root_block;t&&t.toLowerCase()===e.tagName.toLowerCase()&&a.setAttribs(e,l.forced_root_block_attrs)}function y(e){e.innerHTML=r?"":'
'}function b(e){var t=B,n,i,o,s=u.getTextInlineElements();if(e||"TABLE"==F?(n=a.create(e||W),v(n)):n=M.cloneNode(!1),o=n,l.keep_styles!==!1)do if(s[t.nodeName]){if("_mce_caret"==t.id)continue;i=t.cloneNode(!1),a.setAttrib(i,"id",""),n.hasChildNodes()?(i.appendChild(n.firstChild),n.appendChild(i)):(o=i,n.appendChild(i))}while(t=t.parentNode);return r||(o.innerHTML='
'),n}function x(t){var n,r,i;if(3==B.nodeType&&(t?D>0:DB.childNodes.length-1,B=B.childNodes[Math.min(D,B.childNodes.length-1)]||B,D=V&&3==B.nodeType?B.nodeValue.length:0),A=N(B)){if(c.beforeChange(),!a.isBlock(A)&&A!=a.getRoot())return void((!W||H)&&_());if((W&&!H||!W&&H)&&(B=C(B,D)),M=a.getParent(B,a.isBlock),I=M?a.getParent(M.parentNode,a.isBlock):null,F=M?M.nodeName.toUpperCase():"",z=I?I.nodeName.toUpperCase():"","LI"!=z||o.ctrlKey||(M=I,F=z),/^(LI|DT|DD)$/.test(F)){if(!W&&H)return void _();if(a.isEmpty(M))return void w()}if("PRE"==F&&l.br_in_pre!==!1){if(!H)return void _()}else if(!W&&!H&&"LI"!=F||W&&H)return void _();W&&M===i.getBody()||(W=W||"P",x()?k():x(!0)?(P=M.parentNode.insertBefore(b(),M),p(P),g(M)):(R=T.cloneRange(),R.setEndAfter(M),O=R.extractContents(),E(O),P=O.firstChild,a.insertAfter(O,M),m(P),S(M),a.isEmpty(M)&&y(M),a.isEmpty(P)?(a.remove(P),k()):g(P)),a.setAttrib(P,"id",""),i.fire("NewBlock",{newBlock:P}),c.add())}}}var a=i.dom,s=i.selection,l=i.settings,c=i.undoManager,u=i.schema,d=u.getNonEmptyElements(),f=u.getMoveCaretBeforeOnEnterElements(); -i.on("keydown",function(e){13==e.keyCode&&o(e)!==!1&&e.preventDefault()})}}),r(W,[],function(){return function(e){function t(){var t=i.getStart(),s=e.getBody(),l,c,u,d,f,h,p,m=-16777215,g,v,y,b,x;if(x=n.forced_root_block,t&&1===t.nodeType&&x){for(;t&&t!=s;){if(a[t.nodeName])return;t=t.parentNode}if(l=i.getRng(),l.setStart){c=l.startContainer,u=l.startOffset,d=l.endContainer,f=l.endOffset;try{v=e.getDoc().activeElement===s}catch(C){}}else l.item&&(t=l.item(0),l=e.getDoc().body.createTextRange(),l.moveToElementText(t)),v=l.parentElement().ownerDocument===e.getDoc(),y=l.duplicate(),y.collapse(!0),u=-1*y.move("character",m),y.collapsed||(y=l.duplicate(),y.collapse(!1),f=-1*y.move("character",m)-u);for(t=s.firstChild,b=s.nodeName.toLowerCase();t;)if((3===t.nodeType||1==t.nodeType&&!a[t.nodeName])&&o.isValidChild(b,x.toLowerCase())){if(3===t.nodeType&&0===t.nodeValue.length){p=t,t=t.nextSibling,r.remove(p);continue}h||(h=r.create(x,e.settings.forced_root_block_attrs),t.parentNode.insertBefore(h,t),g=!0),p=t,t=t.nextSibling,h.appendChild(p)}else h=null,t=t.nextSibling;if(g&&v){if(l.setStart)l.setStart(c,u),l.setEnd(d,f),i.setRng(l);else try{l=e.getDoc().body.createTextRange(),l.moveToElementText(s),l.collapse(!0),l.moveStart("character",u),f>0&&l.moveEnd("character",f),l.select()}catch(C){}e.nodeChanged()}}}var n=e.settings,r=e.dom,i=e.selection,o=e.schema,a=o.getBlockElements();n.forced_root_block&&e.on("NodeChange",t)}}),r(V,[R,u,f,P,w,m],function(e,n,r,i,o,a){var s=r.each,l=r.extend,c=r.map,u=r.inArray,d=r.explode,f=n.gecko,h=n.ie,p=n.ie&&n.ie<11,m=!0,g=!1;return function(r){function v(e,t,n,i){var o,a,c=0;if(/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(e)||i&&i.skip_focus||r.focus(),i=l({},i),i=r.fire("BeforeExecCommand",{command:e,ui:t,value:n}),i.isDefaultPrevented())return!1;if(a=e.toLowerCase(),o=L.exec[a])return o(a,t,n),r.fire("ExecCommand",{command:e,ui:t,value:n}),!0;if(s(r.plugins,function(i){return i.execCommand&&i.execCommand(e,t,n)?(r.fire("ExecCommand",{command:e,ui:t,value:n}),c=!0,!1):void 0}),c)return c;if(r.theme&&r.theme.execCommand&&r.theme.execCommand(e,t,n))return r.fire("ExecCommand",{command:e,ui:t,value:n}),!0;try{c=r.getDoc().execCommand(e,t,n)}catch(u){}return c?(r.fire("ExecCommand",{command:e,ui:t,value:n}),!0):!1}function y(e){var t;if(!r._isHidden()){if(e=e.toLowerCase(),t=L.state[e])return t(e);try{return r.getDoc().queryCommandState(e)}catch(n){}return!1}}function b(e){var t;if(!r._isHidden()){if(e=e.toLowerCase(),t=L.value[e])return t(e);try{return r.getDoc().queryCommandValue(e)}catch(n){}}}function x(e,t){t=t||"exec",s(e,function(e,n){s(n.toLowerCase().split(","),function(n){L[t][n]=e})})}function C(e,t,n){e=e.toLowerCase(),L.exec[e]=function(e,i,o,a){return t.call(n||r,i,o,a)}}function w(e){if(e=e.toLowerCase(),L.exec[e])return!0;try{return r.getDoc().queryCommandSupported(e)}catch(t){}return!1}function _(e,t,n){e=e.toLowerCase(),L.state[e]=function(){return t.call(n||r)}}function E(e,t,n){e=e.toLowerCase(),L.value[e]=function(){return t.call(n||r)}}function N(e){return e=e.toLowerCase(),!!L.exec[e]}function S(e,n,i){return n===t&&(n=g),i===t&&(i=null),r.getDoc().execCommand(e,n,i)}function k(e){return M.match(e)}function T(e,n){M.toggle(e,n?{value:n}:t),r.nodeChanged()}function R(e){P=D.getBookmark(e)}function A(){D.moveToBookmark(P)}var B,D,M,L={state:{},exec:{},value:{}},H=r.settings,P;r.on("PreInit",function(){B=r.dom,D=r.selection,H=r.settings,M=r.formatter}),l(this,{execCommand:v,queryCommandState:y,queryCommandValue:b,queryCommandSupported:w,addCommands:x,addCommand:C,addQueryStateHandler:_,addQueryValueHandler:E,hasCustomCommand:N}),x({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){r.undoManager.add()},"Cut,Copy,Paste":function(e){var t=r.getDoc(),i;try{S(e)}catch(o){i=m}if(i||!t.queryCommandSupported(e)){var a=r.translate("Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.");n.mac&&(a=a.replace(/Ctrl\+/g,"\u2318+")),r.windowManager.alert(a)}},unlink:function(){if(D.isCollapsed()){var e=D.getNode();return void("A"==e.tagName&&r.dom.remove(e,!0))}M.remove("link")},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone":function(e){var t=e.substring(7);"full"==t&&(t="justify"),s("left,center,right,justify".split(","),function(e){t!=e&&M.remove("align"+e)}),"none"!=t&&(T("align"+t),v("mceRepaint"))},"InsertUnorderedList,InsertOrderedList":function(e){var t,n;S(e),t=B.getParent(D.getNode(),"ol,ul"),t&&(n=t.parentNode,/^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName)&&(R(),B.split(n,t),A()))},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){T(e)},"ForeColor,HiliteColor,FontName":function(e,t,n){T(e,n)},FontSize:function(e,t,n){var r,i;n>=1&&7>=n&&(i=d(H.font_size_style_values),r=d(H.font_size_classes),n=r?r[n-1]||n:i[n-1]||n),T(e,n)},RemoveFormat:function(e){M.remove(e)},mceBlockQuote:function(){T("blockquote")},FormatBlock:function(e,t,n){return T(n||"p")},mceCleanup:function(){var e=D.getBookmark();r.setContent(r.getContent({cleanup:m}),{cleanup:m}),D.moveToBookmark(e)},mceRemoveNode:function(e,t,n){var i=n||D.getNode();i!=r.getBody()&&(R(),r.dom.remove(i,m),A())},mceSelectNodeDepth:function(e,t,n){var i=0;B.getParent(D.getNode(),function(e){return 1==e.nodeType&&i++==n?(D.select(e),g):void 0},r.getBody())},mceSelectNode:function(e,t,n){D.select(n)},mceInsertContent:function(t,n,o){function a(e){function t(e){return r[e]&&3==r[e].nodeType}var n,r,i;return n=D.getRng(!0),r=n.startContainer,i=n.startOffset,3==r.nodeType&&(i>0?e=e.replace(/^ /," "):t("previousSibling")||(e=e.replace(/^ /," ")),i|)$/," "):t("nextSibling")||(e=e.replace(/( | )(
|)$/," "))),e}function l(){var e,t,n;e=D.getRng(!0),t=e.startContainer,n=e.startOffset,3==t.nodeType&&e.collapsed&&("\xa0"===t.data[n]?(t.deleteData(n,1),/[\u00a0| ]$/.test(o)||(o+=" ")):"\xa0"===t.data[n-1]&&(t.deleteData(n-1,1),/[\u00a0| ]$/.test(o)||(o=" "+o)))}function c(e){if(_)for(x=e.firstChild;x;x=x.walk(!0))N[x.name]&&x.attr("data-mce-new","true")}function u(){if(_){var e=r.getBody(),t=new i(B);s(B.select("*[data-mce-new]"),function(n){n.removeAttribute("data-mce-new");for(var r=n.parentNode;r&&r!=e;r=r.parentNode)t.compare(r,n)&&B.remove(n,!0)})}}var d,f,p,m,g,v,y,b,x,C,w,_,E,N=r.schema.getTextInlineElements();"string"!=typeof o&&(_=o.merge,E=o.data,o=o.content),/^ | $/.test(o)&&(o=a(o)),d=r.parser,f=new e({},r.schema),w='​',v={content:o,format:"html",selection:!0},r.fire("BeforeSetContent",v),o=v.content,-1==o.indexOf("{$caret}")&&(o+="{$caret}"),o=o.replace(/\{\$caret\}/,w),b=D.getRng();var S=b.startContainer||(b.parentElement?b.parentElement():null),k=r.getBody();S===k&&D.isCollapsed()&&B.isBlock(k.firstChild)&&B.isEmpty(k.firstChild)&&(b=B.createRng(),b.setStart(k.firstChild,0),b.setEnd(k.firstChild,0),D.setRng(b)),D.isCollapsed()||(r.getDoc().execCommand("Delete",!1,null),l()),p=D.getNode();var T={context:p.nodeName.toLowerCase(),data:E};if(g=d.parse(o,T),c(g),x=g.lastChild,"mce_marker"==x.attr("id"))for(y=x,x=x.prev;x;x=x.walk(!0))if(3==x.type||!B.isBlock(x.name)){r.schema.isValidChild(x.parent.name,"span")&&x.parent.insert(y,x,"br"===x.name);break}if(T.invalid){for(D.setContent(w),p=D.getNode(),m=r.getBody(),9==p.nodeType?p=x=m:x=p;x!==m;)p=x,x=x.parentNode;o=p==m?m.innerHTML:B.getOuterHTML(p),o=f.serialize(d.parse(o.replace(//i,function(){return f.serialize(g)}))),p==m?B.setHTML(m,o):B.setOuterHTML(p,o)}else o=f.serialize(g),x=p.firstChild,C=p.lastChild,!x||x===C&&"BR"===x.nodeName?B.setHTML(p,o):D.setContent(o);u(),y=B.get("mce_marker"),D.scrollIntoView(y),b=B.createRng(),x=y.previousSibling,x&&3==x.nodeType?(b.setStart(x,x.nodeValue.length),h||(C=y.nextSibling,C&&3==C.nodeType&&(x.appendData(C.data),C.parentNode.removeChild(C)))):(b.setStartBefore(y),b.setEndBefore(y)),B.remove(y),D.setRng(b),r.fire("SetContent",v),r.addVisual()},mceInsertRawHTML:function(e,t,n){D.setContent("tiny_mce_marker"),r.setContent(r.getContent().replace(/tiny_mce_marker/g,function(){return n}))},mceToggleFormat:function(e,t,n){T(n)},mceSetContent:function(e,t,n){r.setContent(n)},"Indent,Outdent":function(e){var t,n,i;t=H.indentation,n=/[a-z%]+$/i.exec(t),t=parseInt(t,10),y("InsertUnorderedList")||y("InsertOrderedList")?S(e):(H.forced_root_block||B.getParent(D.getNode(),B.isBlock)||M.apply("div"),s(D.getSelectedBlocks(),function(o){if("LI"!=o.nodeName){var a=r.getParam("indent_use_margin",!1)?"margin":"padding";a+="rtl"==B.getStyle(o,"direction",!0)?"Right":"Left","outdent"==e?(i=Math.max(0,parseInt(o.style[a]||0,10)-t),B.setStyle(o,a,i?i+n:"")):(i=parseInt(o.style[a]||0,10)+t+n,B.setStyle(o,a,i))}}))},mceRepaint:function(){if(f)try{R(m),D.getSel()&&D.getSel().selectAllChildren(r.getBody()),D.collapse(m),A()}catch(e){}},InsertHorizontalRule:function(){r.execCommand("mceInsertContent",!1,"
")},mceToggleVisualAid:function(){r.hasVisual=!r.hasVisual,r.addVisual()},mceReplaceContent:function(e,t,n){r.execCommand("mceInsertContent",!1,n.replace(/\{\$selection\}/g,D.getContent({format:"text"})))},mceInsertLink:function(e,t,n){var r;"string"==typeof n&&(n={href:n}),r=B.getParent(D.getNode(),"a"),n.href=n.href.replace(" ","%20"),r&&n.href||M.remove("link"),n.href&&M.apply("link",n,r)},selectAll:function(){var e=B.getRoot(),t;D.getRng().setStart?(t=B.createRng(),t.setStart(e,0),t.setEnd(e,e.childNodes.length),D.setRng(t)):(t=D.getRng(),t.item||(t.moveToElementText(e),t.select()))},"delete":function(){S("Delete");var e=r.getBody();B.isEmpty(e)&&(r.setContent(""),e.firstChild&&B.isBlock(e.firstChild)?r.selection.setCursorLocation(e.firstChild,0):r.selection.setCursorLocation(e,0))},mceNewDocument:function(){r.setContent("")},InsertLineBreak:function(e,t,n){function i(){for(var e=new a(h,v),t,n=r.schema.getNonEmptyElements();t=e.next();)if(n[t.nodeName.toLowerCase()]||t.length>0)return!0}var s=n,l,c,u,d=D.getRng(!0);new o(B).normalize(d);var f=d.startOffset,h=d.startContainer;if(1==h.nodeType&&h.hasChildNodes()){var g=f>h.childNodes.length-1;h=h.childNodes[Math.min(f,h.childNodes.length-1)]||h,f=g&&3==h.nodeType?h.nodeValue.length:0}var v=B.getParent(h,B.isBlock),y=v?v.nodeName.toUpperCase():"",b=v?B.getParent(v.parentNode,B.isBlock):null,x=b?b.nodeName.toUpperCase():"",C=s&&s.ctrlKey;"LI"!=x||C||(v=b,y=x),h&&3==h.nodeType&&f>=h.nodeValue.length&&(p||i()||(l=B.create("br"),d.insertNode(l),d.setStartAfter(l),d.setEndAfter(l),c=!0)),l=B.create("br"),d.insertNode(l);var w=B.doc.documentMode;return p&&"PRE"==y&&(!w||8>w)&&l.parentNode.insertBefore(B.doc.createTextNode("\r"),l),u=B.create("span",{}," "),l.parentNode.insertBefore(u,l),D.scrollIntoView(u),B.remove(u),c?(d.setStartBefore(l),d.setEndBefore(l)):(d.setStartAfter(l),d.setEndAfter(l)),D.setRng(d),r.undoManager.add(),m}}),x({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t="align"+e.substring(7),n=D.isCollapsed()?[B.getParent(D.getNode(),B.isBlock)]:D.getSelectedBlocks(),r=c(n,function(e){return!!M.matchNode(e,t)});return-1!==u(r,m)},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){return k(e)},mceBlockQuote:function(){return k("blockquote")},Outdent:function(){var e;if(H.inline_styles){if((e=B.getParent(D.getStart(),B.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return m;if((e=B.getParent(D.getEnd(),B.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return m}return y("InsertUnorderedList")||y("InsertOrderedList")||!H.inline_styles&&!!B.getParent(D.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(e){var t=B.getParent(D.getNode(),"ul,ol");return t&&("insertunorderedlist"===e&&"UL"===t.tagName||"insertorderedlist"===e&&"OL"===t.tagName)}},"state"),x({"FontSize,FontName":function(e){var t=0,n;return(n=B.getParent(D.getNode(),"span"))&&(t="fontsize"==e?n.style.fontSize:n.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()),t}},"value"),x({Undo:function(){r.undoManager.undo()},Redo:function(){r.undoManager.redo()}})}}),r(U,[f],function(e){function t(e,o){var a=this,s,l;if(e=r(e),o=a.settings=o||{},s=o.base_uri,/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e))return void(a.source=e);var c=0===e.indexOf("//");0!==e.indexOf("/")||c||(e=(s?s.protocol||"http":"http")+"://mce_host"+e),/^[\w\-]*:?\/\//.test(e)||(l=o.base_uri?o.base_uri.path:new t(location.href).directory,""===o.base_uri.protocol?e="//mce_host"+a.toAbsPath(l,e):(e=/([^#?]*)([#?]?.*)/.exec(e),e=(s&&s.protocol||"http")+"://mce_host"+a.toAbsPath(l,e[1])+e[2])),e=e.replace(/@@/g,"(mce_at)"),e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e),n(i,function(t,n){var r=e[n];r&&(r=r.replace(/\(mce_at\)/g,"@@")),a[t]=r}),s&&(a.protocol||(a.protocol=s.protocol),a.userInfo||(a.userInfo=s.userInfo),a.port||"mce_host"!==a.host||(a.port=s.port),a.host&&"mce_host"!==a.host||(a.host=s.host),a.source=""),c&&(a.protocol="")}var n=e.each,r=e.trim,i="source protocol authority userInfo user password host port relative path directory file query anchor".split(" "),o={ftp:21,http:80,https:443,mailto:25};return t.prototype={setPath:function(e){var t=this;e=/^(.*?)\/?(\w+)?$/.exec(e),t.path=e[0],t.directory=e[1],t.file=e[2],t.source="",t.getURI()},toRelative:function(e){var n=this,r;if("./"===e)return e;if(e=new t(e,{base_uri:n}),"mce_host"!=e.host&&n.host!=e.host&&e.host||n.port!=e.port||n.protocol!=e.protocol&&""!==e.protocol)return e.getURI();var i=n.getURI(),o=e.getURI();return i==o||"/"==i.charAt(i.length-1)&&i.substr(0,i.length-1)==o?i:(r=n.toRelPath(n.path,e.path),e.query&&(r+="?"+e.query),e.anchor&&(r+="#"+e.anchor),r)},toAbsolute:function(e,n){return e=new t(e,{base_uri:this}),e.getURI(n&&this.isSameOrigin(e))},isSameOrigin:function(e){if(this.host==e.host&&this.protocol==e.protocol){if(this.port==e.port)return!0;var t=o[this.protocol];if(t&&(this.port||t)==(e.port||t))return!0}return!1},toRelPath:function(e,t){var n,r=0,i="",o,a;if(e=e.substring(0,e.lastIndexOf("/")),e=e.split("/"),n=t.split("/"),e.length>=n.length)for(o=0,a=e.length;a>o;o++)if(o>=n.length||e[o]!=n[o]){r=o+1;break}if(e.lengtho;o++)if(o>=e.length||e[o]!=n[o]){r=o+1;break}if(1===r)return t;for(o=0,a=e.length-(r-1);a>o;o++)i+="../";for(o=r-1,a=n.length;a>o;o++)i+=o!=r-1?"/"+n[o]:n[o];return i},toAbsPath:function(e,t){var r,i=0,o=[],a,s;for(a=/\/$/.test(t)?"/":"",e=e.split("/"),t=t.split("/"),n(e,function(e){e&&o.push(e)}),e=o,r=t.length-1,o=[];r>=0;r--)0!==t[r].length&&"."!==t[r]&&(".."!==t[r]?i>0?i--:o.push(t[r]):i++);return r=e.length-i,s=0>=r?o.reverse().join("/"):e.slice(0,r).join("/")+"/"+o.reverse().join("/"),0!==s.indexOf("/")&&(s="/"+s),a&&s.lastIndexOf("/")!==s.length-1&&(s+=a),s},getURI:function(e){var t,n=this;return(!n.source||e)&&(t="",e||(t+=n.protocol?n.protocol+"://":"//",n.userInfo&&(t+=n.userInfo+"@"),n.host&&(t+=n.host),n.port&&(t+=":"+n.port)),n.path&&(t+=n.path),n.query&&(t+="?"+n.query),n.anchor&&(t+="#"+n.anchor),n.source=t),n.source}},t.parseDataUri=function(e){var t,n;return e=decodeURIComponent(e).split(","),n=/data:([^;]+)/.exec(e[0]),n&&(t=n[1]),{type:t,data:e[1]}},t}),r($,[f],function(e){function t(){}var n=e.each,r=e.extend,i,o;return t.extend=i=function(e){function t(){var e,t,n,r=this;if(!o&&(r.init&&r.init.apply(r,arguments),t=r.Mixins))for(e=t.length;e--;)n=t[e],n.init&&n.init.apply(r,arguments)}function a(){return this}function s(e,t){return function(){var n=this,r=n._super,i;return n._super=c[e],i=t.apply(n,arguments),n._super=r,i}}var l=this,c=l.prototype,u,d,f;o=!0,u=new l,o=!1,e.Mixins&&(n(e.Mixins,function(t){t=t;for(var n in t)"init"!==n&&(e[n]=t[n])}),c.Mixins&&(e.Mixins=c.Mixins.concat(e.Mixins))),e.Methods&&n(e.Methods.split(","),function(t){e[t]=a}),e.Properties&&n(e.Properties.split(","),function(t){var n="_"+t;e[t]=function(e){var t=this,r;return e!==r?(t[n]=e,t):t[n]}}),e.Statics&&n(e.Statics,function(e,n){t[n]=e}),e.Defaults&&c.Defaults&&(e.Defaults=r({},c.Defaults,e.Defaults));for(d in e)f=e[d],"function"==typeof f&&c[d]?u[d]=s(d,f):u[d]=f;return t.prototype=u,t.constructor=t,t.extend=i,t},t}),r(q,[f],function(e){function t(t){function n(){return!1}function r(){return!0}function i(e,i){var o,s,l,c;if(e=e.toLowerCase(),i=i||{},i.type=e,i.target||(i.target=u),i.preventDefault||(i.preventDefault=function(){i.isDefaultPrevented=r},i.stopPropagation=function(){i.isPropagationStopped=r},i.stopImmediatePropagation=function(){i.isImmediatePropagationStopped=r},i.isDefaultPrevented=n,i.isPropagationStopped=n,i.isImmediatePropagationStopped=n),t.beforeFire&&t.beforeFire(i),o=d[e])for(s=0,l=o.length;l>s;s++){if(c=o[s],c.once&&a(e,c.func),i.isImmediatePropagationStopped())return i.stopPropagation(),i;if(c.func.call(u,i)===!1)return i.preventDefault(),i}return i}function o(t,r,i,o){var a,s,l;if(r===!1&&(r=n),r)for(r={func:r},o&&e.extend(r,o),s=t.toLowerCase().split(" "),l=s.length;l--;)t=s[l],a=d[t],a||(a=d[t]=[],f(t,!0)),i?a.unshift(r):a.push(r);return c}function a(e,t){var n,r,i,o,a;if(e)for(o=e.toLowerCase().split(" "),n=o.length;n--;){if(e=o[n],r=d[e],!e){for(i in d)f(i,!1),delete d[i];return c}if(r){if(t)for(a=r.length;a--;)r[a].func===t&&(r=r.slice(0,a).concat(r.slice(a+1)),d[e]=r);else r.length=0;r.length||(f(e,!1),delete d[e])}}else{for(e in d)f(e,!1);d={}}return c}function s(e,t,n){return o(e,t,n,{once:!0})}function l(e){return e=e.toLowerCase(),!(!d[e]||0===d[e].length)}var c=this,u,d={},f;t=t||{},u=t.scope||c,f=t.toggleEvent||n,c.fire=i,c.on=o,c.off=a,c.once=s,c.has=l}var n=e.makeMap("focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover draggesture dragdrop drop drag submit compositionstart compositionend compositionupdate touchstart touchend"," ");return t.isNative=function(e){return!!n[e.toLowerCase()]},t}),r(j,[],function(){function e(e){this.create=e.create}return e.create=function(t,n){return new e({create:function(e,r){function i(t){e.set(r,t.value)}function o(e){t.set(n,e.value)}var a;return e.on("change:"+r,o),t.on("change:"+n,i),a=e._bindings,a||(a=e._bindings=[],e.on("destroy",function(){for(var e=a.length;e--;)a[e]()})),a.push(function(){t.off("change:"+n,i)}),t.get(n)}})},e}),r(K,[q],function(e){function t(t){return t._eventDispatcher||(t._eventDispatcher=new e({scope:t,toggleEvent:function(n,r){e.isNative(n)&&t.toggleNativeEvent&&t.toggleNativeEvent(n,r)}})),t._eventDispatcher}return{fire:function(e,n,r){var i=this;if(i.removed&&"remove"!==e)return n;if(n=t(i).fire(e,n,r),r!==!1&&i.parent)for(var o=i.parent();o&&!n.isPropagationStopped();)o.fire(e,n,!1),o=o.parent();return n},on:function(e,n,r){return t(this).on(e,n,r)},off:function(e,n){return t(this).off(e,n)},once:function(e,n){return t(this).once(e,n)},hasEventListeners:function(e){return t(this).has(e)}}}),r(Y,[j,K,$,f],function(e,t,n,r){function i(e){return e.nodeType>0}function o(e,t){var n,a;if(e===t)return!0;if(null===e||null===t)return e===t;if("object"!=typeof e||"object"!=typeof t)return e===t;if(r.isArray(t)){if(e.length!==t.length)return!1;for(n=e.length;n--;)if(!o(e[n],t[n]))return!1}if(i(e)||i(t))return e===t;a={};for(n in t){if(!o(e[n],t[n]))return!1;a[n]=!0}for(n in e)if(!a[n]&&!o(e[n],t[n]))return!1;return!0}return n.extend({Mixins:[t],init:function(t){var n,r;t=t||{};for(n in t)r=t[n],r instanceof e&&(t[n]=r.create(this,n));this.data=t},set:function(t,n){var r,i,a=this.data[t];if(n instanceof e&&(n=n.create(this,t)),"object"==typeof t){for(r in t)this.set(r,t[r]);return this}return o(a,n)||(this.data[t]=n,i={target:this,name:t,value:n,oldValue:a},this.fire("change:"+t,i),this.fire("change",i)),this},get:function(e){return this.data[e]},has:function(e){return e in this.data},bind:function(t){return e.create(this,t)},destroy:function(){this.fire("destroy")}})}),r(G,[$],function(e){function t(e){for(var t=[],n=e.length,r;n--;)r=e[n],r.__checked||(t.push(r),r.__checked=1);for(n=t.length;n--;)delete t[n].__checked;return t}var n=/^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,r=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,i=/^\s*|\s*$/g,o,a=e.extend({init:function(e){function t(e){return e?(e=e.toLowerCase(),function(t){return"*"===e||t.type===e}):void 0}function o(e){return e?function(t){return t._name===e}:void 0}function a(e){return e?(e=e.split("."),function(t){for(var n=e.length;n--;)if(!t.classes.contains(e[n]))return!1;return!0}):void 0}function s(e,t,n){return e?function(r){var i=r[e]?r[e]():"";return t?"="===t?i===n:"*="===t?i.indexOf(n)>=0:"~="===t?(" "+i+" ").indexOf(" "+n+" ")>=0:"!="===t?i!=n:"^="===t?0===i.indexOf(n):"$="===t?i.substr(i.length-n.length)===n:!1:!!n}:void 0}function l(e){var t;return e?(e=/(?:not\((.+)\))|(.+)/i.exec(e),e[1]?(t=u(e[1],[]),function(e){return!d(e,t)}):(e=e[2],function(t,n,r){return"first"===e?0===n:"last"===e?n===r-1:"even"===e?n%2===0:"odd"===e?n%2===1:t[e]?t[e]():!1})):void 0}function c(e,r,c){function u(e){e&&r.push(e)}var d;return d=n.exec(e.replace(i,"")),u(t(d[1])),u(o(d[2])),u(a(d[3])),u(s(d[4],d[5],d[6])),u(l(d[7])),r.psuedo=!!d[7],r.direct=c,r}function u(e,t){var n=[],i,o,a;do if(r.exec(""),o=r.exec(e),o&&(e=o[3],n.push(o[1]),o[2])){i=o[3];break}while(o);for(i&&u(i,t),e=[],a=0;a"!=n[a]&&e.push(c(n[a],[],">"===n[a-1]));return t.push(e),t}var d=this.match;this._selectors=u(e,[])},match:function(e,t){var n,r,i,o,a,s,l,c,u,d,f,h,p;for(t=t||this._selectors,n=0,r=t.length;r>n;n++){for(a=t[n],o=a.length,p=e,h=0,i=o-1;i>=0;i--)for(c=a[i];p;){if(c.psuedo)for(f=p.parent().items(),u=d=f.length;u--&&f[u]!==p;);for(s=0,l=c.length;l>s;s++)if(!c[s](p,u,d)){s=l+1;break}if(s===l){h++;break}if(i===o-1)break;p=p.parent()}if(h===o)return!0}return!1},find:function(e){function n(e,t,i){var o,a,s,l,c,u=t[i];for(o=0,a=e.length;a>o;o++){for(c=e[o],s=0,l=u.length;l>s;s++)if(!u[s](c,o,a)){s=l+1;break}if(s===l)i==t.length-1?r.push(c):c.items&&n(c.items(),t,i+1);else if(u.direct)return;c.items&&n(c.items(),t,i)}}var r=[],i,s,l=this._selectors;if(e.items){for(i=0,s=l.length;s>i;i++)n(e.items(),l[i],0);s>1&&(r=t(r))}return o||(o=a.Collection),new o(r)}});return a}),r(X,[f,G,$],function(e,t,n){var r,i,o=Array.prototype.push,a=Array.prototype.slice;return i={length:0,init:function(e){e&&this.add(e)},add:function(t){var n=this;return e.isArray(t)?o.apply(n,t):t instanceof r?n.add(t.toArray()):o.call(n,t),n},set:function(e){var t=this,n=t.length,r;for(t.length=0,t.add(e),r=t.length;n>r;r++)delete t[r];return t},filter:function(e){var n=this,i,o,a=[],s,l;for("string"==typeof e?(e=new t(e),l=function(t){return e.match(t)}):l=e,i=0,o=n.length;o>i;i++)s=n[i],l(s)&&a.push(s);return new r(a)},slice:function(){return new r(a.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},each:function(t){return e.each(this,t),this},toArray:function(){return e.toArray(this)},indexOf:function(e){for(var t=this,n=t.length;n--&&t[n]!==e;);return n},reverse:function(){return new r(e.toArray(this).reverse())},hasClass:function(e){return this[0]?this[0].classes.contains(e):!1},prop:function(e,t){var n=this,r,i;return t!==r?(n.each(function(n){n[e]&&n[e](t)}),n):(i=n[0],i&&i[e]?i[e]():void 0)},exec:function(t){var n=this,r=e.toArray(arguments).slice(1);return n.each(function(e){e[t]&&e[t].apply(e,r)}),n},remove:function(){for(var e=this.length;e--;)this[e].remove();return this},addClass:function(e){return this.each(function(t){t.classes.add(e)})},removeClass:function(e){return this.each(function(t){t.classes.remove(e)})}},e.each("fire on off show hide append prepend before after reflow".split(" "),function(t){i[t]=function(){var n=e.toArray(arguments);return this.each(function(e){t in e&&e[t].apply(e,n)}),this}}),e.each("text name disabled active selected checked visible parent value data".split(" "),function(e){i[e]=function(t){return this.prop(e,t)}}),r=n.extend(i),t.Collection=r,r}),r(J,[f,b],function(e,t){var n=0;return{id:function(){return"mceu_"+n++},createFragment:function(e){return t.DOM.createFragment(e)},getWindowSize:function(){return t.DOM.getViewPort()},getSize:function(e){var t,n;if(e.getBoundingClientRect){var r=e.getBoundingClientRect();t=Math.max(r.width||r.right-r.left,e.offsetWidth),n=Math.max(r.height||r.bottom-r.bottom,e.offsetHeight)}else t=e.offsetWidth,n=e.offsetHeight;return{width:t,height:n}},getPos:function(e,n){return t.DOM.getPos(e,n)},getViewPort:function(e){return t.DOM.getViewPort(e)},get:function(e){return document.getElementById(e)},addClass:function(e,n){return t.DOM.addClass(e,n)},removeClass:function(e,n){return t.DOM.removeClass(e,n)},hasClass:function(e,n){return t.DOM.hasClass(e,n)},toggleClass:function(e,n,r){return t.DOM.toggleClass(e,n,r)},css:function(e,n,r){return t.DOM.setStyle(e,n,r)},getRuntimeStyle:function(e,n){return t.DOM.getStyle(e,n,!0)},on:function(e,n,r,i){return t.DOM.bind(e,n,r,i)},off:function(e,n,r){return t.DOM.unbind(e,n,r)},fire:function(e,n,r){return t.DOM.fire(e,n,r)},innerHtml:function(e,n){t.DOM.setHTML(e,n)}}}),r(Q,[],function(){return{parseBox:function(e){var t,n=10;if(e)return"number"==typeof e?(e=e||0,{top:e,left:e,bottom:e,right:e}):(e=e.split(" "),t=e.length,1===t?e[1]=e[2]=e[3]=e[0]:2===t?(e[2]=e[0],e[3]=e[1]):3===t&&(e[3]=e[1]),{top:parseInt(e[0],n)||0,right:parseInt(e[1],n)||0,bottom:parseInt(e[2],n)||0,left:parseInt(e[3],n)||0})},measureBox:function(e,t){function n(t){var n=document.defaultView;return n?(t=t.replace(/[A-Z]/g,function(e){return"-"+e}),n.getComputedStyle(e,null).getPropertyValue(t)):e.currentStyle[t]}function r(e){var t=parseFloat(n(e),10);return isNaN(t)?0:t}return{top:r(t+"TopWidth"),right:r(t+"RightWidth"),bottom:r(t+"BottomWidth"),left:r(t+"LeftWidth")}}}}),r(Z,[f],function(e){function t(){}function n(e){this.cls=[],this.cls._map={},this.onchange=e||t,this.prefix=""}return e.extend(n.prototype,{add:function(e){return e&&!this.contains(e)&&(this.cls._map[e]=!0,this.cls.push(e),this._change()),this},remove:function(e){if(this.contains(e)){for(var t=0;t0&&(e+=" "),e+=this.prefix+this.cls[t];return e},n}),r(ee,[],function(){function e(e,t){function n(e){window.setTimeout(e,0)}var r,i=window.requestAnimationFrame,o=["ms","moz","webkit"];for(r=0;r=i;o--)r=s[o],r.fire("mouseleave",{target:r.getEl()})}for(o=i;oo;o++)c=l[o]._eventsRoot;for(c||(c=l[l.length-1]||e),e._eventsRoot=c,s=o,o=0;s>o;o++)l[o]._eventsRoot=c;var p=c._delegates;p||(p=c._delegates={});for(d in u){if(!u)return!1;"wheel"!==d||h?("mouseenter"===d||"mouseleave"===d?c._hasMouseEnter||(a(c.getEl()).on("mouseleave",n).on("mouseover",r),c._hasMouseEnter=1):p[d]||(a(c.getEl()).on(d,t),p[d]=!0),u[d]=!1):f?a(e.getEl()).on("mousewheel",i):a(e.getEl()).on("DOMMouseScroll",i)}}}var f="onmousewheel"in document,h=!1,p="mce-",m,g=0,v={Statics:{classPrefix:p},isRtl:function(){return m.rtl},classPrefix:p,init:function(e){function n(e){var t;for(e=e.split(" "),t=0;tn.maxW?n.maxW:i,n.w=i,n.innerW=i-o),i=e.h,i!==s&&(i=in.maxH?n.maxH:i,n.h=i,n.innerH=i-a),i=e.innerW,i!==s&&(i=in.maxW-o?n.maxW-o:i,n.innerW=i,n.w=i+o),i=e.innerH,i!==s&&(i=in.maxH-a?n.maxH-a:i,n.innerH=i,n.h=i+a),e.contentW!==s&&(n.contentW=e.contentW),e.contentH!==s&&(n.contentH=e.contentH),r=t._lastLayoutRect,(r.x!==n.x||r.y!==n.y||r.w!==n.w||r.h!==n.h)&&(l=m.repaintControls,l&&l.map&&!l.map[t._id]&&(l.push(t),l.map[t._id]=!0),r.x=n.x,r.y=n.y,r.w=n.w,r.h=n.h),t):n},repaint:function(){var e=this,t,n,r,i,o,a=0,s=0,l,c,u;c=document.createRange?function(e){return e}:Math.round,t=e.getEl().style,i=e._layoutRect,l=e._lastRepaintRect||{},o=e.borderBox,a=o.left+o.right,s=o.top+o.bottom,i.x!==l.x&&(t.left=c(i.x)+"px",l.x=i.x),i.y!==l.y&&(t.top=c(i.y)+"px",l.y=i.y), -i.w!==l.w&&(u=c(i.w-a),t.width=(u>=0?u:0)+"px",l.w=i.w),i.h!==l.h&&(u=c(i.h-s),t.height=(u>=0?u:0)+"px",l.h=i.h),e._hasBody&&i.innerW!==l.innerW&&(u=c(i.innerW),r=e.getEl("body"),r&&(n=r.style,n.width=(u>=0?u:0)+"px"),l.innerW=i.innerW),e._hasBody&&i.innerH!==l.innerH&&(u=c(i.innerH),r=r||e.getEl("body"),r&&(n=n||r.style,n.height=(u>=0?u:0)+"px"),l.innerH=i.innerH),e._lastRepaintRect=l,e.fire("repaint",{},!1)},on:function(e,t){function n(e){var t,n;return"string"!=typeof e?e:function(i){return t||r.parentsAndSelf().each(function(r){var i=r.settings.callbacks;return i&&(t=i[e])?(n=r,!1):void 0}),t?t.call(n,i):(i.action=e,void this.fire("execute",i))}}var r=this;return u(r).on(e,n(t)),r},off:function(e,t){return u(this).off(e,t),this},fire:function(e,t,n){var r=this;if(t=t||{},t.control||(t.control=r),t=u(r).fire(e,t),n!==!1&&r.parent)for(var i=r.parent();i&&!t.isPropagationStopped();)i.fire(e,t,!1),i=i.parent();return t},hasEventListeners:function(e){return u(this).has(e)},parents:function(e){var t=this,n,r=new i;for(n=t.parent();n;n=n.parent())r.add(n);return e&&(r=r.filter(e)),r},parentsAndSelf:function(e){return new i(this).add(this.parents(e))},next:function(){var e=this.parent().items();return e[e.indexOf(this)+1]},prev:function(){var e=this.parent().items();return e[e.indexOf(this)-1]},innerHtml:function(e){return this.$el.html(e),this},getEl:function(e){var t=e?this._id+"-"+e:this._id;return this._elmCache[t]||(this._elmCache[t]=a("#"+t)[0]),this._elmCache[t]},show:function(){return this.visible(!0)},hide:function(){return this.visible(!1)},focus:function(){try{this.getEl().focus()}catch(e){}return this},blur:function(){return this.getEl().blur(),this},aria:function(e,t){var n=this,r=n.getEl(n.ariaTarget);return"undefined"==typeof t?n._aria[e]:(n._aria[e]=t,n.state.get("rendered")&&r.setAttribute("role"==e?e:"aria-"+e,t),n)},encode:function(e,t){return t!==!1&&(e=this.translate(e)),(e||"").replace(/[&<>"]/g,function(e){return"&#"+e.charCodeAt(0)+";"})},translate:function(e){return m.translate?m.translate(e):e},before:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t),!0),t},after:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t)),t},remove:function(){var e=this,t=e.getEl(),n=e.parent(),r,i;if(e.items){var o=e.items().toArray();for(i=o.length;i--;)o[i].remove()}n&&n.items&&(r=[],n.items().each(function(t){t!==e&&r.push(t)}),n.items().set(r),n._lastRect=null),e._eventsRoot&&e._eventsRoot==e&&a(t).off();var s=e.getRoot().controlIdLookup;return s&&delete s[e._id],t&&t.parentNode&&t.parentNode.removeChild(t),e.state.set("rendered",!1),e.state.destroy(),e.fire("remove"),e},renderBefore:function(e){return a(e).before(this.renderHtml()),this.postRender(),this},renderTo:function(e){return a(e||this.getContainerElm()).append(this.renderHtml()),this.postRender(),this},preRender:function(){},render:function(){},renderHtml:function(){return'
'},postRender:function(){var e=this,t=e.settings,n,r,i,o,s;e.$el=a(e.getEl()),e.state.set("rendered",!0);for(o in t)0===o.indexOf("on")&&e.on(o.substr(2),t[o]);if(e._eventsRoot){for(i=e.parent();!s&&i;i=i.parent())s=i._eventsRoot;if(s)for(o in s._nativeEvents)e._nativeEvents[o]=!0}d(e),t.style&&(n=e.getEl(),n&&(n.setAttribute("style",t.style),n.style.cssText=t.style)),e.settings.border&&(r=e.borderBox,e.$el.css({"border-top-width":r.top,"border-right-width":r.right,"border-bottom-width":r.bottom,"border-left-width":r.left}));var l=e.getRoot();l.controlIdLookup||(l.controlIdLookup={}),l.controlIdLookup[e._id]=e;for(var u in e._aria)e.aria(u,e._aria[u]);e.state.get("visible")===!1&&(e.getEl().style.display="none"),e.bindStates(),e.state.on("change:visible",function(t){var n=t.value,r;e.state.get("rendered")&&(e.getEl().style.display=n===!1?"none":"",e.getEl().getBoundingClientRect()),r=e.parent(),r&&(r._lastRect=null),e.fire(n?"show":"hide"),c.add(e)}),e.fire("postrender",{},!1)},bindStates:function(){},scrollIntoView:function(e){function t(e,t){var n,r,i=e;for(n=r=0;i&&i!=t&&i.nodeType;)n+=i.offsetLeft||0,r+=i.offsetTop||0,i=i.offsetParent;return{x:n,y:r}}var n=this.getEl(),r=n.parentNode,i,o,a,s,l,c,u=t(n,r);return i=u.x,o=u.y,a=n.offsetWidth,s=n.offsetHeight,l=r.clientWidth,c=r.clientHeight,"end"==e?(i-=l-a,o-=c-s):"center"==e&&(i-=l/2-a/2,o-=c/2-s/2),r.scrollLeft=i,r.scrollTop=o,this},getRoot:function(){for(var e=this,t,n=[];e;){if(e.rootControl){t=e.rootControl;break}n.push(e),t=e,e=e.parent()}t||(t=this);for(var r=n.length;r--;)n[r].rootControl=t;return t},reflow:function(){c.remove(this);var e=this.parent();return e._layout&&!e._layout.isNative()&&e.reflow(),this}};return t.each("text title visible disabled active value".split(" "),function(e){v[e]=function(t){return 0===arguments.length?this.state.get(e):("undefined"!=typeof t&&this.state.set(e,t),this)}}),m=e.extend(v)}),r(ne,[],function(){var e={},t;return{add:function(t,n){e[t.toLowerCase()]=n},has:function(t){return!!e[t.toLowerCase()]},create:function(n,r){var i,o,a;if(!t){a=tinymce.ui;for(o in a)e[o.toLowerCase()]=a[o];t=!0}if("string"==typeof n?(r=r||{},r.type=n):(r=n,n=r.type),n=n.toLowerCase(),i=e[n],!i)throw new Error("Could not find control by type: "+n);return i=new i(r),i.type=n,i}}}),r(re,[],function(){return function(e){function t(e){return e&&1===e.nodeType}function n(e){return e=e||x,t(e)?e.getAttribute("role"):null}function r(e){for(var t,r=e||x;r=r.parentNode;)if(t=n(r))return t}function i(e){var n=x;return t(n)?n.getAttribute("aria-"+e):void 0}function o(e){var t=e.tagName.toUpperCase();return"INPUT"==t||"TEXTAREA"==t}function a(e){return o(e)&&!e.hidden?!0:/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell)$/.test(n(e))?!0:!1}function s(e){function t(e){if(1==e.nodeType&&"none"!=e.style.display){a(e)&&n.push(e);for(var r=0;re?e=t.length-1:e>=t.length&&(e=0),t[e]&&t[e].focus(),e}function d(e,t){var n=-1,r=l();t=t||s(r.getEl());for(var i=0;i=0&&(n=t.getEl(),n&&n.parentNode.removeChild(n),n=e.getEl(),n&&n.parentNode.removeChild(n)),t.parent(this)},create:function(t){var n=this,i,a=[];return o.isArray(t)||(t=[t]),o.each(t,function(t){t&&(t instanceof e||("string"==typeof t&&(t={type:t}),i=o.extend({},n.settings.defaults,t),t.type=i.type=i.type||t.type||n.settings.defaultType||(i.defaults?i.defaults.type:null),t=r.create(i)),a.push(t))}),a},renderNew:function(){var e=this;return e.items().each(function(t,n){var r;t.parent(e),t.state.get("rendered")||(r=e.getEl("body"),r.hasChildNodes()&&n<=r.childNodes.length-1?a(r.childNodes[n]).before(t.renderHtml()):a(r).append(t.renderHtml()),t.postRender(),l.add(t))}),e._layout.applyClasses(e.items().filter(":visible")),e._lastRect=null,e},append:function(e){return this.add(e).renderNew()},prepend:function(e){var t=this;return t.items().set(t.create(e).concat(t.items().toArray())),t.renderNew()},insert:function(e,t,n){var r=this,i,o,a;return e=r.create(e),i=r.items(),!n&&t=0&&t
'+(e.settings.html||"")+t.renderHtml(e)+"
"},postRender:function(){var e=this,t;return e.items().exec("postRender"),e._super(),e._layout.postRender(e),e.state.set("rendered",!0),e.settings.style&&e.$el.css(e.settings.style),e.settings.border&&(t=e.borderBox,e.$el.css({"border-top-width":t.top,"border-right-width":t.right,"border-bottom-width":t.bottom,"border-left-width":t.left})),e.parent()||(e.keyboardNav=new i({root:e})),e},initLayoutRect:function(){var e=this,t=e._super();return e._layout.recalc(e),t},recalc:function(){var e=this,t=e._layoutRect,n=e._lastRect;return n&&n.w==t.w&&n.h==t.h?void 0:(e._layout.recalc(e),t=e.layoutRect(),e._lastRect={x:t.x,y:t.y,w:t.w,h:t.h},!0)},reflow:function(){var t;if(l.remove(this),this.visible()){for(e.repaintControls=[],e.repaintControls.map={},this.recalc(),t=e.repaintControls.length;t--;)e.repaintControls[t].repaint();"flow"!==this.settings.layout&&"stack"!==this.settings.layout&&this.repaint(),e.repaintControls=[]}return this}})}),r(oe,[h],function(e){function t(e){var t,n,r,i,o,a,s,l,c=Math.max;return t=e.documentElement,n=e.body,r=c(t.scrollWidth,n.scrollWidth),i=c(t.clientWidth,n.clientWidth),o=c(t.offsetWidth,n.offsetWidth),a=c(t.scrollHeight,n.scrollHeight),s=c(t.clientHeight,n.clientHeight),l=c(t.offsetHeight,n.offsetHeight),{width:o>r?i:r,height:l>a?s:a}}function n(e){var t,n;if(e.changedTouches)for(t="screenX screenY pageX pageY clientX clientY".split(" "),n=0;n").css({position:"absolute",top:0,left:0,width:c.width,height:c.height,zIndex:2147483647,opacity:1e-4,cursor:m}).appendTo(s.body),e(s).on("mousemove touchmove",d).on("mouseup touchend",u),i.start(r)},d=function(e){return n(e),e.button!==l?u(e):(e.deltaX=e.screenX-f,e.deltaY=e.screenY-h,e.preventDefault(),void i.drag(e))},u=function(t){n(t),e(s).off("mousemove touchmove",d).off("mouseup touchend",u),a.remove(),i.stop&&i.stop(t)},this.destroy=function(){e(o()).off()},e(o()).on("mousedown touchstart",c)}}),r(ae,[h,oe],function(e,t){return{init:function(){var e=this;e.on("repaint",e.renderScroll)},renderScroll:function(){function n(){function t(t,a,s,l,c,u){var d,f,h,p,m,g,v,y,b;if(f=i.getEl("scroll"+t)){if(y=a.toLowerCase(),b=s.toLowerCase(),e(i.getEl("absend")).css(y,i.layoutRect()[l]-1),!c)return void e(f).css("display","none");e(f).css("display","block"),d=i.getEl("body"),h=i.getEl("scroll"+t+"t"),p=d["client"+s]-2*o,p-=n&&r?f["client"+u]:0,m=d["scroll"+s],g=p/m,v={},v[y]=d["offset"+a]+o,v[b]=p,e(f).css(v),v={},v[y]=d["scroll"+a]*g,v[b]=p*g,e(h).css(v)}}var n,r,a;a=i.getEl("body"),n=a.scrollWidth>a.clientWidth,r=a.scrollHeight>a.clientHeight,t("h","Left","Width","contentW",n,"Height"),t("v","Top","Height","contentH",r,"Width")}function r(){function n(n,r,a,s,l){var c,u=i._id+"-scroll"+n,d=i.classPrefix;e(i.getEl()).append('
'),i.draghelper=new t(u+"t",{start:function(){c=i.getEl("body")["scroll"+r],e("#"+u).addClass(d+"active")},drag:function(e){var t,u,d,f,h=i.layoutRect();u=h.contentW>h.innerW,d=h.contentH>h.innerH,f=i.getEl("body")["client"+a]-2*o,f-=u&&d?i.getEl("scroll"+n)["client"+l]:0,t=f/i.getEl("body")["scroll"+a],i.getEl("body")["scroll"+r]=c+e["delta"+s]/t},stop:function(){e("#"+u).removeClass(d+"active")}})}i.classes.add("scroll"),n("v","Top","Height","Y","Width"),n("h","Left","Width","X","Height")}var i=this,o=2;i.settings.autoScroll&&(i._hasScroll||(i._hasScroll=!0,r(),i.on("wheel",function(e){var t=i.getEl("body");t.scrollLeft+=10*(e.deltaX||0),t.scrollTop+=10*e.deltaY,n()}),e(i.getEl("body")).on("scroll",n)),n())}}}),r(se,[ie,ae],function(e,t){return e.extend({Defaults:{layout:"fit",containerCls:"panel"},Mixins:[t],renderHtml:function(){var e=this,t=e._layout,n=e.settings.html;return e.preRender(),t.preRender(e),"undefined"==typeof n?n='
'+t.renderHtml(e)+"
":("function"==typeof n&&(n=n.call(e)),e._hasBody=!1),'
'+(e._preBodyHtml||"")+n+"
"}})}),r(le,[J],function(e){function t(t,n,r){var i,o,a,s,l,c,u,d,f,h;return f=e.getViewPort(),o=e.getPos(n),a=o.x,s=o.y,t.state.get("fixed")&&"static"==e.getRuntimeStyle(document.body,"position")&&(a-=f.x,s-=f.y),i=t.getEl(),h=e.getSize(i),l=h.width,c=h.height,h=e.getSize(n),u=h.width,d=h.height,r=(r||"").split(""),"b"===r[0]&&(s+=d),"r"===r[1]&&(a+=u),"c"===r[0]&&(s+=Math.round(d/2)),"c"===r[1]&&(a+=Math.round(u/2)),"b"===r[3]&&(s-=c),"r"===r[4]&&(a-=l),"c"===r[3]&&(s-=Math.round(c/2)),"c"===r[4]&&(a-=Math.round(l/2)),{x:a,y:s,w:l,h:c}}return{testMoveRel:function(n,r){for(var i=e.getViewPort(),o=0;o0&&a.x+a.w0&&a.y+a.hi.x&&a.x+a.wi.y&&a.y+a.he?0:e+n>t?(e=t-n,0>e?0:e):e}var i=this;if(i.settings.constrainToViewport){var o=e.getViewPort(window),a=i.layoutRect();t=r(t,o.w+o.x,a.w),n=r(n,o.h+o.y,a.h)}return i.state.get("rendered")?i.layoutRect({x:t,y:n}).repaint():(i.settings.x=t,i.settings.y=n),i.fire("move",{x:t,y:n}),i}}}),r(ce,[J],function(e){return{resizeToContent:function(){this._layoutRect.autoResize=!0,this._lastRect=null,this.reflow()},resizeTo:function(t,n){if(1>=t||1>=n){var r=e.getWindowSize();t=1>=t?t*r.w:t,n=1>=n?n*r.h:n}return this._layoutRect.autoResize=!1,this.layoutRect({minW:t,minH:n,w:t,h:n}).reflow()},resizeBy:function(e,t){var n=this,r=n.layoutRect();return n.resizeTo(r.w+e,r.h+t)}}}),r(ue,[se,le,ce,J,h],function(e,t,n,r,i){function o(e,t){for(;e;){if(e==t)return!0;e=e.parent()}}function a(e){for(var t=g.length;t--;){var n=g[t],r=n.getParentCtrl(e.target);if(n.settings.autohide){if(r&&(o(r,n)||n.parent()===r))continue;e=n.fire("autohide",{target:e.target}),e.isDefaultPrevented()||n.hide()}}}function s(){h||(h=function(e){2!=e.button&&a(e)},i(document).on("click touchstart",h))}function l(){p||(p=function(){var e;for(e=g.length;e--;)u(g[e])},i(window).on("scroll",p))}function c(){if(!m){var e=document.documentElement,t=e.clientWidth,n=e.clientHeight;m=function(){document.all&&t==e.clientWidth&&n==e.clientHeight||(t=e.clientWidth,n=e.clientHeight,b.hideAll())},i(window).on("resize",m)}}function u(e){function t(t,n){for(var r,i=0;in&&(e.fixed(!1).layoutRect({y:e._autoFixY}).repaint(),t(!1,e._autoFixY-n)):(e._autoFixY=e.layoutRect().y,e._autoFixY
').appendTo(t.getContainerElm())),setTimeout(function(){n.addClass(r+"in"),i(t.getEl()).addClass(r+"in")},0),y=!0),d(!0,t)}}),t.on("show",function(){t.parents().each(function(e){return e.state.get("fixed")?(t.fixed(!0),!1):void 0})}),e.popover&&(t._preBodyHtml='
',t.classes.add("popover").add("bottom").add(t.isRtl()?"end":"start"))},fixed:function(e){var t=this;if(t.state.get("fixed")!=e){if(t.state.get("rendered")){var n=r.getViewPort();e?t.layoutRect().y-=n.y:t.layoutRect().y+=n.y}t.classes.toggle("fixed",e),t.state.set("fixed",e)}return t},show:function(){var e=this,t,n=e._super();for(t=g.length;t--&&g[t]!==e;);return-1===t&&g.push(e),n},hide:function(){return f(this),d(!1,this),this._super()},hideAll:function(){b.hideAll()},close:function(){var e=this;return e.fire("close").isDefaultPrevented()||(e.remove(),d(!1,e)),e},remove:function(){f(this),this._super()},postRender:function(){var e=this;return e.settings.bodyRole&&this.getEl("body").setAttribute("role",e.settings.bodyRole),e._super()}});return b.hideAll=function(){for(var e=g.length;e--;){var t=g[e];t&&t.settings.autohide&&(t.hide(),g.splice(e,1))}},b}),r(de,[ue,se,J,h,oe,Q,u],function(e,t,n,r,i,o,a){function s(e){var t="width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0",n=r("meta[name=viewport]")[0],i;a.overrideViewPort!==!1&&(n||(n=document.createElement("meta"),n.setAttribute("name","viewport"),document.getElementsByTagName("head")[0].appendChild(n)),i=n.getAttribute("content"),i&&"undefined"!=typeof d&&(d=i),n.setAttribute("content",e?t:d))}function l(e){for(var t=0;tr.w&&(o=r.x-Math.max(0,i/2),e.layoutRect({w:i,x:o}),a=!0)),t&&(t.layoutRect({w:e.layoutRect().innerW}).recalc(),i=t.layoutRect().minW+r.deltaW,i>r.w&&(o=r.x-Math.max(0,i-r.w),e.layoutRect({w:i,x:o}),a=!0)),a&&e.recalc()},initLayoutRect:function(){var e=this,t=e._super(),r=0,i;if(e.settings.title&&!e._fullscreen){i=e.getEl("head");var o=n.getSize(i);t.headerW=o.width,t.headerH=o.height,r+=t.headerH}e.statusbar&&(r+=e.statusbar.layoutRect().h),t.deltaH+=r,t.minH+=r,t.h+=r;var a=n.getWindowSize();return t.x=e.settings.x||Math.max(0,a.w/2-t.w/2),t.y=e.settings.y||Math.max(0,a.h/2-t.h/2),t},renderHtml:function(){var e=this,t=e._layout,n=e._id,r=e.classPrefix,i=e.settings,o="",a="",s=i.html;return e.preRender(),t.preRender(e),i.title&&(o='
'+e.encode(i.title)+'
'),i.url&&(s=''),"undefined"==typeof s&&(s=t.renderHtml(e)),e.statusbar&&(a=e.statusbar.renderHtml()),'
'+o+'
'+s+"
"+a+"
"},fullscreen:function(e){var t=this,i=document.documentElement,a,s=t.classPrefix,l;if(e!=t._fullscreen)if(r(window).on("resize",function(){var e;if(t._fullscreen)if(a)t._timer||(t._timer=setTimeout(function(){var e=n.getWindowSize();t.moveTo(0,0).resizeTo(e.w,e.h),t._timer=0},50));else{e=(new Date).getTime();var r=n.getWindowSize();t.moveTo(0,0).resizeTo(r.w,r.h),(new Date).getTime()-e>50&&(a=!0)}}),l=t.layoutRect(),t._fullscreen=e,e){t._initial={x:l.x,y:l.y,w:l.w,h:l.h},t.borderBox=o.parseBox("0"),t.getEl("head").style.display="none",l.deltaH-=l.headerH+2,r([i,document.body]).addClass(s+"fullscreen"),t.classes.add("fullscreen");var c=n.getWindowSize();t.moveTo(0,0).resizeTo(c.w,c.h)}else t.borderBox=o.parseBox(t.settings.border),t.getEl("head").style.display="",l.deltaH+=l.headerH,r([i,document.body]).removeClass(s+"fullscreen"),t.classes.remove("fullscreen"),t.moveTo(t._initial.x,t._initial.y).resizeTo(t._initial.w,t._initial.h);return t.reflow()},postRender:function(){var e=this,t;setTimeout(function(){e.classes.add("in")},0),e._super(),e.statusbar&&e.statusbar.postRender(),e.focus(),this.dragHelper=new i(e._id+"-dragh",{start:function(){t={x:e.layoutRect().x,y:e.layoutRect().y}},drag:function(n){e.moveTo(t.x+n.deltaX,t.y+n.deltaY)}}),e.on("submit",function(t){t.isDefaultPrevented()||e.close()}),u.push(e),s(!0)},submit:function(){return this.fire("submit",{data:this.toJSON()})},remove:function(){var e=this,t;for(e.dragHelper.destroy(),e._super(),e.statusbar&&this.statusbar.remove(),t=u.length;t--;)u[t]===e&&u.splice(t,1);s(u.length>0),l(e.classPrefix)},getContentWindow:function(){var e=this.getEl().getElementsByTagName("iframe")[0];return e?e.contentWindow:null}});return a.desktop||c(),f}),r(fe,[de],function(e){var t=e.extend({init:function(e){e={border:1,padding:20,layout:"flex",pack:"center",align:"center",containerCls:"panel",autoScroll:!0,buttons:{type:"button",text:"Ok",action:"ok"},items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200}},this._super(e)},Statics:{OK:1,OK_CANCEL:2,YES_NO:3,YES_NO_CANCEL:4,msgBox:function(n){function r(e,t,n){return{type:"button",text:e,subtype:n?"primary":"",onClick:function(e){e.control.parents()[1].close(),o(t)}}}var i,o=n.callback||function(){};switch(n.buttons){case t.OK_CANCEL:i=[r("Ok",!0,!0),r("Cancel",!1)];break;case t.YES_NO:case t.YES_NO_CANCEL:i=[r("Yes",1,!0),r("No",0)],n.buttons==t.YES_NO_CANCEL&&i.push(r("Cancel",-1));break;default:i=[r("Ok",!0,!0)]}return new e({padding:20,x:n.x,y:n.y,minWidth:300,minHeight:100,layout:"flex",pack:"center",align:"center",buttons:i,title:n.title,role:"alertdialog",items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200,text:n.text},onPostRender:function(){this.aria("describedby",this.items()[0]._id)},onClose:n.onClose,onCancel:function(){o(!1)}}).renderTo(document.body).reflow()},alert:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,t.msgBox(e)},confirm:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,e.buttons=t.OK_CANCEL,t.msgBox(e)}}});return t}),r(he,[de,fe],function(e,t){return function(n){function r(){return o.length?o[o.length-1]:void 0}var i=this,o=[];i.windows=o,n.on("remove",function(){for(var e=o.length;e--;)o[e].close()}),i.open=function(t,r){var i;return n.editorManager.setActive(n),t.title=t.title||" ",t.url=t.url||t.file,t.url&&(t.width=parseInt(t.width||320,10),t.height=parseInt(t.height||240,10)),t.body&&(t.items={defaults:t.defaults,type:t.bodyType||"form",items:t.body}),t.url||t.buttons||(t.buttons=[{text:"Ok",subtype:"primary",onclick:function(){i.find("form")[0].submit()}},{text:"Cancel",onclick:function(){i.close()}}]),i=new e(t),o.push(i),i.on("close",function(){for(var e=o.length;e--;)o[e]===i&&o.splice(e,1);o.length||n.focus()}),t.data&&i.on("postRender",function(){this.find("*").each(function(e){var n=e.name();n in t.data&&e.value(t.data[n])})}),i.features=t||{},i.params=r||{},1===o.length&&n.nodeChanged(),i.renderTo().reflow()},i.alert=function(e,r,i){t.alert(e,function(){r?r.call(i||this):n.focus()})},i.confirm=function(e,n,r){t.confirm(e,function(e){n.call(r||this,e)})},i.close=function(){r()&&r().close()},i.getParams=function(){return r()?r().params:null},i.setParams=function(e){r()&&(r().params=e)},i.getWindows=function(){return o}}}),r(pe,[D,w,m,E,v,u,f],function(e,t,n,r,i,o,a){return function(s){function l(e,t){try{s.getDoc().execCommand(e,!1,t)}catch(n){}}function c(){var e=s.getDoc().documentMode;return e?e:6}function u(e){return e.isDefaultPrevented()}function d(e){var t,n;e.dataTransfer&&(s.selection.isCollapsed()&&"IMG"==e.target.tagName&&X.select(e.target),t=s.selection.getContent(),t.length>0&&(n=re+escape(s.id)+","+escape(t),e.dataTransfer.setData(ie,n)))}function f(e){var t;return e.dataTransfer&&(t=e.dataTransfer.getData(ie),t&&t.indexOf(re)>=0)?(t=t.substr(re.length).split(","),{id:unescape(t[0]),html:unescape(t[1])}):null}function h(e){s.queryCommandSupported("mceInsertClipboardContent")?s.execCommand("mceInsertClipboardContent",!1,{content:e}):s.execCommand("mceInsertContent",!1,e)}function p(){function r(e){var t=v.schema.getBlockElements(),n=s.getBody();if("BR"!=e.nodeName)return!1;for(e=e;e!=n&&!t[e.nodeName];e=e.parentNode)if(e.nextSibling)return!1;return!0}function i(e,t){var n;for(n=e.nextSibling;n&&n!=t;n=n.nextSibling)if((3!=n.nodeType||0!==j.trim(n.data).length)&&n!==t)return!1;return n===t}function o(e,t,i){var o,a,s;for(s=v.schema.getNonEmptyElements(),o=new n(i||e,e);a=o[t?"next":"prev"]();){if(s[a.nodeName]&&!r(a))return a;if(3==a.nodeType&&a.data.length>0)return a}}function l(e){var n,r,i,a,l;if(!e.collapsed&&(n=v.getParent(t.getNode(e.startContainer,e.startOffset),v.isBlock),r=v.getParent(t.getNode(e.endContainer,e.endOffset),v.isBlock),l=s.schema.getTextBlockElements(),n!=r&&l[n.nodeName]&&l[r.nodeName]&&"false"!==v.getContentEditable(n)&&"false"!==v.getContentEditable(r)))return e.deleteContents(),i=o(n,!1),a=o(r,!0),v.isEmpty(r)||j(n).append(r.childNodes),j(r).remove(),i?1==i.nodeType?"BR"==i.nodeName?(e.setStartBefore(i),e.setEndBefore(i)):(e.setStartAfter(i),e.setEndAfter(i)):(e.setStart(i,i.data.length),e.setEnd(i,i.data.length)):a&&(1==a.nodeType?(e.setStartBefore(a),e.setEndBefore(a)):(e.setStart(a,0),e.setEnd(a,0))),y.setRng(e),!0}function c(e,n){var r,a,l,c,u,d;if(!e.collapsed)return e;if(u=e.startContainer,d=e.startOffset,3==u.nodeType)if(n){if(d0)return e;if(r=t.getNode(e.startContainer,e.startOffset),l=v.getParent(r,v.isBlock),a=o(s.getBody(),n,r),c=v.getParent(a,v.isBlock),!r||!a)return e;if(c&&l!=c)if(n){if(!i(l,c))return e;1==r.nodeType?"BR"==r.nodeName?e.setStartBefore(r):e.setStartAfter(r):e.setStart(r,r.data.length),1==a.nodeType?e.setEnd(a,0):e.setEndBefore(a)}else{if(!i(c,l))return e;1==a.nodeType?"BR"==a.nodeName?e.setStartBefore(a):e.setStartAfter(a):e.setStart(a,a.data.length),1==r.nodeType?e.setEnd(r,0):e.setEndBefore(r)}return e}function p(e){var t=y.getRng();return t=c(t,e),l(t)?!0:void 0}function m(e){var t,n,r;p(e)||(a.each(s.getBody().getElementsByTagName("*"),function(e){"SPAN"==e.tagName&&e.setAttribute("mce-data-marked",1),!e.hasAttribute("data-mce-style")&&e.hasAttribute("style")&&s.dom.setAttrib(e,"style",s.dom.getAttrib(e,"style"))}),t=new b(function(){}),t.observe(s.getDoc(),{childList:!0,attributes:!0,subtree:!0,attributeFilter:["style"]}),s.getDoc().execCommand(e?"ForwardDelete":"Delete",!1,null),n=s.selection.getRng(),r=n.startContainer.parentNode,a.each(t.takeRecords(),function(e){if(v.isChildOf(e.target,s.getBody())){if("style"==e.attributeName){var t=e.target.getAttribute("data-mce-style");t?e.target.setAttribute("style",t):e.target.removeAttribute("style")}a.each(e.addedNodes,function(e){if("SPAN"==e.nodeName&&!e.getAttribute("mce-data-marked")){var t,i;e==r&&(t=n.startOffset,i=e.firstChild),v.remove(e,!0),i&&(n.setStart(i,t),n.setEnd(i,t),s.selection.setRng(n))}})}}),t.disconnect(),a.each(s.dom.select("span[mce-data-marked]"),function(e){e.removeAttribute("mce-data-marked")}))}var g=s.getDoc(),v=s.dom,y=s.selection,b=window.MutationObserver,x,C;b||(x=!0,b=function(){function e(e){var t=e.relatedNode||e.target;n.push({target:t,addedNodes:[t]})}function t(e){var t=e.relatedNode||e.target;n.push({target:t,attributeName:e.attrName})}var n=[],r;this.observe=function(n){r=n,r.addEventListener("DOMSubtreeModified",e,!1),r.addEventListener("DOMNodeInsertedIntoDocument",e,!1),r.addEventListener("DOMNodeInserted",e,!1),r.addEventListener("DOMAttrModified",t,!1)},this.disconnect=function(){r.removeEventListener("DOMSubtreeModified",e,!1),r.removeEventListener("DOMNodeInsertedIntoDocument",e,!1),r.removeEventListener("DOMNodeInserted",e,!1),r.removeEventListener("DOMAttrModified",t,!1)},this.takeRecords=function(){return n}}),s.on("keydown",function(e){var t=e.keyCode==Y,n=e.ctrlKey||e.metaKey;if(!u(e)&&(t||e.keyCode==K)){var r=s.selection.getRng(),i=r.startContainer,o=r.startOffset;if(t&&e.shiftKey)return;if(!n&&r.collapsed&&3==i.nodeType&&(t?o0))return;e.preventDefault(),n&&s.selection.getSel().modify("extend",t?"forward":"backward",e.metaKey?"lineboundary":"word"),m(t)}}),s.on("keypress",function(t){if(!u(t)&&!y.isCollapsed()&&t.charCode&&!e.metaKeyPressed(t)){var n,r,i,o,a,l; -n=s.selection.getRng(),l=String.fromCharCode(t.charCode),t.preventDefault(),r=j(n.startContainer).parents().filter(function(e,t){return!!s.schema.getTextInlineElements()[t.nodeName]}),m(!0),r=r.filter(function(e,t){return!j.contains(s.getBody(),t)}),r.length?(i=v.createFragment(),r.each(function(e,t){t=t.cloneNode(!1),i.hasChildNodes()?(t.appendChild(i.firstChild),i.appendChild(t)):(a=t,i.appendChild(t)),i.appendChild(t)}),a.appendChild(s.getDoc().createTextNode(l)),o=v.getParent(n.startContainer,v.isBlock),v.isEmpty(o)?j(o).empty().append(i):n.insertNode(i),n.setStart(a.firstChild,1),n.setEnd(a.firstChild,1),s.selection.setRng(n)):s.selection.setContent(l)}}),s.addCommand("Delete",function(){m()}),s.addCommand("ForwardDelete",function(){m(!0)}),x||(s.on("dragstart",function(e){C=y.getRng(),d(e)}),s.on("drop",function(e){if(!u(e)){var n=f(e);n&&(e.preventDefault(),window.setTimeout(function(){var r=t.getCaretRangeFromPoint(e.x,e.y,g);C&&(y.setRng(C),C=null),m(),y.setRng(r),h(n.html)},0))}}),s.on("cut",function(e){u(e)||!e.clipboardData||s.selection.isCollapsed()||(e.preventDefault(),e.clipboardData.clearData(),e.clipboardData.setData("text/html",s.selection.getContent()),e.clipboardData.setData("text/plain",s.selection.getContent({format:"text"})),window.setTimeout(function(){m(!0)},0))}))}function m(){function e(e){var t=G.create("body"),n=e.cloneContents();return t.appendChild(n),X.serializer.serialize(t,{format:"html"})}function n(n){if(!n.setStart){if(n.item)return!1;var r=n.duplicate();return r.moveToElementText(s.getBody()),t.compareRanges(n,r)}var i=e(n),o=G.createRng();o.selectNode(s.getBody());var a=e(o);return i===a}s.on("keydown",function(e){var t=e.keyCode,r,i;if(!u(e)&&(t==Y||t==K)){if(r=s.selection.isCollapsed(),i=s.getBody(),r&&!G.isEmpty(i))return;if(!r&&!n(s.selection.getRng()))return;e.preventDefault(),s.setContent(""),i.firstChild&&G.isBlock(i.firstChild)?s.selection.setCursorLocation(i.firstChild,0):s.selection.setCursorLocation(i,0),s.nodeChanged()}})}function g(){s.shortcuts.add("meta+a",null,"SelectAll")}function v(){s.settings.content_editable||(G.bind(s.getDoc(),"focusin",function(){X.setRng(X.getRng())}),G.bind(s.getDoc(),"mousedown mouseup",function(e){e.target==s.getDoc().documentElement&&(s.getBody().focus(),"mousedown"==e.type?X.placeCaretAt(e.clientX,e.clientY):X.setRng(X.getRng()))}))}function y(){s.on("keydown",function(e){if(!u(e)&&e.keyCode===K){if(!s.getBody().getElementsByTagName("hr").length)return;if(X.isCollapsed()&&0===X.getRng(!0).startOffset){var t=X.getNode(),n=t.previousSibling;if("HR"==t.nodeName)return G.remove(t),void e.preventDefault();n&&n.nodeName&&"hr"===n.nodeName.toLowerCase()&&(G.remove(n),e.preventDefault())}}})}function b(){window.Range.prototype.getClientRects||s.on("mousedown",function(e){if(!u(e)&&"HTML"===e.target.nodeName){var t=s.getBody();t.blur(),setTimeout(function(){t.focus()},0)}})}function x(){s.on("click",function(e){var t=e.target;/^(IMG|HR)$/.test(t.nodeName)&&(e.preventDefault(),X.getSel().setBaseAndExtent(t,0,t,1),s.nodeChanged()),"A"==t.nodeName&&G.hasClass(t,"mce-item-anchor")&&(e.preventDefault(),X.select(t))})}function C(){function e(){var e=G.getAttribs(X.getStart().cloneNode(!1));return function(){var t=X.getStart();t!==s.getBody()&&(G.setAttrib(t,"style",null),q(e,function(e){t.setAttributeNode(e.cloneNode(!0))}))}}function t(){return!X.isCollapsed()&&G.getParent(X.getStart(),G.isBlock)!=G.getParent(X.getEnd(),G.isBlock)}s.on("keypress",function(n){var r;return u(n)||8!=n.keyCode&&46!=n.keyCode||!t()?void 0:(r=e(),s.getDoc().execCommand("delete",!1,null),r(),n.preventDefault(),!1)}),G.bind(s.getDoc(),"cut",function(n){var r;!u(n)&&t()&&(r=e(),setTimeout(function(){r()},0))})}function w(){document.body.setAttribute("role","application")}function _(){s.on("keydown",function(e){if(!u(e)&&e.keyCode===K&&X.isCollapsed()&&0===X.getRng(!0).startOffset){var t=X.getNode().previousSibling;if(t&&t.nodeName&&"table"===t.nodeName.toLowerCase())return e.preventDefault(),!1}})}function E(){c()>7||(l("RespectVisibilityInDesign",!0),s.contentStyles.push(".mceHideBrInPre pre br {display: none}"),G.addClass(s.getBody(),"mceHideBrInPre"),Q.addNodeFilter("pre",function(e){for(var t=e.length,n,i,o,a;t--;)for(n=e[t].getAll("br"),i=n.length;i--;)o=n[i],a=o.prev,a&&3===a.type&&"\n"!=a.value.charAt(a.value-1)?a.value+="\n":o.parent.insert(new r("#text",3),o,!0).value="\n"}),Z.addNodeFilter("pre",function(e){for(var t=e.length,n,r,i,o;t--;)for(n=e[t].getAll("br"),r=n.length;r--;)i=n[r],o=i.prev,o&&3==o.type&&(o.value=o.value.replace(/\r?\n$/,""))}))}function N(){G.bind(s.getBody(),"mouseup",function(){var e,t=X.getNode();"IMG"==t.nodeName&&((e=G.getStyle(t,"width"))&&(G.setAttrib(t,"width",e.replace(/[^0-9%]+/g,"")),G.setStyle(t,"width","")),(e=G.getStyle(t,"height"))&&(G.setAttrib(t,"height",e.replace(/[^0-9%]+/g,"")),G.setStyle(t,"height","")))})}function S(){s.on("keydown",function(t){var n,r,i,o,a;if(!u(t)&&t.keyCode==e.BACKSPACE&&(n=X.getRng(),r=n.startContainer,i=n.startOffset,o=G.getRoot(),a=r,n.collapsed&&0===i)){for(;a&&a.parentNode&&a.parentNode.firstChild==a&&a.parentNode!=o;)a=a.parentNode;"BLOCKQUOTE"===a.tagName&&(s.formatter.toggle("blockquote",null,a),n=G.createRng(),n.setStart(r,0),n.setEnd(r,0),X.setRng(n))}})}function k(){function e(){s._refreshContentEditable(),l("StyleWithCSS",!1),l("enableInlineTableEditing",!1),J.object_resizing||l("enableObjectResizing",!1)}J.readonly||s.on("BeforeExecCommand MouseDown",e)}function T(){function e(){q(G.select("a"),function(e){var t=e.parentNode,n=G.getRoot();if(t.lastChild===e){for(;t&&!G.isBlock(t);){if(t.parentNode.lastChild!==t||t===n)return;t=t.parentNode}G.add(t,"br",{"data-mce-bogus":1})}})}s.on("SetContent ExecCommand",function(t){("setcontent"==t.type||"mceInsertLink"===t.command)&&e()})}function R(){J.forced_root_block&&s.on("init",function(){l("DefaultParagraphSeparator",J.forced_root_block)})}function A(){s.on("Undo Redo SetContent",function(e){e.initial||s.execCommand("mceRepaint")})}function B(){s.on("keydown",function(e){var t;u(e)||e.keyCode!=K||(t=s.getDoc().selection.createRange(),t&&t.item&&(e.preventDefault(),s.undoManager.beforeChange(),G.remove(t.item(0)),s.undoManager.add()))})}function D(){var e;c()>=10&&(e="",q("p div h1 h2 h3 h4 h5 h6".split(" "),function(t,n){e+=(n>0?",":"")+t+":empty"}),s.contentStyles.push(e+"{padding-right: 1px !important}"))}function M(){c()<9&&(Q.addNodeFilter("noscript",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.firstChild,r&&n.attr("data-mce-innertext",r.value)}),Z.addNodeFilter("noscript",function(e){for(var t=e.length,n,o,a;t--;)n=e[t],o=e[t].firstChild,o?o.value=i.decode(o.value):(a=n.attributes.map["data-mce-innertext"],a&&(n.attr("data-mce-innertext",null),o=new r("#text",3),o.value=a,o.raw=!0,n.append(o)))}))}function L(){function e(e,t){var n=i.createTextRange();try{n.moveToPoint(e,t)}catch(r){n=null}return n}function t(t){var r;t.button?(r=e(t.x,t.y),r&&(r.compareEndPoints("StartToStart",a)>0?r.setEndPoint("StartToStart",a):r.setEndPoint("EndToEnd",a),r.select())):n()}function n(){var e=r.selection.createRange();a&&!e.item&&0===e.compareEndPoints("StartToEnd",e)&&a.select(),G.unbind(r,"mouseup",n),G.unbind(r,"mousemove",t),a=o=0}var r=G.doc,i=r.body,o,a,s;r.documentElement.unselectable=!0,G.bind(r,"mousedown contextmenu",function(i){if("HTML"===i.target.nodeName){if(o&&n(),s=r.documentElement,s.scrollHeight>s.clientHeight)return;o=1,a=e(i.x,i.y),a&&(G.bind(r,"mouseup",n),G.bind(r,"mousemove",t),G.getRoot().focus(),a.select())}})}function H(){s.on("keyup focusin mouseup",function(t){65==t.keyCode&&e.metaKeyPressed(t)||X.normalize()},!0)}function P(){s.contentStyles.push("img:-moz-broken {-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}")}function O(){s.inline||s.on("keydown",function(){document.activeElement==document.body&&s.getWin().focus()})}function I(){s.inline||(s.contentStyles.push("body {min-height: 150px}"),s.on("click",function(e){var t;if("HTML"==e.target.nodeName){if(o.ie>11)return void s.getBody().focus();t=s.selection.getRng(),s.getBody().focus(),s.selection.setRng(t),s.selection.normalize(),s.nodeChanged()}}))}function F(){o.mac&&s.on("keydown",function(t){!e.metaKeyPressed(t)||t.shiftKey||37!=t.keyCode&&39!=t.keyCode||(t.preventDefault(),s.selection.getSel().modify("move",37==t.keyCode?"backward":"forward","lineboundary"))})}function z(){l("AutoUrlDetect",!1)}function W(){s.on("click",function(e){var t=e.target;do if("A"===t.tagName)return void e.preventDefault();while(t=t.parentNode)}),s.contentStyles.push(".mce-content-body {-webkit-touch-callout: none}")}function V(){s.on("init",function(){s.dom.bind(s.getBody(),"submit",function(e){e.preventDefault()})})}function U(){Q.addNodeFilter("br",function(e){for(var t=e.length;t--;)"Apple-interchange-newline"==e[t].attr("class")&&e[t].remove()})}function $(){s.on("dragstart",function(e){d(e)}),s.on("drop",function(e){if(!u(e)){var n=f(e);if(n&&n.id!=s.id){e.preventDefault();var r=t.getCaretRangeFromPoint(e.x,e.y,s.getDoc());X.setRng(r),h(n.html)}}})}var q=a.each,j=s.$,K=e.BACKSPACE,Y=e.DELETE,G=s.dom,X=s.selection,J=s.settings,Q=s.parser,Z=s.serializer,ee=o.gecko,te=o.ie,ne=o.webkit,re="data:text/mce-internal,",ie=te?"Text":"URL";S(),m(),H(),ne&&(p(),v(),x(),R(),V(),_(),U(),o.iOS?(O(),I(),W()):g()),te&&o.ie<11&&(y(),w(),E(),N(),B(),D(),M(),L()),o.ie>=11&&(I(),_()),o.ie&&(g(),z(),$()),ee&&(y(),b(),C(),k(),T(),A(),P(),F(),_())}}),r(me,[K,b,f],function(e,t,n){function r(e,t){return"selectionchange"==t?e.getDoc():!e.inline&&/^mouse|click|contextmenu|drop|dragover|dragend/.test(t)?e.getDoc().documentElement:e.settings.event_root?(e.eventRoot||(e.eventRoot=o.select(e.settings.event_root)[0]),e.eventRoot):e.getBody()}function i(e,t){var n=r(e,t),i;if(e.delegates||(e.delegates={}),!e.delegates[t])if(e.settings.event_root){if(a||(a={},e.editorManager.on("removeEditor",function(){var t;if(!e.editorManager.activeEditor&&a){for(t in a)e.dom.unbind(r(e,t));a=null}})),a[t])return;i=function(n){for(var r=n.target,i=e.editorManager.editors,a=i.length;a--;){var s=i[a].getBody();(s===r||o.isChildOf(r,s))&&(i[a].hidden||i[a].fire(t,n))}},a[t]=i,o.bind(n,t,i)}else i=function(n){e.hidden||e.fire(t,n)},o.bind(n,t,i),e.delegates[t]=i}var o=t.DOM,a,s={bindPendingEventDelegates:function(){var e=this;n.each(e._pendingNativeEvents,function(t){i(e,t)})},toggleNativeEvent:function(e,t){var n=this;n.settings.readonly||"focus"!=e&&"blur"!=e&&(t?n.initialized?i(n,e):n._pendingNativeEvents?n._pendingNativeEvents.push(e):n._pendingNativeEvents=[e]:n.initialized&&(n.dom.unbind(r(n,e),e,n.delegates[e]),delete n.delegates[e]))},unbindAllNativeEvents:function(){var e=this,t;if(e.delegates){for(t in e.delegates)e.dom.unbind(r(e,t),t,e.delegates[t]);delete e.delegates}e.inline||(e.getBody().onload=null,e.dom.unbind(e.getWin()),e.dom.unbind(e.getDoc())),e.dom.unbind(e.getBody()),e.dom.unbind(e.getContainer())}};return s=n.extend({},e,s)}),r(ge,[f,u],function(e,t){var n=e.each,r=e.explode,i={f9:120,f10:121,f11:122},o=e.makeMap("alt,ctrl,shift,meta,access");return function(a){function s(e,s,l,c){var u,d,f;f={func:l,scope:c||a,desc:a.translate(s)},n(r(e,"+"),function(e){e in o?f[e]=!0:/^[0-9]{2,}$/.test(e)?f.keyCode=parseInt(e,10):(f.charCode=e.charCodeAt(0),f.keyCode=i[e]||e.toUpperCase().charCodeAt(0))}),u=[f.keyCode];for(d in o)f[d]?u.push(d):f[d]=!1;return f.id=u.join(","),f.access&&(f.alt=!0,t.mac?f.ctrl=!0:f.shift=!0),f.meta&&(t.mac?f.meta=!0:(f.ctrl=!0,f.meta=!1)),f}var l=this,c={};a.on("keyup keypress keydown",function(e){(e.altKey||e.ctrlKey||e.metaKey)&&!e.isDefaultPrevented()&&n(c,function(t){return t.ctrl==e.ctrlKey&&t.meta==e.metaKey&&t.alt==e.altKey&&t.shift==e.shiftKey&&(e.keyCode==t.keyCode||e.charCode&&e.charCode==t.charCode)?(e.preventDefault(),"keydown"==e.type&&t.func.call(t.scope),!0):void 0})}),l.add=function(t,i,o,l){var u;return u=o,"string"==typeof o?o=function(){a.execCommand(u,!1,null)}:e.isArray(u)&&(o=function(){a.execCommand(u[0],u[1],u[2])}),n(r(t.toLowerCase()),function(e){var t=s(e,i,o,l);c[t.id]=t}),!0},l.remove=function(e){var t=s(e);return c[t.id]?(delete c[t.id],!0):!1}}}),r(ve,[],function(){function e(e,t){return function(){e.apply(t,arguments)}}function t(t){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof t)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],s(t,e(r,this),e(i,this))}function n(e){var t=this;return null===this._state?void this._deferreds.push(e):void l(function(){var n=t._state?e.onFulfilled:e.onRejected;if(null===n)return void(t._state?e.resolve:e.reject)(t._value);var r;try{r=n(t._value)}catch(i){return void e.reject(i)}e.resolve(r)})}function r(t){try{if(t===this)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if("function"==typeof n)return void s(e(n,t),e(r,this),e(i,this))}this._state=!0,this._value=t,o.call(this)}catch(a){i.call(this,a)}}function i(e){this._state=!1,this._value=e,o.call(this)}function o(){for(var e=0,t=this._deferreds.length;t>e;e++)n.call(this,this._deferreds[e]);this._deferreds=null}function a(e,t,n,r){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof t?t:null,this.resolve=n,this.reject=r}function s(e,t,n){var r=!1;try{e(function(e){r||(r=!0,t(e))},function(e){r||(r=!0,n(e))})}catch(i){if(r)return;r=!0,n(i)}}if(window.Promise)return window.Promise;var l=t.immediateFn||"function"==typeof setImmediate&&setImmediate||function(e){setTimeout(e,1)},c=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};return t.prototype["catch"]=function(e){return this.then(null,e)},t.prototype.then=function(e,r){var i=this;return new t(function(t,o){n.call(i,new a(e,r,t,o))})},t.all=function(){var e=Array.prototype.slice.call(1===arguments.length&&c(arguments[0])?arguments[0]:arguments);return new t(function(t,n){function r(o,a){try{if(a&&("object"==typeof a||"function"==typeof a)){var s=a.then;if("function"==typeof s)return void s.call(a,function(e){r(o,e)},n)}e[o]=a,0===--i&&t(e)}catch(l){n(l)}}if(0===e.length)return t([]);for(var i=e.length,o=0;or;r++)e[r].then(t,n)})},t}),r(ye,[],function(){function e(e){return function(){return e}}return{constant:e}}),r(be,[ve,f,ye],function(e,t,n){return function(r){function i(e){var t,n;return n={"image/jpeg":"jpg","image/jpg":"jpg","image/gif":"gif","image/png":"png"},t=n[e.blob().type.toLowerCase()]||"dat",e.id()+"."+t}function o(e,t){return e?e.replace(/\/$/,"")+"/"+t.replace(/^\//,""):t}function a(e){return{id:e.id,blob:e.blob,base64:e.base64,filename:n.constant(i(e))}}function s(e,t,n){var a,s;a=new XMLHttpRequest,a.open("POST",r.url),a.withCredentials=r.credentials,a.onload=function(){var e;return 200!=a.status?void n("HTTP Error: "+a.status):(e=JSON.parse(a.responseText),e&&"string"==typeof e.location?void t(o(r.basePath,e.location)):void n("Invalid JSON: "+a.responseText))},s=new FormData,s.append("file",e.blob(),i(e)),a.send(s)}function l(n){function i(t){return new e(function(e){var n=r.handler;n(a(t),function(n){e({url:n,blobInfo:t,status:!0})},function(n){e({url:"",blobInfo:t,status:!1,error:n})})})}var o;return r.url||r.handler!==s?(o=t.map(n,function(e){var t,n=e.id();return c[n]?c[n]:(t=i(e).then(function(e){return delete c[n],e})["catch"](function(e){return delete c[n],e}),c[n]=t,t)}),e.all(o)):new e(function(e){e([])})}var c={};return r=t.extend({credentials:!1,handler:s},r),{upload:l}}}),r(xe,[ve],function(e){function t(t){return new e(function(e){var n=new XMLHttpRequest;n.open("GET",t,!0),n.responseType="blob",n.onload=function(){200==this.status&&e(this.response)},n.send()})}function n(e){var t,n;return e=decodeURIComponent(e).split(","),n=/data:([^;]+)/.exec(e[0]),n&&(t=n[1]),{type:t,data:e[1]}}function r(t){return new e(function(e){var r,i,o;t=n(t);try{r=atob(t.data)}catch(a){return void e(new Blob([]))}for(i=new Uint8Array(r.length),o=0;o",visual:!0,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",font_size_legacy_values:"xx-small,small,medium,large,x-large,xx-large,300%",forced_root_block:"p",hidden_input:!0,padd_empty_editor:!0,render_ui:!0,indentation:"30px",inline_styles:!0,convert_fonts_to_spans:!0,indent:"simple",indent_before:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",indent_after:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",validate:!0,entity_encoding:"named",url_converter:o.convertURL,url_converter_scope:o,ie7_compat:!0},t),r.language=t.language||"en",r.languageLoad=t.language_load,r.baseURL=i.baseURL,o.id=t.id=e,o.isNotDirty=!0,o.plugins={},o.documentBaseURI=new p(t.document_base_url||a,{base_uri:s}),o.baseURI=s,o.contentCSS=[],o.contentStyles=[],o.shortcuts=new E(o),o.loadedCSS={},o.editorCommands=new h(o),t.target&&(o.targetElm=t.target),o.suffix=i.suffix,o.editorManager=i,o.inline=t.inline,t.cache_suffix&&(C.cacheSuffix=t.cache_suffix.replace(/^[\?\&]+/,"")),t.override_viewport===!1&&(C.overrideViewPort=!1),i.fire("SetupEditor",o),o.execCallback("setup",o),o.$=n.overrideDefaults(function(){return{context:o.inline?o.getBody():o.getDoc(),element:o.getBody()}})}var k=e.DOM,T=r.ThemeManager,R=r.PluginManager,A=w.extend,B=w.each,D=w.explode,M=w.inArray,L=w.trim,H=w.resolve,P=g.Event,O=C.gecko,I=C.ie;return S.prototype={render:function(){function e(){k.unbind(window,"ready",e),n.render()}function t(){var e=m.ScriptLoader;if(r.language&&"en"!=r.language&&!r.language_url&&(r.language_url=n.editorManager.baseURL+"/langs/"+r.language+".js"),r.language_url&&e.add(r.language_url),r.theme&&"function"!=typeof r.theme&&"-"!=r.theme.charAt(0)&&!T.urls[r.theme]){var t=r.theme_url;t=t?n.documentBaseURI.toAbsolute(t):"themes/"+r.theme+"/theme"+o+".js",T.load(r.theme,t)}w.isArray(r.plugins)&&(r.plugins=r.plugins.join(" ")),B(r.external_plugins,function(e,t){R.load(t,e),r.plugins+=" "+t}),B(r.plugins.split(/[ ,]/),function(e){if(e=L(e),e&&!R.urls[e])if("-"==e.charAt(0)){e=e.substr(1,e.length);var t=R.dependencies(e);B(t,function(e){var t={prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"};e=R.createUrl(t,e),R.load(e.resource,e)})}else R.load(e,{prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"})}),e.loadQueue(function(){n.removed||n.init()})}var n=this,r=n.settings,i=n.id,o=n.suffix;if(!P.domLoaded)return void k.bind(window,"ready",e);if(n.getElement()&&C.contentEditable){r.inline?n.inline=!0:(n.orgVisibility=n.getElement().style.visibility,n.getElement().style.visibility="hidden");var a=n.getElement().form||k.getParent(i,"form");a&&(n.formElement=a,r.hidden_input&&!/TEXTAREA|INPUT/i.test(n.getElement().nodeName)&&(k.insertAfter(k.create("input",{type:"hidden",name:i}),i),n.hasHiddenInput=!0),n.formEventDelegate=function(e){n.fire(e.type,e)},k.bind(a,"submit reset",n.formEventDelegate),n.on("reset",function(){n.setContent(n.startContent,{format:"raw"})}),!r.submit_patch||a.submit.nodeType||a.submit.length||a._mceOldSubmit||(a._mceOldSubmit=a.submit,a.submit=function(){return n.editorManager.triggerSave(),n.isNotDirty=!0,a._mceOldSubmit(a)})),n.windowManager=new v(n),"xml"==r.encoding&&n.on("GetContent",function(e){e.save&&(e.content=k.encode(e.content))}),r.add_form_submit_trigger&&n.on("submit",function(){n.initialized&&n.save()}),r.add_unload_trigger&&(n._beforeUnload=function(){!n.initialized||n.destroyed||n.isHidden()||n.save({format:"raw",no_events:!0,set_dirty:!1})},n.editorManager.on("BeforeUnload",n._beforeUnload)),t()}},init:function(){function e(n){var r=R.get(n),i,o;i=R.urls[n]||t.documentBaseUrl.replace(/\/$/,""),n=L(n),r&&-1===M(m,n)&&(B(R.dependencies(n),function(t){e(t)}),o=new r(t,i,t.$),t.plugins[n]=o,o.init&&(o.init(t,i),m.push(n)))}var t=this,n=t.settings,r=t.getElement(),i,o,a,s,l,c,u,d,f,h,p,m=[];if(this.editorManager.i18n.setCode(n.language),t.rtl=n.rtl_ui||this.editorManager.i18n.rtl,t.editorManager.add(t),n.aria_label=n.aria_label||k.getAttrib(r,"aria-label",t.getLang("aria.rich_text_area")),n.theme&&("function"!=typeof n.theme?(n.theme=n.theme.replace(/-/,""),c=T.get(n.theme),t.theme=new c(t,T.urls[n.theme]),t.theme.init&&t.theme.init(t,T.urls[n.theme]||t.documentBaseUrl.replace(/\/$/,""),t.$)):t.theme=n.theme),B(n.plugins.replace(/\-/g,"").split(/[ ,]/),e),n.render_ui&&t.theme&&(t.orgDisplay=r.style.display,"function"!=typeof n.theme?(i=n.width||r.style.width||r.offsetWidth,o=n.height||r.style.height||r.offsetHeight,a=n.min_height||100,h=/^[0-9\.]+(|px)$/i,h.test(""+i)&&(i=Math.max(parseInt(i,10),100)),h.test(""+o)&&(o=Math.max(parseInt(o,10),a)),l=t.theme.renderUI({targetNode:r,width:i,height:o,deltaWidth:n.delta_width,deltaHeight:n.delta_height}),n.content_editable||(o=(l.iframeHeight||o)+("number"==typeof o?l.deltaHeight||0:""),a>o&&(o=a))):(l=n.theme(t,r),l.editorContainer.nodeType&&(l.editorContainer=l.editorContainer.id=l.editorContainer.id||t.id+"_parent"),l.iframeContainer.nodeType&&(l.iframeContainer=l.iframeContainer.id=l.iframeContainer.id||t.id+"_iframecontainer"),o=l.iframeHeight||r.offsetHeight),t.editorContainer=l.editorContainer),n.content_css&&B(D(n.content_css),function(e){t.contentCSS.push(t.documentBaseURI.toAbsolute(e))}),n.content_style&&t.contentStyles.push(n.content_style),n.content_editable)return r=s=l=null,t.initContentBody();for(t.iframeHTML=n.doctype+"",n.document_base_url!=t.documentBaseUrl&&(t.iframeHTML+=''),!C.caretAfter&&n.ie7_compat&&(t.iframeHTML+=''),t.iframeHTML+='',p=0;p',t.loadedCSS[g]=!0}d=n.body_id||"tinymce",-1!=d.indexOf("=")&&(d=t.getParam("body_id","","hash"),d=d[t.id]||d),f=n.body_class||"",-1!=f.indexOf("=")&&(f=t.getParam("body_class","","hash"),f=f[t.id]||""),n.content_security_policy&&(t.iframeHTML+=''),t.iframeHTML+='
';var v='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinymce.get("'+t.id+'");document.write(ed.iframeHTML);document.close();ed.initContentBody(true);})()';document.domain!=location.hostname&&C.ie&&C.ie<12&&(u=v);var y=k.create("iframe",{id:t.id+"_ifr",frameBorder:"0",allowTransparency:"true",title:t.editorManager.translate("Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help"),style:{width:"100%",height:o,display:"block"}});if(y.onload=function(){y.onload=null,t.fire("load")},k.setAttrib(y,"src",u||'javascript:""'),t.contentAreaContainer=l.iframeContainer,t.iframeElement=y,s=k.add(l.iframeContainer,y),I)try{t.getDoc()}catch(b){s.src=u=v}l.editorContainer&&(k.get(l.editorContainer).style.display=t.orgDisplay,t.hidden=k.isHidden(l.editorContainer)),t.getElement().style.display="none",k.setAttrib(t.id,"aria-hidden",!0),u||t.initContentBody(),r=s=l=null},initContentBody:function(t){var n=this,r=n.settings,s=n.getElement(),h=n.getDoc(),p,m;r.inline||(n.getElement().style.visibility=n.orgVisibility),t||r.content_editable||(h.open(),h.write(n.iframeHTML),h.close()),r.content_editable&&(n.on("remove",function(){var e=this.getBody();k.removeClass(e,"mce-content-body"),k.removeClass(e,"mce-edit-focus"),k.setAttrib(e,"contentEditable",null)}),k.addClass(s,"mce-content-body"),n.contentDocument=h=r.content_document||document,n.contentWindow=r.content_window||window,n.bodyElement=s,r.content_document=r.content_window=null,r.root_name=s.nodeName.toLowerCase()),p=n.getBody(),p.disabled=!0,r.readonly||(n.inline&&"static"==k.getStyle(p,"position",!0)&&(p.style.position="relative"),p.contentEditable=n.getParam("content_editable_state",!0)),p.disabled=!1,n.editorUpload=new N(n),n.schema=new y(r),n.dom=new e(h,{keep_values:!0,url_converter:n.convertURL,url_converter_scope:n,hex_colors:r.force_hex_style_colors,class_filter:r.class_filter,update_styles:!0,root_element:n.inline?n.getBody():null,collect:r.content_editable,schema:n.schema,onSetAttrib:function(e){n.fire("SetAttrib",e)}}),n.parser=new b(r,n.schema),n.parser.addAttributeFilter("src,href,style,tabindex",function(e,t){for(var r=e.length,i,o=n.dom,a,s;r--;)if(i=e[r],a=i.attr(t),s="data-mce-"+t,!i.attributes.map[s]){if(0===a.indexOf("data:")||0===a.indexOf("blob:"))continue;"style"===t?(a=o.serializeStyle(o.parseStyle(a),i.name),a.length||(a=null),i.attr(s,a),i.attr(t,a)):"tabindex"===t?(i.attr(s,a),i.attr(t,null)):i.attr(s,n.convertURL(a,t,i.name))}}),n.parser.addNodeFilter("script",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("type","mce-"+(n.attr("type")||"no/type"))}),n.parser.addNodeFilter("#cdata",function(e){for(var t=e.length,n;t--;)n=e[t],n.type=8,n.name="#comment",n.value="[CDATA["+n.value+"]]"}),n.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(e){for(var t=e.length,r,i=n.schema.getNonEmptyElements();t--;)r=e[t],r.isEmpty(i)&&(r.append(new o("br",1)).shortEnded=!0)}),n.serializer=new a(r,n),n.selection=new l(n.dom,n.getWin(),n.serializer,n),n.formatter=new c(n),n.undoManager=new u(n),n.forceBlocks=new f(n),n.enterKey=new d(n),n._nodeChangeDispatcher=new i(n),n.fire("PreInit"),r.browser_spellcheck||r.gecko_spellcheck||(h.body.spellcheck=!1,k.setAttrib(p,"spellcheck","false")),n.fire("PostRender"),n.quirks=new x(n),r.directionality&&(p.dir=r.directionality),r.nowrap&&(p.style.whiteSpace="nowrap"),r.protect&&n.on("BeforeSetContent",function(e){B(r.protect,function(t){e.content=e.content.replace(t,function(e){return""})})}),n.on("SetContent",function(){n.addVisual(n.getBody())}),r.padd_empty_editor&&n.on("PostProcess",function(e){e.content=e.content.replace(/^(]*>( | |\s|\u00a0|)<\/p>[\r\n]*|
[\r\n]*)$/,"")}),n.load({initial:!0,format:"html"}),n.startContent=n.getContent({format:"raw"}),n.initialized=!0,n.bindPendingEventDelegates(),n.fire("init"),n.focus(!0),n.nodeChanged({initial:!0}),n.execCallback("init_instance_callback",n),n.contentStyles.length>0&&(m="",B(n.contentStyles,function(e){m+=e+"\r\n"}),n.dom.addStyle(m)),B(n.contentCSS,function(e){n.loadedCSS[e]||(n.dom.loadCSS(e),n.loadedCSS[e]=!0)}),r.auto_focus&&setTimeout(function(){var e;e=r.auto_focus===!0?n:n.editorManager.get(r.auto_focus),e.destroyed||e.focus()},100),s=h=p=null},focus:function(e){var t=this,n=t.selection,r=t.settings.content_editable,i,o,a=t.getDoc(),s;if(!e){if(i=n.getRng(),i.item&&(o=i.item(0)),t._refreshContentEditable(),r||(C.opera||t.getBody().focus(),t.getWin().focus()),O||r){if(s=t.getBody(),s.setActive)try{s.setActive()}catch(l){s.focus()}else s.focus();r&&n.normalize()}o&&o.ownerDocument==a&&(i=a.body.createControlRange(),i.addElement(o),i.select())}t.editorManager.setActive(t)},execCallback:function(e){var t=this,n=t.settings[e],r;if(n)return t.callbackLookup&&(r=t.callbackLookup[e])&&(n=r.func,r=r.scope),"string"==typeof n&&(r=n.replace(/\.\w+$/,""),r=r?H(r):0,n=H(n),t.callbackLookup=t.callbackLookup||{},t.callbackLookup[e]={func:n,scope:r}),n.apply(r||t,Array.prototype.slice.call(arguments,1))},translate:function(e){var t=this.settings.language||"en",n=this.editorManager.i18n;return e?n.data[t+"."+e]||e.replace(/\{\#([^\}]+)\}/g,function(e,r){ -return n.data[t+"."+r]||"{#"+r+"}"}):""},getLang:function(e,n){return this.editorManager.i18n.data[(this.settings.language||"en")+"."+e]||(n!==t?n:"{#"+e+"}")},getParam:function(e,t,n){var r=e in this.settings?this.settings[e]:t,i;return"hash"===n?(i={},"string"==typeof r?B(r.indexOf("=")>0?r.split(/[;,](?![^=;,]*(?:[;,]|$))/):r.split(","),function(e){e=e.split("="),e.length>1?i[L(e[0])]=L(e[1]):i[L(e[0])]=L(e)}):i=r,i):r},nodeChanged:function(e){this._nodeChangeDispatcher.nodeChanged(e)},addButton:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),t.text||t.icon||(t.icon=e),n.buttons=n.buttons||{},t.tooltip=t.tooltip||t.title,n.buttons[e]=t},addMenuItem:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),n.menuItems=n.menuItems||{},n.menuItems[e]=t},addContextToolbar:function(e,t){var n=this,r;n.contextToolbars=n.contextToolbars||[],"string"==typeof e&&(r=e,e=function(e){return n.dom.is(e,r)}),n.contextToolbars.push({predicate:e,items:t})},addCommand:function(e,t,n){this.editorCommands.addCommand(e,t,n)},addQueryStateHandler:function(e,t,n){this.editorCommands.addQueryStateHandler(e,t,n)},addQueryValueHandler:function(e,t,n){this.editorCommands.addQueryValueHandler(e,t,n)},addShortcut:function(e,t,n,r){this.shortcuts.add(e,t,n,r)},execCommand:function(e,t,n,r){return this.editorCommands.execCommand(e,t,n,r)},queryCommandState:function(e){return this.editorCommands.queryCommandState(e)},queryCommandValue:function(e){return this.editorCommands.queryCommandValue(e)},queryCommandSupported:function(e){return this.editorCommands.queryCommandSupported(e)},show:function(){var e=this;e.hidden&&(e.hidden=!1,e.inline?e.getBody().contentEditable=!0:(k.show(e.getContainer()),k.hide(e.id)),e.load(),e.fire("show"))},hide:function(){var e=this,t=e.getDoc();e.hidden||(I&&t&&!e.inline&&t.execCommand("SelectAll"),e.save(),e.inline?(e.getBody().contentEditable=!1,e==e.editorManager.focusedEditor&&(e.editorManager.focusedEditor=null)):(k.hide(e.getContainer()),k.setStyle(e.id,"display",e.orgDisplay)),e.hidden=!0,e.fire("hide"))},isHidden:function(){return!!this.hidden},setProgressState:function(e,t){this.fire("ProgressState",{state:e,time:t})},load:function(e){var n=this,r=n.getElement(),i;return r?(e=e||{},e.load=!0,i=n.setContent(r.value!==t?r.value:r.innerHTML,e),e.element=r,e.no_events||n.fire("LoadContent",e),e.element=r=null,i):void 0},save:function(e){var t=this,n=t.getElement(),r,i;if(n&&t.initialized)return e=e||{},e.save=!0,e.element=n,r=e.content=t.getContent(e),e.no_events||t.fire("SaveContent",e),"raw"==e.format&&t.fire("RawSaveContent",e),r=e.content,/TEXTAREA|INPUT/i.test(n.nodeName)?n.value=r:(t.inline||(n.innerHTML=r),(i=k.getParent(t.id,"form"))&&B(i.elements,function(e){return e.name==t.id?(e.value=r,!1):void 0})),e.element=n=null,e.set_dirty!==!1&&(t.isNotDirty=!0),r},setContent:function(e,t){var n=this,r=n.getBody(),i;return t=t||{},t.format=t.format||"html",t.set=!0,t.content=e,t.no_events||n.fire("BeforeSetContent",t),e=t.content,0===e.length||/^\s+$/.test(e)?(i=n.settings.forced_root_block,i&&n.schema.isValidChild(r.nodeName.toLowerCase(),i.toLowerCase())?(e=I&&11>I?"":'
',e=n.dom.createHTML(i,n.settings.forced_root_block_attrs,e)):I||(e='
'),n.dom.setHTML(r,e),n.fire("SetContent",t)):("raw"!==t.format&&(e=new s({},n.schema).serialize(n.parser.parse(e,{isRootContent:!0}))),t.content=L(e),n.dom.setHTML(r,t.content),t.no_events||n.fire("SetContent",t)),t.content},getContent:function(e){var t=this,n,r=t.getBody();return e=e||{},e.format=e.format||"html",e.get=!0,e.getInner=!0,e.no_events||t.fire("BeforeGetContent",e),n="raw"==e.format?r.innerHTML:"text"==e.format?r.innerText||r.textContent:t.serializer.serialize(r,e),"text"!=e.format?e.content=L(n):e.content=n,e.no_events||t.fire("GetContent",e),e.content},insertContent:function(e,t){t&&(e=A({content:e},t)),this.execCommand("mceInsertContent",!1,e)},isDirty:function(){return!this.isNotDirty},getContainer:function(){var e=this;return e.container||(e.container=k.get(e.editorContainer||e.id+"_parent")),e.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return this.targetElm||(this.targetElm=k.get(this.id)),this.targetElm},getWin:function(){var e=this,t;return e.contentWindow||(t=e.iframeElement,t&&(e.contentWindow=t.contentWindow)),e.contentWindow},getDoc:function(){var e=this,t;return e.contentDocument||(t=e.getWin(),t&&(e.contentDocument=t.document)),e.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(e,t,n){var r=this,i=r.settings;return i.urlconverter_callback?r.execCallback("urlconverter_callback",e,n,!0,t):!i.convert_urls||n&&"LINK"==n.nodeName||0===e.indexOf("file:")||0===e.length?e:i.relative_urls?r.documentBaseURI.toRelative(e):e=r.documentBaseURI.toAbsolute(e,i.remove_script_host)},addVisual:function(e){var n=this,r=n.settings,i=n.dom,o;e=e||n.getBody(),n.hasVisual===t&&(n.hasVisual=r.visual),B(i.select("table,a",e),function(e){var t;switch(e.nodeName){case"TABLE":return o=r.visual_table_class||"mce-item-table",t=i.getAttrib(e,"border"),void(t&&"0"!=t||!n.hasVisual?i.removeClass(e,o):i.addClass(e,o));case"A":return void(i.getAttrib(e,"href",!1)||(t=i.getAttrib(e,"name")||e.id,o=r.visual_anchor_class||"mce-item-anchor",t&&n.hasVisual?i.addClass(e,o):i.removeClass(e,o)))}}),n.fire("VisualAid",{element:e,hasVisual:n.hasVisual})},remove:function(){var e=this;e.removed||(e.save(),e.removed=1,e.unbindAllNativeEvents(),e.hasHiddenInput&&k.remove(e.getElement().nextSibling),e.inline||(I&&10>I&&e.getDoc().execCommand("SelectAll",!1,null),k.setStyle(e.id,"display",e.orgDisplay),e.getBody().onload=null),e.fire("remove"),e.editorManager.remove(e),k.remove(e.getContainer()),e.editorUpload.destroy(),e.destroy())},destroy:function(e){var t=this,n;if(!t.destroyed){if(!e&&!t.removed)return void t.remove();e||(t.editorManager.off("beforeunload",t._beforeUnload),t.theme&&t.theme.destroy&&t.theme.destroy(),t.selection.destroy(),t.dom.destroy()),n=t.formElement,n&&(n._mceOldSubmit&&(n.submit=n._mceOldSubmit,n._mceOldSubmit=null),k.unbind(n,"submit reset",t.formEventDelegate)),t.contentAreaContainer=t.formElement=t.container=t.editorContainer=null,t.bodyElement=t.contentDocument=t.contentWindow=null,t.iframeElement=t.targetElm=null,t.selection&&(t.selection=t.selection.win=t.selection.dom=t.selection.dom.doc=null),t.destroyed=1}},uploadImages:function(e){return this.editorUpload.uploadImages(e)},_scanForImages:function(){return this.editorUpload.scanForImages()},_refreshContentEditable:function(){var e=this,t,n;e._isHidden()&&(t=e.getBody(),n=t.parentNode,n.removeChild(t),n.appendChild(t),t.focus())},_isHidden:function(){var e;return O?(e=this.selection.getSel(),!e||!e.rangeCount||0===e.rangeCount):0}},A(S.prototype,_),S}),r(Ne,[],function(){var e={},t="en";return{setCode:function(e){e&&(t=e,this.rtl=this.data[e]?"rtl"===this.data[e]._dir:!1)},getCode:function(){return t},rtl:!1,add:function(t,n){var r=e[t];r||(e[t]=r={});for(var i in n)r[i]=n[i];this.setCode(t)},translate:function(n){var r;if(r=e[t],r||(r={}),"undefined"==typeof n)return n;if("string"!=typeof n&&n.raw)return n.raw;if(n.push){var i=n.slice(1);n=(r[n[0]]||n[0]).replace(/\{([0-9]+)\}/g,function(e,t){return i[t]})}return(r[n]||n).replace(/{context:\w+}$/,"")},data:e}}),r(Se,[b,u],function(e,t){function n(e){function s(){try{return document.activeElement}catch(e){return document.body}}function l(e,t){if(t&&t.startContainer){if(!e.isChildOf(t.startContainer,e.getRoot())||!e.isChildOf(t.endContainer,e.getRoot()))return;return{startContainer:t.startContainer,startOffset:t.startOffset,endContainer:t.endContainer,endOffset:t.endOffset}}return t}function c(e,t){var n;return t.startContainer?(n=e.getDoc().createRange(),n.setStart(t.startContainer,t.startOffset),n.setEnd(t.endContainer,t.endOffset)):n=t,n}function u(e){return!!a.getParent(e,n.isEditorUIElement)}function d(n){var d=n.editor;d.on("init",function(){(d.inline||t.ie)&&("onbeforedeactivate"in document&&t.ie<9?d.dom.bind(d.getBody(),"beforedeactivate",function(e){if(e.target==d.getBody())try{d.lastRng=d.selection.getRng()}catch(t){}}):d.on("nodechange mouseup keyup",function(e){var t=s();"nodechange"==e.type&&e.selectionChange||(t&&t.id==d.id+"_ifr"&&(t=d.getBody()),d.dom.isChildOf(t,d.getBody())&&(d.lastRng=d.selection.getRng()))}),t.webkit&&!r&&(r=function(){var t=e.activeEditor;if(t&&t.selection){var n=t.selection.getRng();n&&!n.collapsed&&(d.lastRng=n)}},a.bind(document,"selectionchange",r)))}),d.on("setcontent",function(){d.lastRng=null}),d.on("mousedown",function(){d.selection.lastFocusBookmark=null}),d.on("focusin",function(){var t=e.focusedEditor;d.selection.lastFocusBookmark&&(d.selection.setRng(c(d,d.selection.lastFocusBookmark)),d.selection.lastFocusBookmark=null),t!=d&&(t&&t.fire("blur",{focusedEditor:d}),e.setActive(d),e.focusedEditor=d,d.fire("focus",{blurredEditor:t}),d.focus(!0)),d.lastRng=null}),d.on("focusout",function(){window.setTimeout(function(){var t=e.focusedEditor;u(s())||t!=d||(d.fire("blur",{focusedEditor:null}),e.focusedEditor=null,d.selection&&(d.selection.lastFocusBookmark=null))},0)}),i||(i=function(t){var n=e.activeEditor;n&&t.target.ownerDocument==document&&(n.selection&&t.target!=n.getBody()&&(n.selection.lastFocusBookmark=l(n.dom,n.lastRng)),t.target==document.body||u(t.target)||e.focusedEditor!=n||(n.fire("blur",{focusedEditor:null}),e.focusedEditor=null))},a.bind(document,"focusin",i)),d.inline&&!o&&(o=function(t){var n=e.activeEditor;if(n.inline&&!n.dom.isChildOf(t.target,n.getBody())){var r=n.selection.getRng();r.collapsed||(n.lastRng=r)}},a.bind(document,"mouseup",o))}function f(t){e.focusedEditor==t.editor&&(e.focusedEditor=null),e.activeEditor||(a.unbind(document,"selectionchange",r),a.unbind(document,"focusin",i),a.unbind(document,"mouseup",o),r=i=o=null)}e.on("AddEditor",d),e.on("RemoveEditor",f)}var r,i,o,a=e.DOM;return n.isEditorUIElement=function(e){return-1!==e.className.toString().indexOf("mce-")},n}),r(ke,[Ee,h,b,U,u,f,K,Ne,Se],function(e,t,n,r,i,o,a,s,l){function c(e){m(b.editors,function(t){t.fire("ResizeWindow",e)})}function u(e,n){n!==x&&(n?t(window).on("resize",c):t(window).off("resize",c),x=n)}function d(e){var t=b.editors,n;delete t[e.id];for(var r=0;r0&&m(p(e),function(e){var n;(n=h.get(e))?r(e,t,n):m(document.forms,function(n){m(n.elements,function(n){n.name===e&&(e="mce_editor_"+v++,h.setAttrib(n,"id",e),r(e,t,n))})})});break;case"textareas":case"specific_textareas":m(h.select("textarea"),function(e){t.editor_deselector&&o(e,t.editor_deselector)||(!t.editor_selector||o(e,t.editor_selector))&&r(n(e),t,e)})}t.oninit&&(e=s=0,m(l,function(t){s++,t.initialized?e++:t.on("init",function(){e++,e==s&&i("oninit")}),e==s&&i("oninit")}))}var s=this,l=[];s.settings=t,h.bind(window,"ready",a)},get:function(e){return arguments.length?e in this.editors?this.editors[e]:null:this.editors},add:function(e){var t=this,n=t.editors;return n[e.id]=e,n.push(e),u(n,!0),t.activeEditor=e,t.fire("AddEditor",{editor:e}),y||(y=function(){t.fire("BeforeUnload")},h.bind(window,"beforeunload",y)),e},createEditor:function(t,n){return this.add(new e(t,n,this))},remove:function(e){var t=this,n,r=t.editors,i;{if(e)return"string"==typeof e?(e=e.selector||e,void m(h.select(e),function(e){i=r[e.id],i&&t.remove(i)})):(i=e,r[i.id]?(d(i)&&t.fire("RemoveEditor",{editor:i}),r.length||h.unbind(window,"beforeunload",y),i.remove(),u(r,r.length>0),i):null);for(n=r.length-1;n>=0;n--)t.remove(r[n])}},execCommand:function(t,n,r){var i=this,o=i.get(r);switch(t){case"mceAddEditor":return i.get(r)||new e(r,i.settings,i).render(),!0;case"mceRemoveEditor":return o&&o.remove(),!0;case"mceToggleEditor":return o?(o.isHidden()?o.show():o.hide(),!0):(i.execCommand("mceAddEditor",0,r),!0)}return i.activeEditor?i.activeEditor.execCommand(t,n,r):!1},triggerSave:function(){m(this.editors,function(e){e.save()})},addI18n:function(e,t){s.add(e,t)},translate:function(e){return s.translate(e)},setActive:function(e){var t=this.activeEditor;this.activeEditor!=e&&(t&&t.fire("deactivate",{relatedTarget:e}),e.fire("activate",{relatedTarget:t})),this.activeEditor=e}},g(b,a),b.setup(),window.tinymce=window.tinyMCE=b,b}),r(Te,[ke,f],function(e,t){var n=t.each,r=t.explode;e.on("AddEditor",function(e){var t=e.editor;t.on("preInit",function(){function e(e,t){n(t,function(t,n){t&&s.setStyle(e,n,t)}),s.rename(e,"span")}function i(e){s=t.dom,l.convert_fonts_to_spans&&n(s.select("font,u,strike",e.node),function(e){o[e.nodeName.toLowerCase()](s,e)})}var o,a,s,l=t.settings;l.inline_styles&&(a=r(l.font_size_legacy_values),o={font:function(t,n){e(n,{backgroundColor:n.style.backgroundColor,color:n.color,fontFamily:n.face,fontSize:a[parseInt(n.size,10)-1]})},u:function(n,r){"html4"===t.settings.schema&&e(r,{textDecoration:"underline"})},strike:function(t,n){e(n,{textDecoration:"line-through"})}},t.on("PreProcess SetContent",i))})})}),r(Re,[K,f],function(e,t){var n={send:function(e){function r(){!e.async||4==i.readyState||o++>1e4?(e.success&&1e4>o&&200==i.status?e.success.call(e.success_scope,""+i.responseText,i,e):e.error&&e.error.call(e.error_scope,o>1e4?"TIMED_OUT":"GENERAL",i,e),i=null):setTimeout(r,10)}var i,o=0;if(e.scope=e.scope||this,e.success_scope=e.success_scope||e.scope,e.error_scope=e.error_scope||e.scope,e.async=e.async===!1?!1:!0,e.data=e.data||"",i=new XMLHttpRequest){if(i.overrideMimeType&&i.overrideMimeType(e.content_type),i.open(e.type||(e.data?"POST":"GET"),e.url,e.async),e.crossDomain&&(i.withCredentials=!0),e.content_type&&i.setRequestHeader("Content-Type",e.content_type),e.requestheaders&&t.each(e.requestheaders,function(e){i.setRequestHeader(e.key,e.value)}),i.setRequestHeader("X-Requested-With","XMLHttpRequest"),i=n.fire("beforeSend",{xhr:i,settings:e}).xhr,i.send(e.data),!e.async)return r();setTimeout(r,10)}}};return t.extend(n,e),n}),r(Ae,[],function(){function e(t,n){var r,i,o,a;if(n=n||'"',null===t)return"null";if(o=typeof t,"string"==o)return i="\bb t\nn\ff\rr\"\"''\\\\",n+t.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(e,t){return'"'===n&&"'"===e?e:(r=i.indexOf(t),r+1?"\\"+i.charAt(r+1):(e=t.charCodeAt().toString(16),"\\u"+"0000".substring(e.length)+e))})+n;if("object"==o){if(t.hasOwnProperty&&"[object Array]"===Object.prototype.toString.call(t)){for(r=0,i="[";r0?",":"")+e(t[r],n);return i+"]"}i="{";for(a in t)t.hasOwnProperty(a)&&(i+="function"!=typeof t[a]?(i.length>1?","+n:n)+a+n+":"+e(t[a],n):"");return i+"}"}return""+t}return{serialize:e,parse:function(e){try{return window[String.fromCharCode(101)+"val"]("("+e+")")}catch(t){}}}}),r(Be,[Ae,Re,f],function(e,t,n){function r(e){this.settings=i({},e),this.count=0}var i=n.extend;return r.sendRPC=function(e){return(new r).send(e)},r.prototype={send:function(n){var r=n.error,o=n.success;n=i(this.settings,n),n.success=function(t,i){t=e.parse(t),"undefined"==typeof t&&(t={error:"JSON Parse error."}),t.error?r.call(n.error_scope||n.scope,t.error,i):o.call(n.success_scope||n.scope,t.result)},n.error=function(e,t){r&&r.call(n.error_scope||n.scope,e,t)},n.data=e.serialize({id:n.id||"c"+this.count++,method:n.method,params:n.params}),n.content_type="application/json",t.send(n)}},r}),r(De,[b],function(e){return{callbacks:{},count:0,send:function(n){var r=this,i=e.DOM,o=n.count!==t?n.count:r.count,a="tinymce_jsonp_"+o;r.callbacks[o]=function(e){i.remove(a),delete r.callbacks[o],n.callback(e)},i.add(i.doc.body,"script",{id:a,src:n.url,type:"text/javascript"}),r.count++}}}),r(Me,[],function(){function e(){s=[];for(var e in a)s.push(e);i.length=s.length}function n(){function n(e){var n,r;return r=e!==t?u+e:i.indexOf(",",u),-1===r||r>i.length?null:(n=i.substring(u,r),u=r+1,n)}var r,i,s,u=0;if(a={},c){o.load(l),i=o.getAttribute(l)||"";do{var d=n();if(null===d)break;if(r=n(parseInt(d,32)||0),null!==r){if(d=n(),null===d)break;s=n(parseInt(d,32)||0),r&&(a[r]=s)}}while(null!==r);e()}}function r(){var t,n="";if(c){for(var r in a)t=a[r],n+=(n?",":"")+r.length.toString(32)+","+r+","+t.length.toString(32)+","+t;o.setAttribute(l,n);try{o.save(l)}catch(i){}e()}}var i,o,a,s,l,c;try{if(window.localStorage)return localStorage}catch(u){}return l="tinymce",o=document.documentElement,c=!!o.addBehavior,c&&o.addBehavior("#default#userData"),i={key:function(e){return s[e]},getItem:function(e){return e in a?a[e]:null},setItem:function(e,t){a[e]=""+t,r()},removeItem:function(e){delete a[e],r()},clear:function(){a={},r()}},n(),i}),r(Le,[b,l,x,C,f,u],function(e,t,n,r,i,o){var a=window.tinymce;return a.DOM=e.DOM,a.ScriptLoader=n.ScriptLoader,a.PluginManager=r.PluginManager,a.ThemeManager=r.ThemeManager,a.dom=a.dom||{},a.dom.Event=t.Event,i.each(i,function(e,t){a[t]=e}),i.each("isOpera isWebKit isIE isGecko isMac".split(" "),function(e){a[e]=o[e.substr(2).toLowerCase()]}),{}}),r(He,[$,f],function(e,t){return e.extend({Defaults:{firstControlClass:"first",lastControlClass:"last"},init:function(e){this.settings=t.extend({},this.Defaults,e)},preRender:function(e){e.bodyClasses.add(this.settings.containerClass)},applyClasses:function(e){var t=this,n=t.settings,r,i,o,a;r=n.firstControlClass,i=n.lastControlClass,e.each(function(e){e.classes.remove(r).remove(i).add(n.controlClass),e.visible()&&(o||(o=e),a=e)}),o&&o.classes.add(r),a&&a.classes.add(i)},renderHtml:function(e){var t=this,n="";return t.applyClasses(e.items()),e.items().each(function(e){n+=e.renderHtml()}),n},recalc:function(){},postRender:function(){},isNative:function(){return!1}})}),r(Pe,[He],function(e){return e.extend({Defaults:{containerClass:"abs-layout",controlClass:"abs-layout-item"},recalc:function(e){e.items().filter(":visible").each(function(e){var t=e.settings;e.layoutRect({x:t.x,y:t.y,w:t.w,h:t.h}),e.recalc&&e.recalc()})},renderHtml:function(e){return'
'+this._super(e)}})}),r(Oe,[te,le],function(e,t){return e.extend({Mixins:[t],Defaults:{classes:"widget tooltip tooltip-n"},renderHtml:function(){var e=this,t=e.classPrefix;return'"},bindStates:function(){var e=this;return e.state.on("change:text",function(t){e.getEl().lastChild.innerHTML=e.encode(t.value)}),e._super()},repaint:function(){var e=this,t,n;t=e.getEl().style,n=e._layoutRect,t.left=n.x+"px",t.top=n.y+"px",t.zIndex=131070}})}),r(Ie,[te,Oe],function(e,t){var n,r=e.extend({init:function(e){var t=this;t._super(e),e=t.settings,t.canFocus=!0,e.tooltip&&r.tooltips!==!1&&(t.on("mouseenter",function(n){var r=t.tooltip().moveTo(-65535);if(n.control==t){var i=r.text(e.tooltip).show().testMoveRel(t.getEl(),["bc-tc","bc-tl","bc-tr"]);r.classes.toggle("tooltip-n","bc-tc"==i),r.classes.toggle("tooltip-nw","bc-tl"==i),r.classes.toggle("tooltip-ne","bc-tr"==i),r.moveRel(t.getEl(),i)}else r.hide()}),t.on("mouseleave mousedown click",function(){t.tooltip().hide()})),t.aria("label",e.ariaLabel||e.tooltip)},tooltip:function(){return n||(n=new t({type:"tooltip"}),n.renderTo()),n},postRender:function(){var e=this,t=e.settings;e._super(),e.parent()||!t.width&&!t.height||(e.initLayoutRect(),e.repaint()),t.autofocus&&e.focus()},bindStates:function(){function e(e){n.aria("disabled",e),n.classes.toggle("disabled",e)}function t(e){n.aria("pressed",e),n.classes.toggle("active",e)}var n=this;return n.state.on("change:disabled",function(t){e(t.value)}),n.state.on("change:active",function(e){t(e.value)}),n.state.get("disabled")&&e(!0),n.state.get("active")&&t(!0),n._super()},remove:function(){this._super(),n&&(n.remove(),n=null)}});return r}),r(Fe,[Ie],function(e){return e.extend({Defaults:{classes:"widget btn",role:"button"},init:function(e){var t=this,n;t._super(e),e=t.settings,n=t.settings.size,t.on("click mousedown",function(e){e.preventDefault()}),t.on("touchstart",function(e){t.fire("click",e),e.preventDefault()}),e.subtype&&t.classes.add(e.subtype),n&&t.classes.add("btn-"+n),e.icon&&t.icon(e.icon)},icon:function(e){return arguments.length?(this.state.set("icon",e),this):this.state.get("icon")},repaint:function(){var e=this.getEl().firstChild,t;e&&(t=e.style,t.width=t.height="100%"),this._super()},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.state.get("icon"),i,o=e.state.get("text");return i=e.settings.image,i?(r="none","string"!=typeof i&&(i=window.getSelection?i[0]:i[1]),i=" style=\"background-image: url('"+i+"')\""):i="",o&&e.classes.add("btn-has-text"),r=e.settings.icon?n+"ico "+n+"i-"+r:"",'
"},bindStates:function(){function e(e){for(var n=t.getEl().firstChild.firstChild;n;n=n.nextSibling)3==n.nodeType&&(n.data=t.translate(e));t.classes.toggle("btn-has-text",!!e)}var t=this;return t.state.on("change:text",function(t){e(t.value)}),t.state.on("change:icon",function(n){var r=n.value,i=t.classPrefix;t.settings.icon=r,r=r?i+"ico "+i+"i-"+t.settings.icon:"";var o=t.getEl().firstChild,a=o.getElementsByTagName("i")[0];r?(a&&a==o.firstChild||(a=document.createElement("i"),o.insertBefore(a,o.firstChild)),a.className=r):a&&o.removeChild(a),e(t.state.get("text"))}),t._super()}})}),r(ze,[ie],function(e){return e.extend({Defaults:{defaultType:"button",role:"group"},renderHtml:function(){var e=this,t=e._layout;return e.classes.add("btn-group"),e.preRender(),t.preRender(e),'
'+(e.settings.html||"")+t.renderHtml(e)+"
"}})}),r(We,[Ie],function(e){return e.extend({Defaults:{classes:"checkbox",role:"checkbox",checked:!1},init:function(e){var t=this;t._super(e),t.on("click mousedown",function(e){e.preventDefault()}),t.on("click",function(e){e.preventDefault(),t.disabled()||t.checked(!t.checked())}),t.checked(t.settings.checked)},checked:function(e){return arguments.length?(this.state.set("checked",e),this):this.state.get("checked")},value:function(e){return arguments.length?this.checked(e):this.checked()},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix;return'
'+e.encode(e.state.get("text"))+"
"},bindStates:function(){function e(e){t.classes.toggle("checked",e),t.aria("checked",e)}var t=this;return t.state.on("change:text",function(e){t.getEl("al").firstChild.data=t.translate(e.value)}),t.state.on("change:checked change:value",function(n){t.fire("change"),e(n.value)}),t.state.on("change:icon",function(e){var n=e.value,r=t.classPrefix;if("undefined"==typeof n)return t.settings.icon;t.settings.icon=n,n=n?r+"ico "+r+"i-"+t.settings.icon:"";var i=t.getEl().firstChild,o=i.getElementsByTagName("i")[0];n?(o&&o==i.firstChild||(o=document.createElement("i"),i.insertBefore(o,i.firstChild)),o.className=n):o&&i.removeChild(o)}),t.state.get("checked")&&e(!0),t._super()}})}),r(Ve,[Ie,ne,J,h],function(e,t,n,r){return e.extend({init:function(e){var t=this;t._super(e),e=t.settings,t.classes.add("combobox"),t.subinput=!0,t.ariaTarget="inp",e.menu=e.menu||e.values,e.menu&&(e.icon="caret"),t.on("click",function(n){var i=n.target,o=t.getEl();if(r.contains(o,i)||i==o)for(;i&&i!=o;)i.id&&-1!=i.id.indexOf("-open")&&(t.fire("action"),e.menu&&(t.showMenu(),n.aria&&t.menu.items()[0].focus())),i=i.parentNode}),t.on("keydown",function(e){"INPUT"==e.target.nodeName&&13==e.keyCode&&t.parents().reverse().each(function(n){var r=t.state.get("value"),i=t.getEl("inp").value;return e.preventDefault(),t.state.set("value",i),r!=i&&t.fire("change"),n.hasEventListeners("submit")&&n.toJSON?(n.fire("submit",{data:n.toJSON()}),!1):void 0})}),t.on("keyup",function(e){"INPUT"==e.target.nodeName&&t.state.set("value",e.target.value)})},showMenu:function(){var e=this,n=e.settings,r;e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(e.getContainerElm()),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control===e.menu&&e.focus()}),e.menu.on("show hide",function(t){t.control.items().each(function(t){t.active(t.value()==e.value())})}).fire("show"),e.menu.on("select",function(t){e.value(t.control.value())}),e.on("focusin",function(t){"INPUT"==t.target.tagName.toUpperCase()&&e.menu.hide()}),e.aria("expanded",!0)),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"])},focus:function(){this.getEl("inp").focus()},repaint:function(){var e=this,t=e.getEl(),i=e.getEl("open"),o=e.layoutRect(),a,s;a=i?o.w-n.getSize(i).width-10:o.w-10;var l=document;return l.all&&(!l.documentMode||l.documentMode<=8)&&(s=e.layoutRect().h-2+"px"),r(t.firstChild).css({width:a,lineHeight:s}),e._super(),e},postRender:function(){var e=this;return r(this.getEl("inp")).on("change",function(t){e.state.set("value",t.target.value),e.fire("change",t)}),e._super()},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.classPrefix,i=e.state.get("value")||"",o,a,s="",l="";return"spellcheck"in n&&(l+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(l+=' maxlength="'+n.maxLength+'"'),n.size&&(l+=' size="'+n.size+'"'),n.subtype&&(l+=' type="'+n.subtype+'"'),e.disabled()&&(l+=' disabled="disabled"'),o=n.icon,o&&"caret"!=o&&(o=r+"ico "+r+"i-"+n.icon),a=e.state.get("text"),(o||a)&&(s='
",e.classes.add("has-open")),'
'+s+"
"},value:function(e){return arguments.length?(this.state.set("value",e),this):(this.state.get("rendered")&&this.state.set("value",this.getEl("inp").value),this.state.get("value"))},bindStates:function(){var e=this;return e.state.on("change:value",function(t){e.getEl("inp").value!=t.value&&(e.getEl("inp").value=t.value)}),e.state.on("change:disabled",function(t){e.getEl("inp").disabled=t.value}),e._super()},remove:function(){r(this.getEl("inp")).off(),this._super()}})}),r(Ue,[Ve],function(e){return e.extend({init:function(e){var t=this;e.spellcheck=!1,e.onaction&&(e.icon="none"),t._super(e),t.classes.add("colorbox"),t.on("change keyup postrender",function(){t.repaintColor(t.value())})},repaintColor:function(e){var t=this.getEl().getElementsByTagName("i")[0];if(t)try{t.style.background=e}catch(n){}},bindStates:function(){var e=this;return e.state.on("change:value",function(t){e._rendered&&e.repaintColor(t.value)}),e._super()}})}),r($e,[Fe,ue],function(e,t){return e.extend({showPanel:function(){var e=this,n=e.settings;if(e.active(!0),e.panel)e.panel.show();else{var r=n.panel;r.type&&(r={layout:"grid",items:r}),r.role=r.role||"dialog",r.popover=!0,r.autohide=!0,r.ariaRoot=!0,e.panel=new t(r).on("hide",function(){e.active(!1)}).on("cancel",function(t){t.stopPropagation(),e.focus(),e.hidePanel()}).parent(e).renderTo(e.getContainerElm()),e.panel.fire("show"),e.panel.reflow()}e.panel.moveRel(e.getEl(),n.popoverAlign||(e.isRtl()?["bc-tr","bc-tc"]:["bc-tl","bc-tc"]))},hidePanel:function(){var e=this;e.panel&&e.panel.hide()},postRender:function(){var e=this;return e.aria("haspopup",!0),e.on("click",function(t){t.control===e&&(e.panel&&e.panel.visible()?e.hidePanel():(e.showPanel(),e.panel.focus(!!t.aria)))}),e._super()},remove:function(){return this.panel&&(this.panel.remove(),this.panel=null),this._super()}})}),r(qe,[$e,b],function(e,t){var n=t.DOM;return e.extend({init:function(e){this._super(e),this.classes.add("colorbutton")},color:function(e){return e?(this._color=e,this.getEl("preview").style.backgroundColor=e,this):this._color},resetColor:function(){return this._color=null,this.getEl("preview").style.backgroundColor=null,this},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.state.get("text"),i=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"",o=e.settings.image?" style=\"background-image: url('"+e.settings.image+"')\"":"";return'
'},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(r){r.aria&&"down"==r.aria.key||r.control!=e||n.getParent(r.target,"."+e.classPrefix+"open")||(r.stopImmediatePropagation(),t.call(e,r))}),delete e.settings.onclick,e._super()}})}),r(je,[],function(){function e(e){function i(e,i,o){var a,s,l,c,u,d;return a=0,s=0,l=0,e/=255,i/=255,o/=255,u=t(e,t(i,o)),d=n(e,n(i,o)),u==d?(l=u,{h:0,s:0,v:100*l}):(c=e==u?i-o:o==u?e-i:o-e,a=e==u?3:o==u?1:5,a=60*(a-c/(d-u)),s=(d-u)/d,l=d,{h:r(a),s:r(100*s),v:r(100*l)})}function o(e,i,o){var a,s,l,c;if(e=(parseInt(e,10)||0)%360,i=parseInt(i,10)/100,o=parseInt(o,10)/100,i=n(0,t(i,1)),o=n(0,t(o,1)),0===i)return void(d=f=h=r(255*o));switch(a=e/60,s=o*i,l=s*(1-Math.abs(a%2-1)),c=o-s,Math.floor(a)){case 0:d=s,f=l,h=0;break;case 1:d=l,f=s,h=0;break;case 2:d=0,f=s,h=l;break;case 3:d=0,f=l,h=s;break;case 4:d=l,f=0,h=s;break;case 5:d=s,f=0,h=l;break;default:d=f=h=0}d=r(255*(d+c)),f=r(255*(f+c)),h=r(255*(h+c))}function a(){function e(e){return e=parseInt(e,10).toString(16),e.length>1?e:"0"+e}return"#"+e(d)+e(f)+e(h)}function s(){return{r:d,g:f,b:h}}function l(){return i(d,f,h)}function c(e){var t;return"object"==typeof e?"r"in e?(d=e.r,f=e.g,h=e.b):"v"in e&&o(e.h,e.s,e.v):(t=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(e))?(d=parseInt(t[1],10), -f=parseInt(t[2],10),h=parseInt(t[3],10)):(t=/#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(e))?(d=parseInt(t[1],16),f=parseInt(t[2],16),h=parseInt(t[3],16)):(t=/#([0-F])([0-F])([0-F])/gi.exec(e))&&(d=parseInt(t[1]+t[1],16),f=parseInt(t[2]+t[2],16),h=parseInt(t[3]+t[3],16)),d=0>d?0:d>255?255:d,f=0>f?0:f>255?255:f,h=0>h?0:h>255?255:h,u}var u=this,d=0,f=0,h=0;e&&c(e),u.toRgb=s,u.toHsv=l,u.toHex=a,u.parse=c}var t=Math.min,n=Math.max,r=Math.round;return e}),r(Ke,[Ie,oe,J,je],function(e,t,n,r){return e.extend({Defaults:{classes:"widget colorpicker"},init:function(e){this._super(e)},postRender:function(){function e(e,t){var r=n.getPos(e),i,o;return i=t.pageX-r.x,o=t.pageY-r.y,i=Math.max(0,Math.min(i/e.clientWidth,1)),o=Math.max(0,Math.min(o/e.clientHeight,1)),{x:i,y:o}}function i(e,t){var i=(360-e.h)/360;n.css(d,{top:100*i+"%"}),t||n.css(h,{left:e.s+"%",top:100-e.v+"%"}),f.style.background=new r({s:100,v:100,h:e.h}).toHex(),s.color().parse({s:e.s,v:e.v,h:e.h})}function o(t){var n;n=e(f,t),c.s=100*n.x,c.v=100*(1-n.y),i(c),s.fire("change")}function a(t){var n;n=e(u,t),c=l.toHsv(),c.h=360*(1-n.y),i(c,!0),s.fire("change")}var s=this,l=s.color(),c,u,d,f,h;u=s.getEl("h"),d=s.getEl("hp"),f=s.getEl("sv"),h=s.getEl("svp"),s._repaint=function(){c=l.toHsv(),i(c)},s._super(),s._svdraghelper=new t(s._id+"-sv",{start:o,drag:o}),s._hdraghelper=new t(s._id+"-h",{start:a,drag:a}),s._repaint()},rgb:function(){return this.color().toRgb()},value:function(e){var t=this;return arguments.length?(t.color().parse(e),void(t._rendered&&t._repaint())):t.color().toHex()},color:function(){return this._color||(this._color=new r),this._color},renderHtml:function(){function e(){var e,t,n="",i,a;for(i="filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=",a=o.split(","),e=0,t=a.length-1;t>e;e++)n+='
';return n}var t=this,n=t._id,r=t.classPrefix,i,o="#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000",a="background: -ms-linear-gradient(top,"+o+");background: linear-gradient(to bottom,"+o+");";return i='
'+e()+'
','
'+i+"
"}})}),r(Ye,[Ie],function(e){return e.extend({init:function(e){var t=this;e.delimiter||(e.delimiter="\xbb"),t._super(e),t.classes.add("path"),t.canFocus=!0,t.on("click",function(e){var n,r=e.target;(n=r.getAttribute("data-index"))&&t.fire("select",{value:t.row()[n],index:n})}),t.row(t.settings.row)},focus:function(){var e=this;return e.getEl().firstChild.focus(),e},row:function(e){return arguments.length?(this.state.set("row",e),this):this.state.get("row")},renderHtml:function(){var e=this;return'
'+e._getDataPathHtml(e.state.get("row"))+"
"},bindStates:function(){var e=this;return e.state.on("change:row",function(t){e.innerHtml(e._getDataPathHtml(t.value))}),e._super()},_getDataPathHtml:function(e){var t=this,n=e||[],r,i,o="",a=t.classPrefix;for(r=0,i=n.length;i>r;r++)o+=(r>0?'":"")+'
'+n[r].name+"
";return o||(o='
\xa0
'),o}})}),r(Ge,[Ye,ke],function(e,t){return e.extend({postRender:function(){function e(e){if(1===e.nodeType){if("BR"==e.nodeName||e.getAttribute("data-mce-bogus"))return!0;if("bookmark"===e.getAttribute("data-mce-type"))return!0}return!1}var n=this,r=t.activeEditor;return r.settings.elementpath!==!1&&(n.on("select",function(e){r.focus(),r.selection.select(this.row()[e.index].element),r.nodeChanged()}),r.on("nodeChange",function(t){for(var i=[],o=t.parents,a=o.length;a--;)if(1==o[a].nodeType&&!e(o[a])){var s=r.fire("ResolveName",{name:o[a].nodeName.toLowerCase(),target:o[a]});if(s.isDefaultPrevented()||i.push({name:s.name,element:o[a]}),s.isPropagationStopped())break}n.row(i)})),n._super()}})}),r(Xe,[ie],function(e){return e.extend({Defaults:{layout:"flex",align:"center",defaults:{flex:1}},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.classes.add("formitem"),t.preRender(e),'
'+(e.settings.title?'
'+e.settings.title+"
":"")+'
'+(e.settings.html||"")+t.renderHtml(e)+"
"}})}),r(Je,[ie,Xe,f],function(e,t,n){return e.extend({Defaults:{containerCls:"form",layout:"flex",direction:"column",align:"stretch",flex:1,padding:20,labelGap:30,spacing:10,callbacks:{submit:function(){this.submit()}}},preRender:function(){var e=this,r=e.items();e.settings.formItemDefaults||(e.settings.formItemDefaults={layout:"flex",autoResize:"overflow",defaults:{flex:1}}),r.each(function(r){var i,o=r.settings.label;o&&(i=new t(n.extend({items:{type:"label",id:r._id+"-l",text:o,flex:0,forId:r._id,disabled:r.disabled()}},e.settings.formItemDefaults)),i.type="formitem",r.aria("labelledby",r._id+"-l"),"undefined"==typeof r.settings.flex&&(r.settings.flex=1),e.replace(r,i),i.add(r))})},submit:function(){return this.fire("submit",{data:this.toJSON()})},postRender:function(){var e=this;e._super(),e.fromJSON(e.settings.data)},bindStates:function(){function e(){var e=0,n=[],r,i,o;if(t.settings.labelGapCalc!==!1)for(o="children"==t.settings.labelGapCalc?t.find("formitem"):t.items(),o.filter("formitem").each(function(t){var r=t.items()[0],i=r.getEl().clientWidth;e=i>e?i:e,n.push(r)}),i=t.settings.labelGap||0,r=n.length;r--;)n[r].settings.minWidth=e+i}var t=this;t._super(),t.on("show",e),e()}})}),r(Qe,[Je],function(e){return e.extend({Defaults:{containerCls:"fieldset",layout:"flex",direction:"column",align:"stretch",flex:1,padding:"25 15 5 15",labelGap:30,spacing:10,border:1},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.preRender(),t.preRender(e),'
'+(e.settings.title?''+e.settings.title+"":"")+'
'+(e.settings.html||"")+t.renderHtml(e)+"
"}})}),r(Ze,[Ve,f],function(e,t){return e.extend({init:function(e){var n=this,r=tinymce.activeEditor,i=r.settings,o,a,s;e.spellcheck=!1,s=i.file_picker_types||i.file_browser_callback_types,s&&(s=t.makeMap(s,/[, ]/)),(!s||s[e.filetype])&&(a=i.file_picker_callback,!a||s&&!s[e.filetype]?(a=i.file_browser_callback,!a||s&&!s[e.filetype]||(o=function(){a(n.getEl("inp").id,n.value(),e.filetype,window)})):o=function(){var i=n.fire("beforecall").meta;i=t.extend({filetype:e.filetype},i),a.call(r,function(e,t){n.value(e).fire("change",{meta:t})},n.value(),i)}),o&&(e.icon="browse",e.onaction=o),n._super(e)}})}),r(et,[Pe],function(e){return e.extend({recalc:function(e){var t=e.layoutRect(),n=e.paddingBox;e.items().filter(":visible").each(function(e){e.layoutRect({x:n.left,y:n.top,w:t.innerW-n.right-n.left,h:t.innerH-n.top-n.bottom}),e.recalc&&e.recalc()})}})}),r(tt,[Pe],function(e){return e.extend({recalc:function(e){var t,n,r,i,o,a,s,l,c,u,d,f,h,p,m,g,v=[],y,b,x,C,w,_,E,N,S,k,T,R,A,B,D,M,L,H,P,O,I,F,z=Math.max,W=Math.min;for(r=e.items().filter(":visible"),i=e.layoutRect(),o=e.paddingBox,a=e.settings,f=e.isRtl()?a.direction||"row-reversed":a.direction,s=a.align,l=e.isRtl()?a.pack||"end":a.pack,c=a.spacing||0,("row-reversed"==f||"column-reverse"==f)&&(r=r.set(r.toArray().reverse()),f=f.split("-")[0]),"column"==f?(S="y",E="h",N="minH",k="maxH",R="innerH",T="top",A="deltaH",B="contentH",P="left",L="w",D="x",M="innerW",H="minW",O="right",I="deltaW",F="contentW"):(S="x",E="w",N="minW",k="maxW",R="innerW",T="left",A="deltaW",B="contentW",P="top",L="h",D="y",M="innerH",H="minH",O="bottom",I="deltaH",F="contentH"),d=i[R]-o[T]-o[T],_=u=0,t=0,n=r.length;n>t;t++)h=r[t],p=h.layoutRect(),m=h.settings,g=m.flex,d-=n-1>t?c:0,g>0&&(u+=g,p[k]&&v.push(h),p.flex=g),d-=p[N],y=o[P]+p[H]+o[O],y>_&&(_=y);if(C={},0>d?C[N]=i[N]-d+i[A]:C[N]=i[R]-d+i[A],C[H]=_+i[I],C[B]=i[R]-d,C[F]=_,C.minW=W(C.minW,i.maxW),C.minH=W(C.minH,i.maxH),C.minW=z(C.minW,i.startMinWidth),C.minH=z(C.minH,i.startMinHeight),!i.autoResize||C.minW==i.minW&&C.minH==i.minH){for(x=d/u,t=0,n=v.length;n>t;t++)h=v[t],p=h.layoutRect(),b=p[k],y=p[N]+p.flex*x,y>b?(d-=p[k]-p[N],u-=p.flex,p.flex=0,p.maxFlexSize=b):p.maxFlexSize=0;for(x=d/u,w=o[T],C={},0===u&&("end"==l?w=d+o[T]:"center"==l?(w=Math.round(i[R]/2-(i[R]-d)/2)+o[T],0>w&&(w=o[T])):"justify"==l&&(w=o[T],c=Math.floor(d/(r.length-1)))),C[D]=o[P],t=0,n=r.length;n>t;t++)h=r[t],p=h.layoutRect(),y=p.maxFlexSize||p[N],"center"===s?C[D]=Math.round(i[M]/2-p[L]/2):"stretch"===s?(C[L]=z(p[H]||0,i[M]-o[P]-o[O]),C[D]=o[P]):"end"===s&&(C[D]=i[M]-p[L]-o.top),p.flex>0&&(y+=p.flex*x),C[E]=y,C[S]=w,h.layoutRect(C),h.recalc&&h.recalc(),w+=y+c}else if(C.w=C.minW,C.h=C.minH,e.layoutRect(C),this.recalc(e),null===e._lastRect){var V=e.parent();V&&(V._lastRect=null,V.recalc())}}})}),r(nt,[He],function(e){return e.extend({Defaults:{containerClass:"flow-layout",controlClass:"flow-layout-item",endClass:"break"},recalc:function(e){e.items().filter(":visible").each(function(e){e.recalc&&e.recalc()})},isNative:function(){return!0}})}),r(rt,[te,Ie,ue,f,ke,u],function(e,t,n,r,i,o){function a(e){function t(t,n){return function(){var r=this;e.on("nodeChange",function(i){var o=e.formatter,a=null;s(i.parents,function(e){return s(t,function(t){return n?o.matchNode(e,n,{value:t.value})&&(a=t.value):o.matchNode(e,t.value)&&(a=t.value),a?!1:void 0}),a?!1:void 0}),r.value(a)})}}function r(e){e=e.replace(/;$/,"").split(";");for(var t=e.length;t--;)e[t]=e[t].split("=");return e}function i(){function t(e){var n=[];if(e)return s(e,function(e){var o={text:e.title,icon:e.icon};if(e.items)o.menu=t(e.items);else{var a=e.format||"custom"+r++;e.format||(e.name=a,i.push(e)),o.format=a,o.cmd=e.cmd}n.push(o)}),n}function n(){var n;return n=t(e.settings.style_formats_merge?e.settings.style_formats?o.concat(e.settings.style_formats):o:e.settings.style_formats||o)}var r=0,i=[],o=[{title:"Headings",items:[{title:"Heading 1",format:"h1"},{title:"Heading 2",format:"h2"},{title:"Heading 3",format:"h3"},{title:"Heading 4",format:"h4"},{title:"Heading 5",format:"h5"},{title:"Heading 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}];return e.on("init",function(){s(i,function(t){e.formatter.register(t.name,t)})}),{type:"menu",items:n(),onPostRender:function(t){e.fire("renderFormatsMenu",{control:t.control})},itemDefaults:{preview:!0,textStyle:function(){return this.settings.format?e.formatter.getCssText(this.settings.format):void 0},onPostRender:function(){var t=this;t.parent().on("show",function(){var n,r;n=t.settings.format,n&&(t.disabled(!e.formatter.canApply(n)),t.active(e.formatter.match(n))),r=t.settings.cmd,r&&t.active(e.queryCommandState(r))})},onclick:function(){this.settings.format&&l(this.settings.format),this.settings.cmd&&e.execCommand(this.settings.cmd)}}}}function o(t){return function(){function n(){return e.undoManager?e.undoManager[t]():!1}var r=this;t="redo"==t?"hasRedo":"hasUndo",r.disabled(!n()),e.on("Undo Redo AddUndo TypingUndo ClearUndos",function(){r.disabled(!n())})}}function a(){var t=this;e.on("VisualAid",function(e){t.active(e.hasVisual)}),t.active(e.hasVisual)}function l(t){t.control&&(t=t.control.value()),t&&e.execCommand("mceToggleFormat",!1,t)}var c;c=i(),s({bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",subscript:"Subscript",superscript:"Superscript"},function(t,n){e.addButton(n,{tooltip:t,onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})},onclick:function(){l(n)}})}),s({outdent:["Decrease indent","Outdent"],indent:["Increase indent","Indent"],cut:["Cut","Cut"],copy:["Copy","Copy"],paste:["Paste","Paste"],help:["Help","mceHelp"],selectall:["Select all","SelectAll"],removeformat:["Clear formatting","RemoveFormat"],visualaid:["Visual aids","mceToggleVisualAid"],newdocument:["New document","mceNewDocument"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1]})}),s({blockquote:["Blockquote","mceBlockQuote"],numlist:["Numbered list","InsertOrderedList"],bullist:["Bullet list","InsertUnorderedList"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],alignleft:["Align left","JustifyLeft"],aligncenter:["Align center","JustifyCenter"],alignright:["Align right","JustifyRight"],alignjustify:["Justify","JustifyFull"],alignnone:["No alignment","JustifyNone"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1],onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})}})}),e.addButton("undo",{tooltip:"Undo",onPostRender:o("undo"),cmd:"undo"}),e.addButton("redo",{tooltip:"Redo",onPostRender:o("redo"),cmd:"redo"}),e.addMenuItem("newdocument",{text:"New document",icon:"newdocument",cmd:"mceNewDocument"}),e.addMenuItem("undo",{text:"Undo",icon:"undo",shortcut:"Meta+Z",onPostRender:o("undo"),cmd:"undo"}),e.addMenuItem("redo",{text:"Redo",icon:"redo",shortcut:"Meta+Y",onPostRender:o("redo"),cmd:"redo"}),e.addMenuItem("visualaid",{text:"Visual aids",selectable:!0,onPostRender:a,cmd:"mceToggleVisualAid"}),e.addButton("remove",{tooltip:"Remove",icon:"remove",cmd:"Delete"}),s({cut:["Cut","Cut","Meta+X"],copy:["Copy","Copy","Meta+C"],paste:["Paste","Paste","Meta+V"],selectall:["Select all","SelectAll","Meta+A"],bold:["Bold","Bold","Meta+B"],italic:["Italic","Italic","Meta+I"],underline:["Underline","Underline"],strikethrough:["Strikethrough","Strikethrough"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],removeformat:["Clear formatting","RemoveFormat"]},function(t,n){e.addMenuItem(n,{text:t[0],icon:n,shortcut:t[2],cmd:t[1]})}),e.on("mousedown",function(){n.hideAll()}),e.addButton("styleselect",{type:"menubutton",text:"Formats",menu:c}),e.addButton("formatselect",function(){var n=[],i=r(e.settings.block_formats||"Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Preformatted=pre");return s(i,function(t){n.push({text:t[0],value:t[1],textStyle:function(){return e.formatter.getCssText(t[1])}})}),{type:"listbox",text:i[0][0],values:n,fixedWidth:!0,onselect:l,onPostRender:t(n)}}),e.addButton("fontselect",function(){var n="Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats",i=[],o=r(e.settings.font_formats||n);return s(o,function(e){i.push({text:{raw:e[0]},value:e[1],textStyle:-1==e[1].indexOf("dings")?"font-family:"+e[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:i,fixedWidth:!0,onPostRender:t(i,"fontname"),onselect:function(t){t.control.settings.value&&e.execCommand("FontName",!1,t.control.settings.value)}}}),e.addButton("fontsizeselect",function(){var n=[],r="8pt 10pt 12pt 14pt 18pt 24pt 36pt",i=e.settings.fontsize_formats||r;return s(i.split(" "),function(e){var t=e,r=e,i=e.split("=");i.length>1&&(t=i[0],r=i[1]),n.push({text:t,value:r})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:n,fixedWidth:!0,onPostRender:t(n,"fontsize"),onclick:function(t){t.control.settings.value&&e.execCommand("FontSize",!1,t.control.settings.value)}}}),e.addMenuItem("formats",{text:"Formats",menu:c})}var s=r.each;i.on("AddEditor",function(t){t.editor.rtl&&(e.rtl=!0),a(t.editor)}),e.translate=function(e){return i.translate(e)},t.tooltips=!o.iOS}),r(it,[Pe],function(e){return e.extend({recalc:function(e){var t=e.settings,n,r,i,o,a,s,l,c,u,d,f,h,p,m,g,v,y,b,x,C,w,_,E=[],N=[],S,k,T,R,A,B;t=e.settings,i=e.items().filter(":visible"),o=e.layoutRect(),r=t.columns||Math.ceil(Math.sqrt(i.length)),n=Math.ceil(i.length/r),y=t.spacingH||t.spacing||0,b=t.spacingV||t.spacing||0,x=t.alignH||t.align,C=t.alignV||t.align,g=e.paddingBox,A="reverseRows"in t?t.reverseRows:e.isRtl(),x&&"string"==typeof x&&(x=[x]),C&&"string"==typeof C&&(C=[C]);for(d=0;r>d;d++)E.push(0);for(f=0;n>f;f++)N.push(0);for(f=0;n>f;f++)for(d=0;r>d&&(u=i[f*r+d],u);d++)c=u.layoutRect(),S=c.minW,k=c.minH,E[d]=S>E[d]?S:E[d],N[f]=k>N[f]?k:N[f];for(T=o.innerW-g.left-g.right,w=0,d=0;r>d;d++)w+=E[d]+(d>0?y:0),T-=(d>0?y:0)+E[d];for(R=o.innerH-g.top-g.bottom,_=0,f=0;n>f;f++)_+=N[f]+(f>0?b:0),R-=(f>0?b:0)+N[f];if(w+=g.left+g.right,_+=g.top+g.bottom,l={},l.minW=w+(o.w-o.innerW),l.minH=_+(o.h-o.innerH),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH,l.minW=Math.min(l.minW,o.maxW),l.minH=Math.min(l.minH,o.maxH),l.minW=Math.max(l.minW,o.startMinWidth),l.minH=Math.max(l.minH,o.startMinHeight),!o.autoResize||l.minW==o.minW&&l.minH==o.minH){o.autoResize&&(l=e.layoutRect(l),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH);var D;D="start"==t.packV?0:R>0?Math.floor(R/n):0;var M=0,L=t.flexWidths;if(L)for(d=0;dd;d++)E[d]+=L?L[d]*H:H;for(p=g.top,f=0;n>f;f++){for(h=g.left,s=N[f]+D,d=0;r>d&&(B=A?f*r+r-1-d:f*r+d,u=i[B],u);d++)m=u.settings,c=u.layoutRect(),a=Math.max(E[d],c.startMinWidth),c.x=h,c.y=p,v=m.alignH||(x?x[d]||x[0]:null),"center"==v?c.x=h+a/2-c.w/2:"right"==v?c.x=h+a-c.w:"stretch"==v&&(c.w=a),v=m.alignV||(C?C[d]||C[0]:null),"center"==v?c.y=p+s/2-c.h/2:"bottom"==v?c.y=p+s-c.h:"stretch"==v&&(c.h=s),u.layoutRect(c),h+=a+y,u.recalc&&u.recalc();p+=s+b}}else if(l.w=l.minW,l.h=l.minH,e.layoutRect(l),this.recalc(e),null===e._lastRect){var P=e.parent();P&&(P._lastRect=null,P.recalc())}}})}),r(ot,[Ie],function(e){return e.extend({renderHtml:function(){var e=this;return e.classes.add("iframe"),e.canFocus=!1,''},src:function(e){this.getEl().src=e},html:function(e,t){var n=this,r=this.getEl().contentWindow.document.body;return r?(r.innerHTML=e,t&&t()):setTimeout(function(){n.html(e)},0),this}})}),r(at,[Ie,J],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t.classes.add("widget").add("label"),t.canFocus=!1,e.multiline&&t.classes.add("autoscroll"),e.strong&&t.classes.add("strong")},initLayoutRect:function(){var e=this,n=e._super();if(e.settings.multiline){var r=t.getSize(e.getEl());r.width>n.maxW&&(n.minW=n.maxW,e.classes.add("multiline")),e.getEl().style.width=n.minW+"px",n.startMinH=n.h=n.minH=Math.min(n.maxH,t.getSize(e.getEl()).height)}return n},repaint:function(){var e=this;return e.settings.multiline||(e.getEl().style.lineHeight=e.layoutRect().h+"px"),e._super()},renderHtml:function(){var e=this,t=e.settings.forId;return'"},bindStates:function(){var e=this;return e.state.on("change:text",function(t){e.innerHtml(e.encode(t.value))}),e._super()}})}),r(st,[ie],function(e){return e.extend({Defaults:{role:"toolbar",layout:"flow"},init:function(e){var t=this;t._super(e),t.classes.add("toolbar")},postRender:function(){var e=this;return e.items().each(function(e){e.classes.add("toolbar-item")}),e._super()}})}),r(lt,[st],function(e){return e.extend({Defaults:{role:"menubar",containerCls:"menubar",ariaRoot:!0,defaults:{type:"menubutton"}}})}),r(ct,[Fe,ne,lt],function(e,t,n){function r(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1}var i=e.extend({init:function(e){var t=this;t._renderOpen=!0,t._super(e),e=t.settings,t.classes.add("menubtn"),e.fixedWidth&&t.classes.add("fixed-width"),t.aria("haspopup",!0),t.state.set("menu",e.menu||t.render())},showMenu:function(){var e=this,n;return e.menu&&e.menu.visible()?e.hideMenu():(e.menu||(n=e.state.get("menu")||[],n.length?n={type:"menu",items:n}:n.type=n.type||"menu",n.renderTo?e.menu=n.parent(e).show().renderTo():e.menu=t.create(n).parent(e).renderTo(),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control.parent()===e.menu&&(t.stopPropagation(),e.focus(),e.hideMenu())}),e.menu.on("select",function(){e.focus()}),e.menu.on("show hide",function(t){t.control==e.menu&&e.activeMenu("show"==t.type),e.aria("expanded","show"==t.type)}).fire("show")),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),void e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"]))},hideMenu:function(){var e=this;e.menu&&(e.menu.items().each(function(e){e.hideMenu&&e.hideMenu()}),e.menu.hide())},activeMenu:function(e){this.classes.toggle("active",e)},renderHtml:function(){var e=this,t=e._id,r=e.classPrefix,i=e.settings.icon,o,a=e.state.get("text");return o=e.settings.image,o?(i="none","string"!=typeof o&&(o=window.getSelection?o[0]:o[1]),o=" style=\"background-image: url('"+o+"')\""):o="",i=e.settings.icon?r+"ico "+r+"i-"+i:"",e.aria("role",e.parent()instanceof n?"menuitem":"button"),'
'},postRender:function(){var e=this;return e.on("click",function(t){t.control===e&&r(t.target,e.getEl())&&(e.showMenu(),t.aria&&e.menu.items()[0].focus())}),e.on("mouseenter",function(t){var n=t.control,r=e.parent(),o;n&&r&&n instanceof i&&n.parent()==r&&(r.items().filter("MenuButton").each(function(e){e.hideMenu&&e!=n&&(e.menu&&e.menu.visible()&&(o=!0),e.hideMenu())}),o&&(n.focus(),n.showMenu()))}),e._super()},bindStates:function(){var e=this;return e.state.on("change:menu",function(){e.menu&&e.menu.remove(),e.menu=null}),e._super()},remove:function(){this._super(),this.menu&&this.menu.remove()}});return i}),r(ut,[Ie,ne,u],function(e,t,n){return e.extend({Defaults:{border:0,role:"menuitem"},init:function(e){var t=this,n;t._super(e),e=t.settings,t.classes.add("menu-item"),e.menu&&t.classes.add("menu-item-expand"),e.preview&&t.classes.add("menu-item-preview"),n=t.state.get("text"),("-"===n||"|"===n)&&(t.classes.add("menu-item-sep"),t.aria("role","separator"),t.state.set("text","-")),e.selectable&&(t.aria("role","menuitemcheckbox"),t.classes.add("menu-item-checkbox"),e.icon="selected"),e.preview||e.selectable||t.classes.add("menu-item-normal"),t.on("mousedown",function(e){e.preventDefault()}),e.menu&&!e.ariaHideMenu&&t.aria("haspopup",!0)},hasMenus:function(){return!!this.settings.menu},showMenu:function(){var e=this,n=e.settings,r,i=e.parent();if(i.items().each(function(t){t!==e&&t.hideMenu()}),n.menu){r=e.menu,r?r.show():(r=n.menu,r.length?r={type:"menu",items:r}:r.type=r.type||"menu",i.settings.itemDefaults&&(r.itemDefaults=i.settings.itemDefaults),r=e.menu=t.create(r).parent(e).renderTo(),r.reflow(),r.on("cancel",function(t){t.stopPropagation(),e.focus(),r.hide()}),r.on("show hide",function(e){e.control.items().each(function(e){e.active(e.settings.selected)})}).fire("show"),r.on("hide",function(t){t.control===r&&e.classes.remove("selected")}),r.submenu=!0),r._parentMenu=i,r.classes.add("menu-sub");var o=r.testMoveRel(e.getEl(),e.isRtl()?["tl-tr","bl-br","tr-tl","br-bl"]:["tr-tl","br-bl","tl-tr","bl-br"]);r.moveRel(e.getEl(),o),r.rel=o,o="menu-sub-"+o,r.classes.remove(r._lastRel).add(o),r._lastRel=o,e.classes.add("selected"),e.aria("expanded",!0)}},hideMenu:function(){var e=this;return e.menu&&(e.menu.items().each(function(e){e.hideMenu&&e.hideMenu()}),e.menu.hide(),e.aria("expanded",!1)),e},renderHtml:function(){function e(e){var t,r,i={};for(i=n.mac?{alt:"⌥",ctrl:"⌘",shift:"⇧",meta:"⌘"}:{meta:"Ctrl"},e=e.split("+"),t=0;t'+("-"!==a?'\xa0":"")+("-"!==a?''+a+"":"")+(c?'
'+c+"
":"")+(i.menu?'
':"")+""},postRender:function(){var e=this,t=e.settings,n=t.textStyle;if("function"==typeof n&&(n=n.call(this)),n){var r=e.getEl("text");r&&r.setAttribute("style",n)}return e.on("mouseenter click",function(n){n.control===e&&(t.menu||"click"!==n.type?(e.showMenu(),n.aria&&e.menu.focus(!0)):(e.fire("select"),e.parent().hideAll()))}),e._super(),e},active:function(e){return"undefined"!=typeof e&&this.aria("checked",e),this._super(e)},remove:function(){this._super(),this.menu&&this.menu.remove()}})}),r(dt,[ue,ut,f],function(e,t,n){var r=e.extend({Defaults:{defaultType:"menuitem",border:1,layout:"stack",role:"application",bodyRole:"menu",ariaRoot:!0},init:function(e){var t=this;if(e.autohide=!0,e.constrainToViewport=!0,e.itemDefaults)for(var r=e.items,i=r.length;i--;)r[i]=n.extend({},e.itemDefaults,r[i]);t._super(e),t.classes.add("menu")},repaint:function(){return this.classes.toggle("menu-align",!0),this._super(),this.getEl().style.height="",this.getEl("body").style.height="",this},cancel:function(){var e=this;e.hideAll(),e.fire("select")},hideAll:function(){var e=this;return this.find("menuitem").exec("hideMenu"),e._super()},preRender:function(){var e=this;return e.items().each(function(t){var n=t.settings;return n.icon||n.image||n.selectable?(e._hasIcons=!0,!1):void 0}),e._super()}});return r}),r(ft,[ct,dt],function(e,t){return e.extend({init:function(e){function t(r){for(var a=0;a0&&(o=r[0].text,n.state.set("value",r[0].value)),n.state.set("menu",r)),n.state.set("text",e.text||o||r[0].text),n.classes.add("listbox"),n.on("select",function(t){var r=t.control;a&&(t.lastControl=a),e.multiple?r.active(!r.active()):n.value(t.control.value()),a=r})},bindStates:function(){function e(e,n){e instanceof t&&e.items().each(function(e){e.hasMenus()||e.active(e.value()===n)})}function n(e,t){var r;if(e)for(var i=0;i=r.x&&o.x+o.w<=r.w+r.x&&o.y>=r.y&&o.y+o.h<=r.h+r.y)return i[a]}function n(e,t,n){return{x:e.x-t,y:e.y-n,w:e.w+2*t,h:e.h+2*n}}function r(e,t){var n,r,i,s;return n=a(e.x,t.x),r=a(e.y,t.y),i=o(e.x+e.w,t.x+t.w),s=o(e.y+e.h,t.y+t.h),0>i-n||0>s-r?null:{x:n,y:r,w:i-n,h:s-r}}function i(e,t,n){var r,i,o,s,l,c,u,d,f,h;return l=e.x,c=e.y,u=e.x+e.w,d=e.y+e.h,f=t.x+t.w,h=t.y+t.h,r=a(0,t.x-l),i=a(0,t.y-c),o=a(0,u-f),s=a(0,d-h),l+=r,c+=i,n&&(u+=r,d+=i,l-=o,c-=s),u-=o,d-=s,{x:l,y:c,w:u-l,h:d-c}}var o=Math.min,a=Math.max,s=Math.round;return{inflate:n,relativePosition:e,findBestRelativePosition:t,intersect:r,clamp:i}}),r(mt,[Ie,oe],function(e,t){return e.extend({renderHtml:function(){var e=this,t=e.classPrefix;return e.classes.add("resizehandle"),"both"==e.settings.direction&&e.classes.add("resizehandle-both"),e.canFocus=!1,'
'},postRender:function(){var e=this;e._super(),e.resizeDragHelper=new t(this._id,{start:function(){e.fire("ResizeStart")},drag:function(t){"both"!=e.settings.direction&&(t.deltaX=0),e.fire("Resize",t)},stop:function(){e.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),r(gt,[Ie,oe,J],function(e,t,n){function r(e,t,n){return t>e&&(e=t),e>n&&(e=n),e}function i(e,t){var r,i,o,a,s;"v"==e.settings.orientation?(a="top",o="height",i="h"):(a="left",o="width",i="w"),r=(e.layoutRect()[i]||100)-n.getSize(e.getEl("handle"))[o],s=r*((t-e._minValue)/(e._maxValue-e._minValue))+"px",e.getEl("handle").style[a]=s,e.getEl("handle").style.height=e.layoutRect().h+"px"}return e.extend({init:function(e){var t=this;e.previewFilter||(e.previewFilter=function(e){return Math.round(100*e)/100}),t._super(e),t.classes.add("slider"),"v"==e.orientation&&t.classes.add("vertical"),t._minValue=e.minValue||0,t._maxValue=e.maxValue||100,t._initValue=t.state.get("value")},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix;return'
'},reset:function(){this.value(this._initValue).repaint()},postRender:function(){var e=this,i,o,a=0,s,l,c,u,d,f,h,p;l=e._minValue,c=e._maxValue,s=e.value(),"v"==e.settings.orientation?(d="screenY",f="top",h="height",p="h"):(d="screenX",f="left",h="width",p="w"),e._super(),e._dragHelper=new t(e._id,{handle:e._id+"-handle",start:function(t){i=t[d],o=parseInt(e.getEl("handle").style[f],10),u=(e.layoutRect()[p]||100)-n.getSize(e.getEl("handle"))[h],e.fire("dragstart",{value:s})},drag:function(t){var n=t[d]-i,h=e.getEl("handle");a=r(o+n,0,u),h.style[f]=a+"px",s=l+a/u*(c-l),e.value(s),e.tooltip().text(""+e.settings.previewFilter(s)).show().moveRel(h,"bc tc"),e.fire("drag",{value:s})},stop:function(){e.tooltip().hide(),e.fire("dragend",{value:s})}})},repaint:function(){this._super(),i(this,this.value())},bindStates:function(){var e=this;return e.state.on("change:value",function(t){i(e,t.value)}),e._super()}})}),r(vt,[Ie],function(e){return e.extend({renderHtml:function(){var e=this;return e.classes.add("spacer"),e.canFocus=!1, -'
'}})}),r(yt,[ct,J,h],function(e,t,n){return e.extend({Defaults:{classes:"widget btn splitbtn",role:"button"},repaint:function(){var e=this,r=e.getEl(),i=e.layoutRect(),o,a;return e._super(),o=r.firstChild,a=r.lastChild,n(o).css({width:i.w-t.getSize(a).width,height:i.h-2}),n(a).css({height:i.h-2}),e},activeMenu:function(e){var t=this;n(t.getEl().lastChild).toggleClass(t.classPrefix+"active",e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r,i=e.state.get("icon"),o=e.state.get("text");return r=e.settings.image,r?(i="none","string"!=typeof r&&(r=window.getSelection?r[0]:r[1]),r=" style=\"background-image: url('"+r+"')\""):r="",i=e.settings.icon?n+"ico "+n+"i-"+i:"",'
'},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(e){var n=e.target;if(e.control==this)for(;n;){if(e.aria&&"down"!=e.aria.key||"BUTTON"==n.nodeName&&-1==n.className.indexOf("open"))return e.stopImmediatePropagation(),void(t&&t.call(this,e));n=n.parentNode}}),delete e.settings.onclick,e._super()}})}),r(bt,[nt],function(e){return e.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"},isNative:function(){return!0}})}),r(xt,[se,h,J],function(e,t,n){return e.extend({Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(e){var n;this.activeTabId&&(n=this.getEl(this.activeTabId),t(n).removeClass(this.classPrefix+"active"),n.setAttribute("aria-selected","false")),this.activeTabId="t"+e,n=this.getEl("t"+e),n.setAttribute("aria-selected","true"),t(n).addClass(this.classPrefix+"active"),this.items()[e].show().fire("showtab"),this.reflow(),this.items().each(function(t,n){e!=n&&t.hide()})},renderHtml:function(){var e=this,t=e._layout,n="",r=e.classPrefix;return e.preRender(),t.preRender(e),e.items().each(function(t,i){var o=e._id+"-t"+i;t.aria("role","tabpanel"),t.aria("labelledby",o),n+='"}),'
'+n+'
'+t.renderHtml(e)+"
"},postRender:function(){var e=this;e._super(),e.settings.activeTab=e.settings.activeTab||0,e.activateTab(e.settings.activeTab),this.on("click",function(t){var n=t.target.parentNode;if(t.target.parentNode.id==e._id+"-head")for(var r=n.childNodes.length;r--;)n.childNodes[r]==t.target&&e.activateTab(r)})},initLayoutRect:function(){var e=this,t,r,i;r=n.getSize(e.getEl("head")).width,r=0>r?0:r,i=0,e.items().each(function(e){r=Math.max(r,e.layoutRect().minW),i=Math.max(i,e.layoutRect().minH)}),e.items().each(function(e){e.settings.x=0,e.settings.y=0,e.settings.w=r,e.settings.h=i,e.layoutRect({x:0,y:0,w:r,h:i})});var o=n.getSize(e.getEl("head")).height;return e.settings.minWidth=r,e.settings.minHeight=i+o,t=e._super(),t.deltaH+=o,t.innerH=t.h-t.deltaH,t}})}),r(Ct,[Ie],function(e){return e.extend({init:function(e){var t=this;t._super(e),t.classes.add("textbox"),e.multiline?t.classes.add("multiline"):(t.on("keydown",function(e){var n;13==e.keyCode&&(e.preventDefault(),t.parents().reverse().each(function(e){return e.toJSON?(n=e,!1):void 0}),t.fire("submit",{data:n.toJSON()}))}),t.on("keyup",function(e){t.state.set("value",e.target.value)}))},repaint:function(){var e=this,t,n,r,i=0,o=0,a;t=e.getEl().style,n=e._layoutRect,a=e._lastRepaintRect||{};var s=document;return!e.settings.multiline&&s.all&&(!s.documentMode||s.documentMode<=8)&&(t.lineHeight=n.h-o+"px"),r=e.borderBox,i=r.left+r.right+8,o=r.top+r.bottom+(e.settings.multiline?8:0),n.x!==a.x&&(t.left=n.x+"px",a.x=n.x),n.y!==a.y&&(t.top=n.y+"px",a.y=n.y),n.w!==a.w&&(t.width=n.w-i+"px",a.w=n.w),n.h!==a.h&&(t.height=n.h-o+"px",a.h=n.h),e._lastRepaintRect=a,e.fire("repaint",{},!1),e},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.encode(e.state.get("value"),!1),i="";return"spellcheck"in n&&(i+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(i+=' maxlength="'+n.maxLength+'"'),n.size&&(i+=' size="'+n.size+'"'),n.subtype&&(i+=' type="'+n.subtype+'"'),e.disabled()&&(i+=' disabled="disabled"'),n.multiline?'":'"},value:function(e){return arguments.length?(this.state.set("value",e),this):(this.state.get("rendered")&&this.state.set("value",this.getEl().value),this.state.get("value"))},postRender:function(){var e=this;e._super(),e.$el.on("change",function(t){e.state.set("value",t.target.value),e.fire("change",t)})},bindStates:function(){var e=this;return e.state.on("change:value",function(t){e.getEl().value!=t.value&&(e.getEl().value=t.value)}),e.state.on("change:disabled",function(t){e.getEl().disabled=t.value}),e._super()},remove:function(){this.$el.off(),this._super()}})}),r(wt,[h,te],function(e,t){return function(n,r){var i=this,o,a=t.classPrefix;i.show=function(t,s){return i.hide(),o=!0,window.setTimeout(function(){o&&(e(n).append('
'),s&&s())},t||0),i},i.hide=function(){var e=n.lastChild;return e&&-1!=e.className.indexOf("throbber")&&e.parentNode.removeChild(e),o=!1,i}}}),a([l,c,u,f,h,p,m,v,b,x,C,w,E,N,S,k,T,R,A,D,M,L,H,I,F,V,U,$,q,K,G,X,ee,te,ne,re,ie,oe,ae,se,le,ce,ue,de,fe,he,me,ge,ve,Ee,Ne,Se,ke,Re,Ae,Be,De,Me,Le,He,Pe,Oe,Ie,Fe,ze,We,Ve,Ue,$e,qe,je,Ke,Ye,Ge,Xe,Je,Qe,Ze,et,tt,nt,rt,it,ot,at,st,lt,ct,ut,dt,ft,ht,pt,mt,gt,vt,yt,bt,xt,Ct,wt])}(this); \ No newline at end of file diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index daaaeca7e0..5b212d79a4 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -327,23 +327,9 @@ - - - - - - - - - - - - - - @@ -1498,7 +1484,6 @@ - @@ -1528,7 +1513,6 @@ - @@ -2671,14 +2655,7 @@ - - - - - - - diff --git a/Website/bower.json b/Website/bower.json index 0d367da774..beabf0bccb 100644 --- a/Website/bower.json +++ b/Website/bower.json @@ -4,6 +4,7 @@ "dependencies": { "codemirror": "5.9.0", "autobahnjs": "autobahn#^0.10.1", - "babel-polyfill": "^0.0.1" + "babel-polyfill": "^0.0.1", + "tinymce": "4.5.7" } } diff --git a/Website/gruntfile.js b/Website/gruntfile.js index fe788e5341..25f08223c1 100644 --- a/Website/gruntfile.js +++ b/Website/gruntfile.js @@ -1,4 +1,4 @@ -/// +ï»ż/// module.exports = function (grunt) { 'use strict'; @@ -45,6 +45,18 @@ module.exports = function (grunt) { files: [ { expand: true, cwd: 'bower_components/babel-polyfill', src: ['browser-polyfill.js'], dest: 'Composite/lib/babel' }, ] + }, + tinymce: { + files: function () { + let tinymceDestFolder = "Composite/content/misc/editors/visualeditor/tinymce"; + let tinymcePlugins = ["autolink", "lists", "paste", "table"]; + let tinymceFiles = [{ expand: true, cwd: 'bower_components/tinymce', src: ['tinymce.min.js'], dest: `${tinymceDestFolder}` }]; + tinymcePlugins.forEach(function (pluginName, index) { + tinymceFiles.push({ expand: true, cwd: `bower_components/tinymce/plugins/${pluginName}`, src: ['*.min.js'], dest: `${tinymceDestFolder}/plugins/${pluginName}` }); + }); + tinymceFiles.push({ expand: true, cwd: `bower_components/tinymce/skins/lightgray`, src: ['**'], dest: `${tinymceDestFolder}/skins/lightgray` }); + return tinymceFiles; + }() } }); @@ -277,7 +289,7 @@ module.exports = function (grunt) { .replace('', '') .replace('xlink:href="#', 'xlink:href="#icon-') - .replace(/(?:stroke|fill)="#(?:([0-9a-eA-E])\1{2,5})"/g, '') + .replace(/(?:stroke|fill)="#(?:([0-9a-eA-E])\1{2,5})"/g, '') + '\r\n'; }); outputText += '\r\n'; From c80e6106ef3e59c84ad385c7239cd3d83d7b3417 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 26 Apr 2017 14:27:23 +0200 Subject: [PATCH 134/135] Fixed the issue of temporary ASP.NET assemblies not being resolved correctly --- Composite/AspNet/TempAssembliesFix.cs | 40 +++++++++++++++++++++++++++ Composite/Composite.csproj | 1 + 2 files changed, 41 insertions(+) create mode 100644 Composite/AspNet/TempAssembliesFix.cs diff --git a/Composite/AspNet/TempAssembliesFix.cs b/Composite/AspNet/TempAssembliesFix.cs new file mode 100644 index 0000000000..25480401a6 --- /dev/null +++ b/Composite/AspNet/TempAssembliesFix.cs @@ -0,0 +1,40 @@ +ï»żusing System; +using System.Linq; +using System.Reflection; +using Composite.Core; +using Composite.Core.Application; + +namespace Composite.AspNet +{ + /// + /// Fixed the issue of temporary asp.net assemblies not being resolved correctly. + /// + [ApplicationStartup] + class TempAssembliesFix + { + public static void OnInitialized() + { + AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; + } + + private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args) + { + string asmName = args.Name; + + if (!asmName.StartsWith("App_") || !asmName.Contains(",")) + { + return null; + } + + var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(asm => asm.FullName == asmName); + if (assembly != null) + { + return assembly; + } + + Log.LogVerbose("OnAssemblyResolve", $"Failed to resolve assembly: {args.Name}" + + (args.RequestingAssembly != null ? $", requesting assembly: '{args.RequestingAssembly.FullName}'" : "")); + return null; + } + } +} diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 77ea1ca4d7..62a2d7d06f 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -228,6 +228,7 @@ + ASPXCodeBehind From e3aca58949a52043ab2713b0123e9f95d53446a0 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Wed, 26 Apr 2017 16:27:57 +0200 Subject: [PATCH 135/135] Search - not indexing