diff --git a/Credits.txt b/Credits.txt
index b202dce0..1284b58f 100644
--- a/Credits.txt
+++ b/Credits.txt
@@ -6,7 +6,7 @@ has been used throughout Invision Community to add style, flair and functionalit
to our product.
NULLING
- Last Updated: 5 November 2025
+ Last Updated: 9 December 2025
Author: https://ipbmafia.ru
AES implementation in PHP
diff --git a/admin/assets/css/forms.css b/admin/assets/css/forms.css
index d8bfd292..c49ac65e 100644
--- a/admin/assets/css/forms.css
+++ b/admin/assets/css/forms.css
@@ -460,89 +460,4 @@ label input{
/* Install: Admin username, password, email */
.ipsFieldRow[id^="admin_admin_"] input{
justify-self: stretch;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-@supports(display:ehren){
-
-
-
-
-
-.ipsFieldRow:not( :last-child ) {
-
- margin-bottom: 15px;
-}
-
-/* FIELD LISTS (for stacks of radios/checkboxes) */
-.ipsFieldList {
- padding-top: 7px;
-}
-
-.ipsFieldList > li {
- margin-bottom: 10px;
-}
-
-.ipsFieldList input[type="radio"], .ipsFieldList input[type="checkbox"] {
- float: left;
- margin-top: 4px;
-}
-
-.ipsFieldList__content {
- margin-left: 22px;
-}
-
-/* FORM TYPOGRAPHY */
-.ipsFieldRow__desc {
- font-size: 12px;
- color: #adadad;
- margin-top: 3px;
- display: inline-block;
-}
-
-.ipsFieldRow:not( .ipsFieldRow_checkbox ) .ipsFieldRow_label,
-.ipsFieldRow:not( .ipsFieldRow_checkbox ) .ipsFieldRow_title {
- font-size: 15px;
- font-weight: bold;
- margin-bottom: 5px;
- display: inline-block;
- padding-top: 5px;
-}
-
-.ipsFieldRow__required {
- font-size: 10px;
- text-transform: uppercase;
- color: #c02222;
- margin-left: 10px;
- font-weight: normal;
-}
-
-
-
-.ipsFieldRow__content select {
- margin-top: 6px;
-}
-
-.ipsFieldRow_section {
- background: #f9f9f9;
- color: #333;
- padding: 15px;
- font-size: 16px;
- margin-bottom: 10px;
-}
-
-
-
}
\ No newline at end of file
diff --git a/admin/install/eula.txt b/admin/install/eula.txt
index 3c70a5cc..bde365d0 100644
--- a/admin/install/eula.txt
+++ b/admin/install/eula.txt
@@ -3,7 +3,7 @@
Nulled by IPBMafia.ru
Buy license at https://invisioncommunity.com/buy/self-hosted/
================================================================
- IPS 5.0.13 (5001302)
+ IPS 5.0.14 (5001403)
=============================[NOTE]=============================
Invision Community End User License Agreement
diff --git a/applications/blog/Application.php b/applications/blog/Application.php
index 7550537f..6b295a74 100644
--- a/applications/blog/Application.php
+++ b/applications/blog/Application.php
@@ -105,7 +105,7 @@ class Application extends SystemApplication
}
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
- Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE, parseFileObjects: FALSE );
+ Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE, parseFileObjects: true );
}
/**
diff --git a/applications/blog/data/javascript.xml b/applications/blog/data/javascript.xml
index 71419ff1..b797a291 100644
--- a/applications/blog/data/javascript.xml
+++ b/applications/blog/data/javascript.xml
@@ -1,6 +1,6 @@
-
- {{#lang}}manage_cats_new_row{{/lang}} \
");
diff --git a/applications/blog/data/lang.xml b/applications/blog/data/lang.xml
index ebe5540c..f273a6ba 100644
--- a/applications/blog/data/lang.xml
+++ b/applications/blog/data/lang.xml
@@ -1,6 +1,6 @@
-
+
Blogs
Blogs
a comment on a blog entry
diff --git a/applications/blog/data/versions.json b/applications/blog/data/versions.json
index 4631b0ac..15bde495 100644
--- a/applications/blog/data/versions.json
+++ b/applications/blog/data/versions.json
@@ -275,6 +275,19 @@
"107799": "4.7.20 Beta 5",
"107800": "4.7.20",
"107801": "4.7.20",
+ "107802": "4.7.20",
+ "107803": "4.7.20",
+ "107810": "4.7.21 Beta 1",
+ "107811": "4.7.21",
+ "107815": "4.7.22 Beta 1",
+ "107816": "4.7.22 Beta 2",
+ "107817": "4.7.22",
+ "107818": "4.7.22",
+ "107819": "4.7.22",
+ "107820": "4.7.22",
+ "107826": "4.7.23 Beta 1",
+ "107827": "4.7.23",
+ "107828": "4.7.23",
"500001": "5.0.0 Alpha 1",
"500002": "5.0.0 Alpha 2",
"5000003": "5.0.0 Alpha 3",
@@ -397,5 +410,9 @@
"5001204": "5.0.12",
"5001300": "5.0.13 Beta 1",
"5001301": "5.0.13 Beta 2",
- "5001302": "5.0.13"
+ "5001302": "5.0.13",
+ "5001400": "5.0.14 Beta 1",
+ "5001401": "5.0.14 Beta 1",
+ "5001402": "5.0.14 Beta 2",
+ "5001403": "5.0.14"
}
\ No newline at end of file
diff --git a/applications/blog/extensions/core/ModeratorPermissions/Blogs.php b/applications/blog/extensions/core/ModeratorPermissions/Blogs.php
index f6feb887..91692d27 100644
--- a/applications/blog/extensions/core/ModeratorPermissions/Blogs.php
+++ b/applications/blog/extensions/core/ModeratorPermissions/Blogs.php
@@ -27,6 +27,12 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class Blogs extends ModeratorPermissionsAbstract
{
+ public function getPermissions( array $toggles ): array
+ {
+ /* Leave this empty because we are going to just add to the existing Blogs tab */
+ return [];
+ }
+
/**
* Get Permissions
*
@@ -45,7 +51,7 @@ class Blogs extends ModeratorPermissionsAbstract
* @param array $toggles
* @return array
*/
- public function getPermissions( array $toggles ): array
+ public function getContentPermissions( array $toggles ): array
{
return array( 'can_mod_blogs' => 'YesNo' );
}
diff --git a/applications/blog/setup/upg_107802/data.json b/applications/blog/setup/upg_107802/data.json
new file mode 100644
index 00000000..e8c7ffe8
--- /dev/null
+++ b/applications/blog/setup/upg_107802/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107802,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107803/data.json b/applications/blog/setup/upg_107803/data.json
new file mode 100644
index 00000000..c303dba8
--- /dev/null
+++ b/applications/blog/setup/upg_107803/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107803,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107810/data.json b/applications/blog/setup/upg_107810/data.json
new file mode 100644
index 00000000..d6859da8
--- /dev/null
+++ b/applications/blog/setup/upg_107810/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107810,
+ "name": "4.7.21 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107811/data.json b/applications/blog/setup/upg_107811/data.json
new file mode 100644
index 00000000..21427d5d
--- /dev/null
+++ b/applications/blog/setup/upg_107811/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107811,
+ "name": "4.7.21",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107815/data.json b/applications/blog/setup/upg_107815/data.json
new file mode 100644
index 00000000..069df6ab
--- /dev/null
+++ b/applications/blog/setup/upg_107815/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107815,
+ "name": "4.7.22 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107816/data.json b/applications/blog/setup/upg_107816/data.json
new file mode 100644
index 00000000..f33f25af
--- /dev/null
+++ b/applications/blog/setup/upg_107816/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107816,
+ "name": "4.7.22 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107817/data.json b/applications/blog/setup/upg_107817/data.json
new file mode 100644
index 00000000..29b49df9
--- /dev/null
+++ b/applications/blog/setup/upg_107817/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107817,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107818/data.json b/applications/blog/setup/upg_107818/data.json
new file mode 100644
index 00000000..26c77bc5
--- /dev/null
+++ b/applications/blog/setup/upg_107818/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107818,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107819/data.json b/applications/blog/setup/upg_107819/data.json
new file mode 100644
index 00000000..968a94ca
--- /dev/null
+++ b/applications/blog/setup/upg_107819/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107819,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107820/data.json b/applications/blog/setup/upg_107820/data.json
new file mode 100644
index 00000000..5082a5f4
--- /dev/null
+++ b/applications/blog/setup/upg_107820/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107820,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107826/data.json b/applications/blog/setup/upg_107826/data.json
new file mode 100644
index 00000000..67c4b57c
--- /dev/null
+++ b/applications/blog/setup/upg_107826/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107826,
+ "name": "4.7.23 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107827/data.json b/applications/blog/setup/upg_107827/data.json
new file mode 100644
index 00000000..d8181b24
--- /dev/null
+++ b/applications/blog/setup/upg_107827/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107827,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_107828/data.json b/applications/blog/setup/upg_107828/data.json
new file mode 100644
index 00000000..41933acb
--- /dev/null
+++ b/applications/blog/setup/upg_107828/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107828,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_5001400/data.json b/applications/blog/setup/upg_5001400/data.json
new file mode 100644
index 00000000..1571e915
--- /dev/null
+++ b/applications/blog/setup/upg_5001400/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001400,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_5001401/data.json b/applications/blog/setup/upg_5001401/data.json
new file mode 100644
index 00000000..6954be4a
--- /dev/null
+++ b/applications/blog/setup/upg_5001401/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001401,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_5001402/data.json b/applications/blog/setup/upg_5001402/data.json
new file mode 100644
index 00000000..daadfa3b
--- /dev/null
+++ b/applications/blog/setup/upg_5001402/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001402,
+ "name": "5.0.14 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/blog/setup/upg_5001403/data.json b/applications/blog/setup/upg_5001403/data.json
new file mode 100644
index 00000000..21b48da4
--- /dev/null
+++ b/applications/blog/setup/upg_5001403/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001403,
+ "name": "5.0.14",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/Application.php b/applications/calendar/Application.php
index dcd5d9ca..cca80d15 100644
--- a/applications/calendar/Application.php
+++ b/applications/calendar/Application.php
@@ -128,7 +128,7 @@ class Application extends SystemApplication
$ics = $feed->buildICalendarFeed( $calendar );
- Output::i()->sendOutput( $ics, 200, 'text/calendar', [ 'Content-Disposition' => Output::getContentDisposition( 'inline', "calendarEvents.ics" ) ], FALSE, FALSE, FALSE );
+ Output::i()->sendOutput( $ics, 200, 'text/calendar', [ 'Content-Disposition' => Output::getContentDisposition( 'inline', "calendarEvents.ics" ) ], FALSE, FALSE, true );
}
/**
@@ -171,7 +171,7 @@ class Application extends SystemApplication
}
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
- Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
+ Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', parseFileObjects: true );
}
/**
diff --git a/applications/calendar/data/build.xml b/applications/calendar/data/build.xml
index 0bb05b1f..a9063488 100644
--- a/applications/calendar/data/build.xml
+++ b/applications/calendar/data/build.xml
@@ -5,6 +5,7 @@
icalendar
eventreminders
+ clearfeaturedevents
diff --git a/applications/calendar/data/javascript.xml b/applications/calendar/data/javascript.xml
index 753a6ba7..630a67e8 100644
--- a/applications/calendar/data/javascript.xml
+++ b/applications/calendar/data/javascript.xml
@@ -1,6 +1,6 @@
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -2087,7 +2087,7 @@ var PER_PAGE = 16;
});
}(jQuery, _));
- \
");]]>
-
diff --git a/applications/calendar/data/lang.xml b/applications/calendar/data/lang.xml
index c0edbb7c..1d9b039d 100644
--- a/applications/calendar/data/lang.xml
+++ b/applications/calendar/data/lang.xml
@@ -1,6 +1,6 @@
-
+
Events
Events
a comment on an event
@@ -89,6 +89,9 @@
Allow comments?
Allow reviews?
Reviews must be approved?
+ Allow recurring events?
+ Include in Overview
+ events landing page. Featured events will always be displayed in the overview.]]>
See Calendar
View Events
diff --git a/applications/calendar/data/tasks.json b/applications/calendar/data/tasks.json
index 3f38252e..c85763a6 100644
--- a/applications/calendar/data/tasks.json
+++ b/applications/calendar/data/tasks.json
@@ -1 +1 @@
-{"icalendar":"P0Y0M0DT4H0M0S","eventreminders":"P0Y0M0DT1H0M0S"}
\ No newline at end of file
+{"icalendar":"P0Y0M0DT4H0M0S","eventreminders":"P0Y0M0DT1H0M0S","clearfeaturedevents":"P0Y0M1DT0H0M0S"}
\ No newline at end of file
diff --git a/applications/calendar/data/theme.xml b/applications/calendar/data/theme.xml
index 215ef5fd..59cbd563 100644
--- a/applications/calendar/data/theme.xml
+++ b/applications/calendar/data/theme.xml
@@ -1549,6 +1549,7 @@
+ {{if $value['allow_recurring']}}
{lang="submit_event_summary"}
@@ -1623,6 +1624,10 @@
+ {{else}}
+
+
+ {{endif}}
]]>
calendar_bitoptions['bw_hide_overview'];
+ });
+
/* Events near me */
if( isset( Request::i()->lat ) and isset( Request::i()->lon ) )
{
diff --git a/applications/calendar/setup/upg_107802/data.json b/applications/calendar/setup/upg_107802/data.json
new file mode 100644
index 00000000..e8c7ffe8
--- /dev/null
+++ b/applications/calendar/setup/upg_107802/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107802,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107803/data.json b/applications/calendar/setup/upg_107803/data.json
new file mode 100644
index 00000000..c303dba8
--- /dev/null
+++ b/applications/calendar/setup/upg_107803/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107803,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107810/data.json b/applications/calendar/setup/upg_107810/data.json
new file mode 100644
index 00000000..d6859da8
--- /dev/null
+++ b/applications/calendar/setup/upg_107810/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107810,
+ "name": "4.7.21 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107811/data.json b/applications/calendar/setup/upg_107811/data.json
new file mode 100644
index 00000000..21427d5d
--- /dev/null
+++ b/applications/calendar/setup/upg_107811/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107811,
+ "name": "4.7.21",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107815/data.json b/applications/calendar/setup/upg_107815/data.json
new file mode 100644
index 00000000..069df6ab
--- /dev/null
+++ b/applications/calendar/setup/upg_107815/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107815,
+ "name": "4.7.22 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107816/data.json b/applications/calendar/setup/upg_107816/data.json
new file mode 100644
index 00000000..f33f25af
--- /dev/null
+++ b/applications/calendar/setup/upg_107816/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107816,
+ "name": "4.7.22 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107817/data.json b/applications/calendar/setup/upg_107817/data.json
new file mode 100644
index 00000000..29b49df9
--- /dev/null
+++ b/applications/calendar/setup/upg_107817/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107817,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107818/data.json b/applications/calendar/setup/upg_107818/data.json
new file mode 100644
index 00000000..26c77bc5
--- /dev/null
+++ b/applications/calendar/setup/upg_107818/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107818,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107819/data.json b/applications/calendar/setup/upg_107819/data.json
new file mode 100644
index 00000000..968a94ca
--- /dev/null
+++ b/applications/calendar/setup/upg_107819/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107819,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107820/data.json b/applications/calendar/setup/upg_107820/data.json
new file mode 100644
index 00000000..5082a5f4
--- /dev/null
+++ b/applications/calendar/setup/upg_107820/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107820,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107826/data.json b/applications/calendar/setup/upg_107826/data.json
new file mode 100644
index 00000000..67c4b57c
--- /dev/null
+++ b/applications/calendar/setup/upg_107826/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107826,
+ "name": "4.7.23 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107827/data.json b/applications/calendar/setup/upg_107827/data.json
new file mode 100644
index 00000000..d8181b24
--- /dev/null
+++ b/applications/calendar/setup/upg_107827/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107827,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_107828/data.json b/applications/calendar/setup/upg_107828/data.json
new file mode 100644
index 00000000..41933acb
--- /dev/null
+++ b/applications/calendar/setup/upg_107828/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107828,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001400/data.json b/applications/calendar/setup/upg_5001400/data.json
new file mode 100644
index 00000000..4a526476
--- /dev/null
+++ b/applications/calendar/setup/upg_5001400/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001400,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": true,
+ "theme": true,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": true,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001400/lang.json b/applications/calendar/setup/upg_5001400/lang.json
new file mode 100644
index 00000000..929ffeaf
--- /dev/null
+++ b/applications/calendar/setup/upg_5001400/lang.json
@@ -0,0 +1,16 @@
+{
+ "normal": {
+ "added": [
+ "cal_allow_recurring",
+ "cal_show_overview",
+ "cal_show_overview_desc"
+ ],
+ "edited": [],
+ "removed": []
+ },
+ "js": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ }
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001400/tasks.json b/applications/calendar/setup/upg_5001400/tasks.json
new file mode 100644
index 00000000..5d493103
--- /dev/null
+++ b/applications/calendar/setup/upg_5001400/tasks.json
@@ -0,0 +1,7 @@
+{
+ "added": [
+ "clearfeaturedevents"
+ ],
+ "edited": [],
+ "removed": []
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001400/theme.json b/applications/calendar/setup/upg_5001400/theme.json
new file mode 100644
index 00000000..3659b71d
--- /dev/null
+++ b/applications/calendar/setup/upg_5001400/theme.json
@@ -0,0 +1,19 @@
+{
+ "html": {
+ "added": [],
+ "edited": [
+ "front\/submit\/datesForm"
+ ],
+ "removed": []
+ },
+ "css": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ },
+ "resources": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ }
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001401/data.json b/applications/calendar/setup/upg_5001401/data.json
new file mode 100644
index 00000000..6954be4a
--- /dev/null
+++ b/applications/calendar/setup/upg_5001401/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001401,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001402/data.json b/applications/calendar/setup/upg_5001402/data.json
new file mode 100644
index 00000000..daadfa3b
--- /dev/null
+++ b/applications/calendar/setup/upg_5001402/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001402,
+ "name": "5.0.14 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/setup/upg_5001403/data.json b/applications/calendar/setup/upg_5001403/data.json
new file mode 100644
index 00000000..21b48da4
--- /dev/null
+++ b/applications/calendar/setup/upg_5001403/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001403,
+ "name": "5.0.14",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/calendar/sources/Calendar/Calendar.php b/applications/calendar/sources/Calendar/Calendar.php
index 6450fc27..9b7ba158 100644
--- a/applications/calendar/sources/Calendar/Calendar.php
+++ b/applications/calendar/sources/Calendar/Calendar.php
@@ -145,7 +145,9 @@ class Calendar extends Model implements Permissions
'calendar_bitoptions' => array(
'calendar_bitoptions' => array(
'bw_disable_tagging' => 1,
- 'bw_disable_prefixes' => 2
+ 'bw_disable_prefixes' => 2,
+ 'bw_disable_recurring' => 4,
+ 'bw_hide_overview' => 8
)
)
);
@@ -239,6 +241,8 @@ class Calendar extends Model implements Permissions
$form->add( new YesNo( 'cal_allow_reviews', $this->id ? $this->allow_reviews : FALSE, FALSE, array( 'togglesOn' => array( 'cal_review_moderate' ) ) ) );
$form->add( new YesNo( 'cal_review_moderate', $this->id ? $this->review_moderate : FALSE, FALSE, array(), NULL, NULL, NULL, 'cal_review_moderate' ) );
$form->add( new YesNo( 'cal_allow_anonymous', $this->id ? $this->allow_anonymous : FALSE, FALSE, array(), NULL, NULL, NULL, 'cal_allow_anonymous' ) );
+ $form->add( new YesNo( 'cal_allow_recurring', $this->id ? !$this->calendar_bitoptions['bw_disable_recurring'] : true, false ) );
+ $form->add( new YesNo( 'cal_show_overview', $this->id ? !$this->calendar_bitoptions['bw_hide_overview'] : true, false ) );
parent::form( $form );
}
@@ -264,6 +268,13 @@ class Calendar extends Model implements Permissions
unset( $values['cal_title'] );
}
+ /* These are reversed because we want to default to previous behavior, which means that the bit options would be turned OFF.
+ However, to the end-user it makes more sense to disable it as opposed to enable */
+ $values['calendar_bitoptions']['bw_disable_recurring'] = !$values['cal_allow_recurring'];
+ $values['calendar_bitoptions']['bw_hide_overview'] = !$values['cal_show_overview'];
+ unset( $values['cal_allow_recurring'] );
+ unset( $values['cal_show_overview'] );
+
return $values;
}
diff --git a/applications/calendar/sources/Event/Event.php b/applications/calendar/sources/Event/Event.php
index d343fdeb..aff2620e 100644
--- a/applications/calendar/sources/Event/Event.php
+++ b/applications/calendar/sources/Event/Event.php
@@ -1446,6 +1446,7 @@ class Event extends Item implements Embeddable,
'event_repeat_freq' => NULL, /* Repeat every 1 day, 2 days, 3 days, etc. */
'repeat_end_occurrences' => NULL, /* Ends after x occurrences */
'repeat_end_date' => NULL, /* Ends on x date (which is separate from the event end date - e.g. jan 9 2014 3pm to jan 10 2014 3pm, repeat annually until jan 9 2019) */
+ 'allow_recurring' => ( !$container->calendar_bitoptions['bw_disable_recurring'] )
);
/* If we're copying an event, reset the date & time fields */
@@ -1463,7 +1464,7 @@ class Event extends Item implements Embeddable,
}
/* Figure out the recurrence data if we are editing */
- if ( $item AND $item->recurring )
+ if ( $item AND $item->recurring AND $dateValues['allow_recurring'] )
{
try
{
@@ -1768,6 +1769,13 @@ class Event extends Item implements Embeddable,
$this->start_date = Date::createFromForm( $values['event_dates']['start_date'], ( ( !isset( $values['event_dates']['all_day'] ) OR !$values['event_dates']['all_day'] ) ? $values['event_dates']['start_time'] : '' ), ( isset( $values['event_dates']['all_day'] ) AND $values['event_dates']['all_day'] ) ? 'UTC' : $values['event_dates']['event_timezone'] )->format( 'Y-m-d H:i' );
$this->end_date = null;
+ /* If the calendar does not allow recurring events, force the settings */
+ if( $this->container()->calendar_bitoptions['bw_disable_recurring'] )
+ {
+ $values['event_dates']['repeat_end'] = 'never';
+ $values['event_dates']['event_repeat'] = 0;
+ }
+
/* Clear clear fields for non-selected items */
switch( $values['event_dates']['repeat_end'] )
{
@@ -2279,57 +2287,61 @@ class Event extends Item implements Embeddable,
$formattedEvents = iterator_to_array( $events );
}
- /* Now get the recurring events.... */
- $recurringEvents = Event::getItemsWithPermission( array_merge( $where, array( array( "event_recurring IS NOT NULL AND (event_recurring_end_date IS NULL OR DATE(event_recurring_end_date) >= '{$startDate->mysqlDatetime( FALSE )}')" ) ) ), 'event_start_date ASC', NULL, ( $skipPermissions === TRUE ) ? NULL : 'view', ( $skipPermissions === TRUE ) ? Filter::FILTER_SHOW_HIDDEN : Filter::FILTER_AUTOMATIC, 0, $member, FALSE, FALSE, FALSE,FALSE, NULL, FALSE, TRUE, TRUE, TRUE, FALSE, $location );
-
- /* Loop over any results */
- foreach( $recurringEvents as $event )
+ /* Now get the recurring events....
+ If we only have one calendar, and it does not allow recurring events, we can skip this extra query */
+ if( !( $calendar instanceof Calendar ) or !$calendar->calendar_bitoptions['bw_disable_recurring'] )
{
- /* @var Event $event */
- /* Find occurrences within our date range (if any) */
- $thisEndDate = ( $endDate ? $endDate->setTime( 23, 59, 59 ) : $startDate->adjust( "+2 years" ) )->setTime( 23, 59, 59 );
- $thisEndDate = ( clone $thisEndDate )->adjust( "+1 day" );
- $occurrences = $event->findOccurrences( $startDate, $thisEndDate );
+ $recurringEvents = Event::getItemsWithPermission( array_merge( $where, array( array( "event_recurring IS NOT NULL AND (event_recurring_end_date IS NULL OR DATE(event_recurring_end_date) >= '{$startDate->mysqlDatetime( FALSE )}')" ) ) ), 'event_start_date ASC', NULL, ( $skipPermissions === TRUE ) ? NULL : 'view', ( $skipPermissions === TRUE ) ? Filter::FILTER_SHOW_HIDDEN : Filter::FILTER_AUTOMATIC, 0, $member, FALSE, FALSE, FALSE,FALSE, NULL, FALSE, TRUE, TRUE, TRUE, FALSE, $location );
- /* Do we have any? */
- if ( count( $occurrences ) )
+ /* Loop over any results */
+ foreach( $recurringEvents as $event )
{
- /* Are we formatting events? If so, place into the array as appropriate. */
- if ( $formatEvents )
+ /* @var Event $event */
+ /* Find occurrences within our date range (if any) */
+ $thisEndDate = ( $endDate ? $endDate->setTime( 23, 59, 59 ) : $startDate->adjust( "+2 years" ) )->setTime( 23, 59, 59 );
+ $thisEndDate = ( clone $thisEndDate )->adjust( "+1 day" );
+ $occurrences = $event->findOccurrences( $startDate, $thisEndDate );
+
+ /* Do we have any? */
+ if ( count( $occurrences ) )
{
- foreach( $occurrences as $occurrence )
+ /* Are we formatting events? If so, place into the array as appropriate. */
+ if ( $formatEvents )
{
- /* Is this a ranged repeating event? */
- if ( $occurrence['endDate'] !== NULL )
+ foreach( $occurrences as $occurrence )
{
- $date = $occurrence['startDate'];
- $eDate = ( $thisEndDate->mysqlDatetime( FALSE ) < $occurrence['endDate']->mysqlDatetime( FALSE ) ) ? $thisEndDate : $occurrence['endDate'];
-
- if ( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
+ /* Is this a ranged repeating event? */
+ if ( $occurrence['endDate'] !== NULL )
{
- while( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
- {
- $formattedEvents[ $date->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
- $date = $date->adjust( '+1 day' );
- }
+ $date = $occurrence['startDate'];
+ $eDate = ( $thisEndDate->mysqlDatetime( FALSE ) < $occurrence['endDate']->mysqlDatetime( FALSE ) ) ? $thisEndDate : $occurrence['endDate'];
- $formattedEvents[ $eDate->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
+ if ( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
+ {
+ while( $date->mysqlDatetime( FALSE ) < $eDate->mysqlDatetime( FALSE ) )
+ {
+ $formattedEvents[ $date->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
+ $date = $date->adjust( '+1 day' );
+ }
+
+ $formattedEvents[ $eDate->mysqlDatetime( FALSE ) ]['ranged'][ $event->id ] = $event;
+ }
+ else
+ {
+ $formattedEvents[ $date->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
+ }
}
else
{
- $formattedEvents[ $date->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
+ $formattedEvents[ $occurrence['startDate']->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
}
}
- else
- {
- $formattedEvents[ $occurrence['startDate']->mysqlDatetime( FALSE ) ]['single'][ $event->id ] = $event;
- }
}
- }
- /* Otherwise we only want one instance of the event in our final array */
- else
- {
- $formattedEvents[] = $event;
+ /* Otherwise we only want one instance of the event in our final array */
+ else
+ {
+ $formattedEvents[] = $event;
+ }
}
}
}
diff --git a/applications/calendar/sources/Icalendar/ICSParser.php b/applications/calendar/sources/Icalendar/ICSParser.php
index bc32849d..260056ab 100644
--- a/applications/calendar/sources/Icalendar/ICSParser.php
+++ b/applications/calendar/sources/Icalendar/ICSParser.php
@@ -400,6 +400,12 @@ class ICSParser
{
break;
}
+
+ /* If recurring is blocked on this calendar, disable it */
+ if( !$calendar->calendar_bitoptions['bw_disable_recurring'] and isset( $event['recurr'] ) )
+ {
+ unset( $event['recurr'] );
+ }
/* Quickly, if we don't support the recurrence data provided let's just skip this event */
if( isset( $event['recurr'] ) )
diff --git a/applications/calendar/tasks/clearfeaturedevents.php b/applications/calendar/tasks/clearfeaturedevents.php
new file mode 100644
index 00000000..16f1043a
--- /dev/null
+++ b/applications/calendar/tasks/clearfeaturedevents.php
@@ -0,0 +1,72 @@
+Invision Power Services, Inc.
+ * @copyright (c) Invision Power Services, Inc.
+ * @license https://www.invisioncommunity.com/legal/standards/
+ * @package Invision Community
+{subpackage}
+ * @since 03 Nov 2025
+ */
+
+namespace IPS\calendar\tasks;
+
+use IPS\calendar\Event;
+use IPS\Task;
+use IPS\Task\Exception as TaskException;
+use function defined;
+
+/* To prevent PHP errors (extending class does not exist) revealing path */
+if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
+{
+ header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
+ exit;
+}
+
+/**
+ * clearfeaturedevents Task
+ */
+class clearfeaturedevents extends Task
+{
+ /**
+ * Execute
+ *
+ * If ran successfully, should return anything worth logging. Only log something
+ * worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
+ * If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
+ * Tasks should execute within the time of a normal HTTP request.
+ *
+ * @return mixed Message to log or NULL
+ * @throws TaskException
+ */
+ public function execute() : mixed
+ {
+ $log = "";
+ $featured = iterator_to_array( Event::featured( null ) );
+ foreach( $featured as $event )
+ {
+ /* @var Event $event */
+ if( $event->hasPassed() )
+ {
+ $event->setFeatured( false );
+ $log .= "Unfeatured event {$event->id}; ";
+ }
+ }
+
+ return $log ?: null;
+ }
+
+ /**
+ * Cleanup
+ *
+ * If your task takes longer than 15 minutes to run, this method
+ * will be called before execute(). Use it to clean up anything which
+ * may not have been done
+ *
+ * @return void
+ */
+ public function cleanup() : void
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/applications/cms/Application.php b/applications/cms/Application.php
index f3710fd2..96b39b54 100644
--- a/applications/cms/Application.php
+++ b/applications/cms/Application.php
@@ -331,10 +331,10 @@ class Application extends SystemApplication
'tab' => 'cms',
'module_url' => 'databases',
'controller' => 'records',
- 'do' => 'manage&database_id=' . $database['id'],
+ 'do' => "&database_id={$database['id']}",
'restriction' => 'records_manage',
'restriction_module' => 'databases',
- 'menu_checks' => array( 'do' => 'manage', 'database_id' => $database['id'] ),
+ 'menu_checks' => array( 'database_id' => $database['id'] ),
'menu_controller' => 'records_' . $database['id']
);
@@ -344,10 +344,10 @@ class Application extends SystemApplication
'tab' => 'cms',
'module_url' => 'databases',
'controller' => 'categories',
- 'do' => 'manage&database_id=' . $database['id'],
+ 'do' => "&database_id={$database['id']}",
'restriction' => 'categories_manage',
'restriction_module' => 'databases',
- 'menu_checks' => array( 'do' => 'manage', 'database_id' => $database['id'] ),
+ 'menu_checks' => array( 'database_id' => $database['id'] ),
'menu_controller' => 'categories_' . $database['id']
);
}
@@ -356,10 +356,10 @@ class Application extends SystemApplication
'tab' => 'cms',
'module_url' => 'databases',
'controller' => 'fields',
- 'do' => 'manage&database_id=' . $database['id'],
+ 'do' => "&database_id={$database['id']}",
'restriction' => 'cms_fields_manage',
'restriction_module' => 'databases',
- 'menu_checks' => array( 'do' => 'manage', 'database_id' => $database['id'] ),
+ 'menu_checks' => array( 'database_id' => $database['id'] ),
'menu_controller' => 'fields_' . $database['id']
);
diff --git a/applications/cms/data/cms_theme.xml b/applications/cms/data/cms_theme.xml
index 6feca55b..43f98b7b 100644
--- a/applications/cms/data/cms_theme.xml
+++ b/applications/cms/data/cms_theme.xml
@@ -498,7 +498,7 @@
]]>
-
+
]]>
id" title="$database->title"}]]>
- {lang="block_DatabaseFilters_title" sprintf="$category->_title"}
+ {lang="block_DatabaseFilters_title" sprintf="$category->_title"}
+{{else}}
+
+{{endif}}
{$form|raw}
diff --git a/applications/cms/data/versions.json b/applications/cms/data/versions.json
index 4631b0ac..15bde495 100644
--- a/applications/cms/data/versions.json
+++ b/applications/cms/data/versions.json
@@ -275,6 +275,19 @@
"107799": "4.7.20 Beta 5",
"107800": "4.7.20",
"107801": "4.7.20",
+ "107802": "4.7.20",
+ "107803": "4.7.20",
+ "107810": "4.7.21 Beta 1",
+ "107811": "4.7.21",
+ "107815": "4.7.22 Beta 1",
+ "107816": "4.7.22 Beta 2",
+ "107817": "4.7.22",
+ "107818": "4.7.22",
+ "107819": "4.7.22",
+ "107820": "4.7.22",
+ "107826": "4.7.23 Beta 1",
+ "107827": "4.7.23",
+ "107828": "4.7.23",
"500001": "5.0.0 Alpha 1",
"500002": "5.0.0 Alpha 2",
"5000003": "5.0.0 Alpha 3",
@@ -397,5 +410,9 @@
"5001204": "5.0.12",
"5001300": "5.0.13 Beta 1",
"5001301": "5.0.13 Beta 2",
- "5001302": "5.0.13"
+ "5001302": "5.0.13",
+ "5001400": "5.0.14 Beta 1",
+ "5001401": "5.0.14 Beta 1",
+ "5001402": "5.0.14 Beta 2",
+ "5001403": "5.0.14"
}
\ No newline at end of file
diff --git a/applications/cms/extensions/core/SearchContent/Records.php b/applications/cms/extensions/core/SearchContent/Records.php
index 932a3baf..7eb1748f 100644
--- a/applications/cms/extensions/core/SearchContent/Records.php
+++ b/applications/cms/extensions/core/SearchContent/Records.php
@@ -122,18 +122,15 @@ class Records extends SearchContentAbstract
*/
public function searchIndexPermissions(): string
{
- if( $this->object instanceof BaseRecords )
- {
- /* We don't want to index items in databases with search disabled */
- if( !$this->object::database()->search )
- {
- return '';
- }
+ $record = ( $this->object instanceof BaseComment ) ? $this->object->item() : $this->object;
- return $this->object->deleteLogPermissions();
+ /* We don't want to index items in databases with search disabled */
+ if( !$record::database()->search )
+ {
+ return '';
}
- return parent::searchIndexPermissions();
+ return $record->deleteLogPermissions();
}
/**
diff --git a/applications/cms/modules/front/database/category.php b/applications/cms/modules/front/database/category.php
index 71d3c5c6..39f10e6d 100644
--- a/applications/cms/modules/front/database/category.php
+++ b/applications/cms/modules/front/database/category.php
@@ -92,7 +92,7 @@ class category extends Controller
try
{
$category = $catClass::loadAndCheckPerms( Dispatcher::i()->categoryId );
- $category->saveFilterCookie( FALSE );
+ $category::database()->saveFilterCookie( false, $category );
Output::i()->redirect( $category->url(), 'cms_filters_cleared' );
}
@@ -143,7 +143,7 @@ class category extends Controller
/* Check cookie */
$where = array();
- $cookie = $category->getFilterCookie();
+ $cookie = $category::database()->getFilterCookie( $category );
if ( $cookie !== NULL )
{
@@ -192,7 +192,7 @@ class category extends Controller
}
}
- $where = $category->buildWhereFromCookie( $cookie );
+ $where = $category::database()->buildWhereFromCookie( $cookie, $category );
}
else
{
diff --git a/applications/cms/modules/front/database/index.php b/applications/cms/modules/front/database/index.php
index b2ec4016..ffc29d02 100644
--- a/applications/cms/modules/front/database/index.php
+++ b/applications/cms/modules/front/database/index.php
@@ -17,6 +17,7 @@ use IPS\cms\Categories;
use IPS\cms\Databases;
use IPS\cms\Databases\Controller;
use IPS\cms\Databases\Dispatcher;
+use IPS\cms\Fields;
use IPS\cms\Pages\Page;
use IPS\cms\Records;
use IPS\Content\Filter;
@@ -28,6 +29,7 @@ use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
+use IPS\Session;
use IPS\Theme;
use IPS\Xml\Rss;
use OutOfRangeException;
@@ -47,6 +49,12 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class index extends Controller
{
+ /**
+ * Store any active filters for this view
+ *
+ * @var array
+ */
+ static public array $activeFilters = array();
/**
* Determine which method to load
@@ -139,13 +147,10 @@ class index extends Controller
$where = [];
- /** @var Categories $categoryClass */
- $categoryClass = 'IPS\cms\Categories' . $database->id;
- $category = $categoryClass::load( $database->_default_category );
- $cookie = $category->getFilterCookie();
+ $cookie = $database->getFilterCookie();
if( $cookie !== null )
{
- $where = $category->buildWhereFromCookie( $cookie );
+ $where = $database->buildWhereFromCookie( $cookie );
}
elseif( isset( Request::i()->advanced_search_submitted ) and Request::i()->advanced_search_submitted )
{
@@ -163,7 +168,59 @@ class index extends Controller
}
if( count( $cookie ) )
{
- $where = $category->buildWhereFromCookie( $cookie );
+ $where = $database->buildWhereFromCookie( $cookie );
+ }
+ }
+
+ /* Build the filters */
+ /* @var Fields $fieldClass */
+ $fieldClass = 'IPS\cms\Fields' . $database->id;
+ $customFields = $fieldClass::data( 'view', null, $fieldClass::FIELD_SKIP_TITLE_CONTENT );
+ if( $cookie !== null )
+ {
+ foreach( $cookie as $f => $v )
+ {
+ if( $f == 'cms_record_i_started' and Member::loggedIn()->member_id )
+ {
+ /* FilterMessage template only accepts \IPS\cms\Fields */
+ $field = new Fields;
+ $field->id = 'cms_record_i_started';
+
+ Member::loggedIn()->language()->words['content_field_cms_record_i_started'] = Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', FALSE, array( 'sprintf' => $database->recordWord() ) );
+
+ static::$activeFilters['cms_record_i_started'] = array( 'field' => $field, 'value' => Member::loggedIn()->language()->addToStack('content_field_cms_record_i_started_on') );
+ }
+ else
+ {
+ $displayValue = $customFields[ $f ]->displayValue( $v );
+
+ if ( $customFields[ $f ]->type === 'Member' )
+ {
+ if ( ! empty( $v ) )
+ {
+ $newDisplayValue = array();
+ $concat = '\n';
+
+ if ( is_array( $v ) )
+ {
+ foreach( $v as $m )
+ {
+ $member = Member::load( $m );
+ $newDisplayValue[] = $member->name;
+ }
+ }
+ else
+ {
+ $member = Member::load( $v );
+ $newDisplayValue[] = $member->name;
+ }
+
+ $displayValue = implode( ', ', $newDisplayValue );
+ }
+ }
+
+ static::$activeFilters[ $f ] = array( 'field' => $customFields[ $f ], 'value' => $displayValue );
+ }
}
}
@@ -194,7 +251,7 @@ class index extends Controller
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'database_index/featured.css', 'cms', 'front' ) );
Output::i()->title = ( $page > 1 ) ? Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $database->pageTitle(), $page ) ) ) : $database->pageTitle();
- Dispatcher::i()->output .= Output::i()->output = \IPS\cms\Theme::i()->getTemplate( $database->template_featured, 'cms', 'database' )->index( $database, $articles, $url, $pagination );
+ Dispatcher::i()->output .= Output::i()->output = \IPS\cms\Theme::i()->getTemplate( $database->template_featured, 'cms', 'database' )->index( $database, $articles, $url, $pagination, static::$activeFilters );
}
else
{
@@ -275,4 +332,19 @@ class index extends Controller
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack( 'cms_select_category' ) );
Dispatcher::i()->output = Output::i()->output = Theme::i()->getTemplate( 'records' )->categorySelector( $form );
}
+
+ /**
+ * Clear any filters
+ *
+ * @return void
+ */
+ public function clearFilters() : void
+ {
+ Session::i()->csrfCheck();
+
+ $database = Databases::load( Dispatcher::i()->databaseId );
+ $database->saveFilterCookie( false );
+
+ Output::i()->redirect( $database->page->url(), 'cms_filters_cleared' );
+ }
}
diff --git a/applications/cms/setup/upg_107802/data.json b/applications/cms/setup/upg_107802/data.json
new file mode 100644
index 00000000..e8c7ffe8
--- /dev/null
+++ b/applications/cms/setup/upg_107802/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107802,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107803/data.json b/applications/cms/setup/upg_107803/data.json
new file mode 100644
index 00000000..c303dba8
--- /dev/null
+++ b/applications/cms/setup/upg_107803/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107803,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107810/data.json b/applications/cms/setup/upg_107810/data.json
new file mode 100644
index 00000000..bf15a04b
--- /dev/null
+++ b/applications/cms/setup/upg_107810/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107810,
+ "name": "4.7.21 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": true,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107810/settings.json b/applications/cms/setup/upg_107810/settings.json
new file mode 100644
index 00000000..3f2e5252
--- /dev/null
+++ b/applications/cms/setup/upg_107810/settings.json
@@ -0,0 +1,7 @@
+{
+ "added": [
+ "sitemap_databases_count"
+ ],
+ "edited": [],
+ "removed": []
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107811/data.json b/applications/cms/setup/upg_107811/data.json
new file mode 100644
index 00000000..21427d5d
--- /dev/null
+++ b/applications/cms/setup/upg_107811/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107811,
+ "name": "4.7.21",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107815/data.json b/applications/cms/setup/upg_107815/data.json
new file mode 100644
index 00000000..069df6ab
--- /dev/null
+++ b/applications/cms/setup/upg_107815/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107815,
+ "name": "4.7.22 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107816/data.json b/applications/cms/setup/upg_107816/data.json
new file mode 100644
index 00000000..f33f25af
--- /dev/null
+++ b/applications/cms/setup/upg_107816/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107816,
+ "name": "4.7.22 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107817/data.json b/applications/cms/setup/upg_107817/data.json
new file mode 100644
index 00000000..29b49df9
--- /dev/null
+++ b/applications/cms/setup/upg_107817/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107817,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107818/data.json b/applications/cms/setup/upg_107818/data.json
new file mode 100644
index 00000000..26c77bc5
--- /dev/null
+++ b/applications/cms/setup/upg_107818/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107818,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107819/data.json b/applications/cms/setup/upg_107819/data.json
new file mode 100644
index 00000000..968a94ca
--- /dev/null
+++ b/applications/cms/setup/upg_107819/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107819,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107820/data.json b/applications/cms/setup/upg_107820/data.json
new file mode 100644
index 00000000..5082a5f4
--- /dev/null
+++ b/applications/cms/setup/upg_107820/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107820,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107826/data.json b/applications/cms/setup/upg_107826/data.json
new file mode 100644
index 00000000..67c4b57c
--- /dev/null
+++ b/applications/cms/setup/upg_107826/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107826,
+ "name": "4.7.23 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107827/data.json b/applications/cms/setup/upg_107827/data.json
new file mode 100644
index 00000000..d8181b24
--- /dev/null
+++ b/applications/cms/setup/upg_107827/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107827,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_107828/data.json b/applications/cms/setup/upg_107828/data.json
new file mode 100644
index 00000000..41933acb
--- /dev/null
+++ b/applications/cms/setup/upg_107828/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107828,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_5001400/data.json b/applications/cms/setup/upg_5001400/data.json
new file mode 100644
index 00000000..67d5df85
--- /dev/null
+++ b/applications/cms/setup/upg_5001400/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001400,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": true,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_5001400/theme.json b/applications/cms/setup/upg_5001400/theme.json
new file mode 100644
index 00000000..81a586e9
--- /dev/null
+++ b/applications/cms/setup/upg_5001400/theme.json
@@ -0,0 +1,19 @@
+{
+ "html": {
+ "added": [],
+ "edited": [
+ "front\/widgets\/DatabaseFilters"
+ ],
+ "removed": []
+ },
+ "css": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ },
+ "resources": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ }
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_5001401/data.json b/applications/cms/setup/upg_5001401/data.json
new file mode 100644
index 00000000..6954be4a
--- /dev/null
+++ b/applications/cms/setup/upg_5001401/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001401,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_5001402/data.json b/applications/cms/setup/upg_5001402/data.json
new file mode 100644
index 00000000..daadfa3b
--- /dev/null
+++ b/applications/cms/setup/upg_5001402/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001402,
+ "name": "5.0.14 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/setup/upg_5001403/data.json b/applications/cms/setup/upg_5001403/data.json
new file mode 100644
index 00000000..21b48da4
--- /dev/null
+++ b/applications/cms/setup/upg_5001403/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001403,
+ "name": "5.0.14",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/cms/sources/Categories/Categories.php b/applications/cms/sources/Categories/Categories.php
index 9d95a6c7..6a6fa49c 100644
--- a/applications/cms/sources/Categories/Categories.php
+++ b/applications/cms/sources/Categories/Categories.php
@@ -2077,175 +2077,6 @@ class Categories extends Model implements Permissions
Index::i()->massUpdate( 'IPS\cms\Records\Comment' . static::database()->_id, $this->_id, NULL, $permissions, NULL, NULL, NULL, NULL, NULL, TRUE );
}
}
-
- /**
- * Get the filter cookie for this category
- *
- * @return array|null
- */
- public function getFilterCookie(): ?array
- {
- if ( isset( Request::i()->cookie['cms_filters'] ) )
- {
- $saved = json_decode( Request::i()->cookie['cms_filters'], TRUE );
-
- if ( array_key_exists( $this->id, $saved ) and count( $saved[ $this->id ] ) )
- {
- return $saved[ $this->id ];
- }
- }
-
- return NULL;
- }
-
- /**
- * Save filter cookie for this category
- *
- * @param array|bool $values Filter values to save (array) or FALSE to remove cookie
- * @return void
- */
- public function saveFilterCookie( array|bool $values ): void
- {
- $cookie = ( isset( Request::i()->cookie['cms_filters'] ) ) ? json_decode( Request::i()->cookie['cms_filters'], TRUE ) : array();
-
- if ( $values === FALSE )
- {
- if ( array_key_exists( $this->id, $cookie ) )
- {
- unset( $cookie[ $this->id ] );
- }
- }
- else
- {
- /* We only want to include ones where we have actually specified values to filter on */
- $toSave = array();
- foreach( $values AS $key => $data )
- {
- if ( is_numeric( $key ) or $key == 'cms_record_i_started' )
- {
- $toSave[$key] = $data;
- }
- }
-
- $cookie[ $this->id ] = $toSave;
- }
-
- Request::i()->setCookie( 'cms_filters', json_encode( $cookie ), DateTime::create()->add( new DateInterval( 'P7D' ) ) );
- }
-
- /**
- * Use the cookie to build filters
- *
- * @param array $cookie
- * @return array
- */
- public function buildWhereFromCookie( array $cookie ) : array
- {
- $where = [];
- $database = static::database();
-
- /** @var Fields $fieldClass */
- $fieldClass = 'IPS\cms\Fields' . $database->id;
- $customFields = $fieldClass::data( 'view', $this, $fieldClass::FIELD_SKIP_TITLE_CONTENT );
-
- foreach( $cookie as $f => $v )
- {
- if ( $f == 'cms_record_i_started' and Member::loggedIn()->member_id )
- {
- $where[] = array( 'cms_custom_database_' . $database->id . '.member_id=' . Member::loggedIn()->member_id );
- continue;
- }
-
- $k = 'content_field_' . $f;
-
- if ( $customFields[ $f ]->type === 'Member' )
- {
- if ( ! empty( $v ) )
- {
- if ( is_array( $v ) )
- {
- foreach( $v as $m )
- {
- $member = Member::load( $m );
- $where[] = [ "FIND_IN_SET( " . $member->member_id . ", REPLACE(field_" . $f . ", '\n',','))" ];
- }
- }
- else
- {
- $member = Member::load( $v );
- $where[] = [ "FIND_IN_SET( " . $member->member_id . ", REPLACE(field_" . $f . ", '\n',','))" ];
- }
- }
-
- continue;
- }
-
- if ( isset( $customFields[ $f ] ) and $v !== '___any___' )
- {
- if ( is_array( $v ) )
- {
- if ( array_key_exists( 'start', $v ) or array_key_exists( 'end', $v ) )
- {
- $start = ( $v['start'] instanceof DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
- $end = ( $v['end'] instanceof DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
-
- if ( $start or $end )
- {
- $where[] = array( '( ' . mb_substr( $k, 8 ) . ' BETWEEN ' . $start . ' AND ' . $end . ' )' );
- }
- }
- else
- {
- $like = array();
- foreach( $v as $val )
- {
- if ( $val === 0 or ! empty( $val ) )
- {
- $like[] = $val;
- }
- }
-
- if( $customFields[ $f ]->default_value and in_array( $customFields[ $f ]->default_value, $v ) )
- {
- $where[] = array( "( " . mb_substr( $k, 8 ) . " IS NULL OR " . Db::i()->findInSet( mb_substr( $k, 8 ), $like ) . ")" );
- }
- else
- {
- $where[] = array( Db::i()->findInSet( mb_substr( $k, 8 ), $like ) );
- }
- }
- }
- else
- {
- if ( is_bool( $v ) )
- {
- /* YesNo fields are false or true */
- if ( $v === false )
- {
- $where[] = array( '(' . mb_substr( $k, 8 ) . ' IS NULL or ' . mb_substr( $k, 8 ) . '=0)' );
- }
- else
- {
- $where[] = array( mb_substr( $k, 8 ) . "=1" );
- }
- }
- else
- {
- if ( $v !== 0 and ! $v )
- {
- $where[] = array( mb_substr( $k, 8 ) . " IS NULL" );
- }
- else
- {
- $where[] = array( mb_substr( $k, 8 ) . "=?", $v );
- }
- }
- }
- }
- }
-
- return $where;
- }
/**
* [Node] Get meta description
diff --git a/applications/cms/sources/Databases/Databases.php b/applications/cms/sources/Databases/Databases.php
index dd9f15da..beea473e 100644
--- a/applications/cms/sources/Databases/Databases.php
+++ b/applications/cms/sources/Databases/Databases.php
@@ -13,12 +13,14 @@ namespace IPS\cms;
/* To prevent PHP errors (extending class does not exist) revealing path */
+use DateInterval;
use Exception;
use IPS\Application;
use IPS\cms\Pages\Page;
use IPS\Content\Search\Index;
use IPS\Content\ViewUpdates;
use IPS\Data\Store;
+use IPS\DateTime;
use IPS\Db;
use IPS\Dispatcher;
use IPS\File;
@@ -32,6 +34,7 @@ use IPS\Node\Permissions;
use IPS\Patterns\ActiveRecord;
use IPS\Patterns\ActiveRecordIterator;
use IPS\Platform\Bridge;
+use IPS\Request;
use IPS\Settings;
use IPS\Task;
use IPS\Widget\Area;
@@ -1490,6 +1493,179 @@ class Databases extends Model implements Permissions
}
}
+ /**
+ * Get the filter cookie for this category/database
+ *
+ * @param Categories|null $category
+ * @return array|null
+ */
+ public function getFilterCookie( ?Categories $category=null ): ?array
+ {
+ $key = $category ? $category->id : 'd' . $this->id;
+ if ( isset( Request::i()->cookie['cms_filters'] ) )
+ {
+ $saved = json_decode( Request::i()->cookie['cms_filters'], TRUE );
+
+ if ( array_key_exists( $key, $saved ) and count( $saved[ $key ] ) )
+ {
+ return $saved[ $key ];
+ }
+ }
+
+ return NULL;
+ }
+
+ /**
+ * Save filter cookie for this category
+ *
+ * @param array|bool $values Filter values to save (array) or FALSE to remove cookie
+ * @param Categories|null $category
+ * @return void
+ */
+ public function saveFilterCookie( array|bool $values, ?Categories $category=null ): void
+ {
+ $key = $category ? $category->id : 'd' . $this->id;
+ $cookie = ( isset( Request::i()->cookie['cms_filters'] ) ) ? json_decode( Request::i()->cookie['cms_filters'], TRUE ) : array();
+
+ if ( $values === FALSE )
+ {
+ if ( array_key_exists( $key, $cookie ) )
+ {
+ unset( $cookie[ $key ] );
+ }
+ }
+ else
+ {
+ /* We only want to include ones where we have actually specified values to filter on */
+ $toSave = array();
+ foreach( $values AS $k => $v )
+ {
+ if ( is_numeric( $k ) or $k == 'cms_record_i_started' )
+ {
+ $toSave[ $k ] = $v;
+ }
+ }
+
+ $cookie[ $key ] = $toSave;
+ }
+
+ Request::i()->setCookie( 'cms_filters', json_encode( $cookie ), DateTime::create()->add( new DateInterval( 'P7D' ) ) );
+ }
+
+ /**
+ * Use the cookie to build filters
+ *
+ * @param array $cookie
+ * @param Categories|null $category
+ * @return array
+ */
+ public function buildWhereFromCookie( array $cookie, ?Categories $category=null ) : array
+ {
+ $where = [];
+
+ /** @var Fields $fieldClass */
+ $fieldClass = 'IPS\cms\Fields' . $this->id;
+ $customFields = $fieldClass::data( 'view', $category, $fieldClass::FIELD_SKIP_TITLE_CONTENT );
+
+ foreach( $cookie as $f => $v )
+ {
+ if ( $f == 'cms_record_i_started' and Member::loggedIn()->member_id )
+ {
+ $where[] = array( 'cms_custom_database_' . $this->id . '.member_id=' . Member::loggedIn()->member_id );
+ continue;
+ }
+
+ $k = 'content_field_' . $f;
+
+ if ( $customFields[ $f ]->type === 'Member' )
+ {
+ if ( ! empty( $v ) )
+ {
+ if ( is_array( $v ) )
+ {
+ foreach( $v as $m )
+ {
+ $member = Member::load( $m );
+ $where[] = [ "FIND_IN_SET( " . $member->member_id . ", REPLACE(field_" . $f . ", '\n',','))" ];
+ }
+ }
+ else
+ {
+ $member = Member::load( $v );
+ $where[] = [ "FIND_IN_SET( " . $member->member_id . ", REPLACE(field_" . $f . ", '\n',','))" ];
+ }
+ }
+
+ continue;
+ }
+
+ if ( isset( $customFields[ $f ] ) and $v !== '___any___' )
+ {
+ if ( is_array( $v ) )
+ {
+ if ( array_key_exists( 'start', $v ) or array_key_exists( 'end', $v ) )
+ {
+ $start = ( $v['start'] instanceof DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
+ $end = ( $v['end'] instanceof DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
+
+ if ( $start or $end )
+ {
+ $where[] = array( '( ' . mb_substr( $k, 8 ) . ' BETWEEN ' . $start . ' AND ' . $end . ' )' );
+ }
+ }
+ else
+ {
+ $like = array();
+ foreach( $v as $val )
+ {
+ if ( $val === 0 or ! empty( $val ) )
+ {
+ $like[] = $val;
+ }
+ }
+
+ if( $customFields[ $f ]->default_value and in_array( $customFields[ $f ]->default_value, $v ) )
+ {
+ $where[] = array( "( " . mb_substr( $k, 8 ) . " IS NULL OR " . Db::i()->findInSet( mb_substr( $k, 8 ), $like ) . ")" );
+ }
+ else
+ {
+ $where[] = array( Db::i()->findInSet( mb_substr( $k, 8 ), $like ) );
+ }
+ }
+ }
+ else
+ {
+ if ( is_bool( $v ) )
+ {
+ /* YesNo fields are false or true */
+ if ( $v === false )
+ {
+ $where[] = array( '(' . mb_substr( $k, 8 ) . ' IS NULL or ' . mb_substr( $k, 8 ) . '=0)' );
+ }
+ else
+ {
+ $where[] = array( mb_substr( $k, 8 ) . "=1" );
+ }
+ }
+ else
+ {
+ if ( $v !== 0 and ! $v )
+ {
+ $where[] = array( mb_substr( $k, 8 ) . " IS NULL" );
+ }
+ else
+ {
+ $where[] = array( mb_substr( $k, 8 ) . "=?", $v );
+ }
+ }
+ }
+ }
+ }
+
+ return $where;
+ }
+
/**
* Get output for API
*
diff --git a/applications/cms/sources/Fields/Fields.php b/applications/cms/sources/Fields/Fields.php
index a81b41e3..9ace5872 100644
--- a/applications/cms/sources/Fields/Fields.php
+++ b/applications/cms/sources/Fields/Fields.php
@@ -1241,7 +1241,7 @@ class Fields extends CustomField implements Permissions
*/
public function get_display_json(): array
{
- return ( is_array( $this->_data['display_json'] ) ) ? $this->_data['display_json'] : json_decode( $this->_data['display_json'], TRUE );
+ return ( is_array( $this->_data['display_json'] ) ) ? $this->_data['display_json'] : ( isset( $this->_data['display_json'] ) ? json_decode( $this->_data['display_json'], TRUE ) : [] );
}
/**
diff --git a/applications/cms/sources/Pages/Page.php b/applications/cms/sources/Pages/Page.php
index d8c6f8c8..c1edf596 100644
--- a/applications/cms/sources/Pages/Page.php
+++ b/applications/cms/sources/Pages/Page.php
@@ -1268,6 +1268,13 @@ class Page extends Model implements Permissions
try
{
$template = Templates::load( $key );
+
+ /* If this is an empty file, don't bother loading it */
+ if( empty( $template->content ) )
+ {
+ continue;
+ }
+
$object = $template->_file_object;
$return['js'][ $key ] = $object;
@@ -1287,6 +1294,13 @@ class Page extends Model implements Permissions
try
{
$template = Templates::load( $key );
+
+ /* Skip if empty */
+ if( empty( $template->content ) )
+ {
+ continue;
+ }
+
$object = $template->_file_object;
$return['css'][ $key ] = $object;
diff --git a/applications/cms/sources/Records/Records.php b/applications/cms/sources/Records/Records.php
index c07d8866..449168bd 100644
--- a/applications/cms/sources/Records/Records.php
+++ b/applications/cms/sources/Records/Records.php
@@ -3771,7 +3771,11 @@ class Records extends Item implements
{
$title = '';
- if( $prefix = static::database()->forum_prefix )
+ if ( $prefix = $this->container()->forum_prefix )
+ {
+ $title .= $prefix . ' ';
+ }
+ else if( $prefix = static::database()->forum_prefix )
{
$title .= $prefix . ' ';
}
@@ -3779,7 +3783,11 @@ class Records extends Item implements
$column = 'field_' . static::database()->field_title;
$title .= $this->$column;
- if( $suffix = static::database()->forum_suffix )
+ if ( $suffix = $this->container()->forum_suffix )
+ {
+ $title .= ' ' . $suffix;
+ }
+ else if( $suffix = static::database()->forum_suffix )
{
$title .= ' ' . $suffix;
}
diff --git a/applications/cms/widgets/Codemirror.php b/applications/cms/widgets/Codemirror.php
index c6bcb910..6d147734 100644
--- a/applications/cms/widgets/Codemirror.php
+++ b/applications/cms/widgets/Codemirror.php
@@ -71,6 +71,11 @@ class Codemirror extends Widget
{
$form = parent::configuration( $form );
+ if( !Dispatcher::i()->checkAcpPermission( 'theme_sets_manage', 'core', Module::get( 'core', 'customization', 'admin' ), true ) )
+ {
+ return $form;
+ }
+
$form->add(
new Form\TextArea(
'content',
@@ -111,6 +116,11 @@ class Codemirror extends Widget
*/
public function preConfig( array $values=array() ) : array
{
+ if( !array_key_exists( 'content', $values ) )
+ {
+ $values['content'] = $this->configuration['content'];
+ }
+
$functionName = 'content_widget_' . $this->uniqueKey;
if ( isset( Store::i()->$functionName ) )
{
diff --git a/applications/cms/widgets/DatabaseFilters.php b/applications/cms/widgets/DatabaseFilters.php
index 98ab7056..e7410f8f 100644
--- a/applications/cms/widgets/DatabaseFilters.php
+++ b/applications/cms/widgets/DatabaseFilters.php
@@ -13,6 +13,7 @@ namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
+use DateInterval;
use Exception;
use IPS\cms\Categories;
use IPS\cms\Databases;
@@ -85,7 +86,7 @@ class DatabaseFilters extends Widget
return '';
}
- if ( ! Dispatcher::i()->databaseId AND ! Dispatcher::i()->categoryId )
+ if ( ! Dispatcher::i()->databaseId )
{
return '';
}
@@ -99,24 +100,36 @@ class DatabaseFilters extends Widget
{
return '';
}
-
- try
+
+ $category = null;
+ if( isset( Dispatcher::i()->categoryId ) )
{
- /* @var Categories $categoryClass */
- $categoryClass = "IPS\cms\Categories" . Dispatcher::i()->databaseId;
- $category = $categoryClass::load( Dispatcher::i()->categoryId );
+ try
+ {
+ /* @var Categories $categoryClass */
+ $categoryClass = "IPS\cms\Categories" . Dispatcher::i()->databaseId;
+ $category = $categoryClass::load( Dispatcher::i()->categoryId );
+ }
+ catch ( OutOfRangeException $e )
+ {
+ return '';
+ }
}
- catch ( OutOfRangeException $e )
+ else
{
- return '';
+ /* Is this the category view? */
+ if( $database->display_settings['index']['type'] == 'categories' or isset( Request::i()->show ) )
+ {
+ return '';
+ }
}
/* @var Fields $fieldClass */
$fieldClass = 'IPS\cms\Fields' . $database->id;
$fields = array();
- $cookie = $category->getFilterCookie();
- $cookieValues = ( $cookie !== NULL ) ? array_combine( array_map( function( $k ) { return "field_" . $k; }, array_keys( $cookie ) ), $cookie ) : array();
+ $cookie = $database->getFilterCookie( $category );
+ $cookieValues = ( !empty( $cookie ) ) ? array_combine( array_map( function( $k ) { return "field_" . $k; }, array_keys( $cookie ) ), $cookie ) : array();
$databaseFields = $fieldClass::roots();
$urlValues = array();
@@ -186,7 +199,8 @@ class DatabaseFilters extends Widget
if ( count( $fields ) )
{
- $form = new Form( 'category_filters', 'update', $category->url() );
+ $baseUrl = $category ? $category->url() : $database->page->url();
+ $form = new Form( 'category_filters', 'update', $baseUrl );
$form->class = 'ipsForm--vertical ipsForm--database-widget-filters';
if ( Request::i()->sortby )
{
@@ -233,7 +247,7 @@ class DatabaseFilters extends Widget
if ( $values = $form->values() )
{
- $url = $category->url()->setQueryString( array( 'advanced_search_submitted' => 1 ) );
+ $url = $baseUrl->setQueryString( array( 'advanced_search_submitted' => 1 ) );
$cookie = array();
$params = array();
foreach( $values as $k => $v )
@@ -308,13 +322,13 @@ class DatabaseFilters extends Widget
if ( $values['cms_widget_filters_remember'] )
{
- $category->saveFilterCookie( $cookie );
- Output::i()->redirect( $category->url() );
+ $database->saveFilterCookie( $cookie, $category );
+ Output::i()->redirect( $baseUrl );
}
else
{
/* Remove the filter cookie */
- $category->saveFilterCookie( FALSE );
+ $database->saveFilterCookie( false, $category );
Output::i()->redirect( $url->setQueryString( $params ) );
}
}
diff --git a/applications/convert/data/javascript.xml b/applications/convert/data/javascript.xml
index 361cb1cf..de10a4a9 100644
--- a/applications/convert/data/javascript.xml
+++ b/applications/convert/data/javascript.xml
@@ -1,6 +1,6 @@
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -45,7 +45,7 @@
}
} );
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
diff --git a/applications/convert/data/lang.xml b/applications/convert/data/lang.xml
index 3d423bf1..10df55e1 100644
--- a/applications/convert/data/lang.xml
+++ b/applications/convert/data/lang.xml
@@ -1,6 +1,6 @@
-
+
Converter
Conversions
Start New Conversion
diff --git a/applications/convert/data/versions.json b/applications/convert/data/versions.json
index 4631b0ac..15bde495 100644
--- a/applications/convert/data/versions.json
+++ b/applications/convert/data/versions.json
@@ -275,6 +275,19 @@
"107799": "4.7.20 Beta 5",
"107800": "4.7.20",
"107801": "4.7.20",
+ "107802": "4.7.20",
+ "107803": "4.7.20",
+ "107810": "4.7.21 Beta 1",
+ "107811": "4.7.21",
+ "107815": "4.7.22 Beta 1",
+ "107816": "4.7.22 Beta 2",
+ "107817": "4.7.22",
+ "107818": "4.7.22",
+ "107819": "4.7.22",
+ "107820": "4.7.22",
+ "107826": "4.7.23 Beta 1",
+ "107827": "4.7.23",
+ "107828": "4.7.23",
"500001": "5.0.0 Alpha 1",
"500002": "5.0.0 Alpha 2",
"5000003": "5.0.0 Alpha 3",
@@ -397,5 +410,9 @@
"5001204": "5.0.12",
"5001300": "5.0.13 Beta 1",
"5001301": "5.0.13 Beta 2",
- "5001302": "5.0.13"
+ "5001302": "5.0.13",
+ "5001400": "5.0.14 Beta 1",
+ "5001401": "5.0.14 Beta 1",
+ "5001402": "5.0.14 Beta 2",
+ "5001403": "5.0.14"
}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107802/data.json b/applications/convert/setup/upg_107802/data.json
new file mode 100644
index 00000000..e8c7ffe8
--- /dev/null
+++ b/applications/convert/setup/upg_107802/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107802,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107803/data.json b/applications/convert/setup/upg_107803/data.json
new file mode 100644
index 00000000..cc47049e
--- /dev/null
+++ b/applications/convert/setup/upg_107803/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107803,
+ "name": "4.7.20",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": true,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107803/theme.json b/applications/convert/setup/upg_107803/theme.json
new file mode 100644
index 00000000..e7acb013
--- /dev/null
+++ b/applications/convert/setup/upg_107803/theme.json
@@ -0,0 +1,19 @@
+{
+ "html": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ },
+ "css": {
+ "added": [],
+ "edited": [
+ "admin\/convert.css"
+ ],
+ "removed": []
+ },
+ "resources": {
+ "added": [],
+ "edited": [],
+ "removed": []
+ }
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107810/data.json b/applications/convert/setup/upg_107810/data.json
new file mode 100644
index 00000000..d6859da8
--- /dev/null
+++ b/applications/convert/setup/upg_107810/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107810,
+ "name": "4.7.21 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107811/data.json b/applications/convert/setup/upg_107811/data.json
new file mode 100644
index 00000000..21427d5d
--- /dev/null
+++ b/applications/convert/setup/upg_107811/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107811,
+ "name": "4.7.21",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107815/data.json b/applications/convert/setup/upg_107815/data.json
new file mode 100644
index 00000000..069df6ab
--- /dev/null
+++ b/applications/convert/setup/upg_107815/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107815,
+ "name": "4.7.22 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107816/data.json b/applications/convert/setup/upg_107816/data.json
new file mode 100644
index 00000000..f33f25af
--- /dev/null
+++ b/applications/convert/setup/upg_107816/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107816,
+ "name": "4.7.22 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107817/data.json b/applications/convert/setup/upg_107817/data.json
new file mode 100644
index 00000000..29b49df9
--- /dev/null
+++ b/applications/convert/setup/upg_107817/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107817,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107818/data.json b/applications/convert/setup/upg_107818/data.json
new file mode 100644
index 00000000..26c77bc5
--- /dev/null
+++ b/applications/convert/setup/upg_107818/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107818,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107819/data.json b/applications/convert/setup/upg_107819/data.json
new file mode 100644
index 00000000..968a94ca
--- /dev/null
+++ b/applications/convert/setup/upg_107819/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107819,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107820/data.json b/applications/convert/setup/upg_107820/data.json
new file mode 100644
index 00000000..5082a5f4
--- /dev/null
+++ b/applications/convert/setup/upg_107820/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107820,
+ "name": "4.7.22",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107826/data.json b/applications/convert/setup/upg_107826/data.json
new file mode 100644
index 00000000..67c4b57c
--- /dev/null
+++ b/applications/convert/setup/upg_107826/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107826,
+ "name": "4.7.23 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107827/data.json b/applications/convert/setup/upg_107827/data.json
new file mode 100644
index 00000000..d8181b24
--- /dev/null
+++ b/applications/convert/setup/upg_107827/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107827,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_107828/data.json b/applications/convert/setup/upg_107828/data.json
new file mode 100644
index 00000000..41933acb
--- /dev/null
+++ b/applications/convert/setup/upg_107828/data.json
@@ -0,0 +1,23 @@
+{
+ "id": 107828,
+ "name": "4.7.23",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeSettings": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "hooks": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_5001400/data.json b/applications/convert/setup/upg_5001400/data.json
new file mode 100644
index 00000000..1571e915
--- /dev/null
+++ b/applications/convert/setup/upg_5001400/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001400,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_5001401/data.json b/applications/convert/setup/upg_5001401/data.json
new file mode 100644
index 00000000..6954be4a
--- /dev/null
+++ b/applications/convert/setup/upg_5001401/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001401,
+ "name": "5.0.14 Beta 1",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_5001402/data.json b/applications/convert/setup/upg_5001402/data.json
new file mode 100644
index 00000000..daadfa3b
--- /dev/null
+++ b/applications/convert/setup/upg_5001402/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001402,
+ "name": "5.0.14 Beta 2",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/convert/setup/upg_5001403/data.json b/applications/convert/setup/upg_5001403/data.json
new file mode 100644
index 00000000..21b48da4
--- /dev/null
+++ b/applications/convert/setup/upg_5001403/data.json
@@ -0,0 +1,22 @@
+{
+ "id": 5001403,
+ "name": "5.0.14",
+ "steps": {
+ "queries": false,
+ "lang": false,
+ "theme": false,
+ "themeeditor": false,
+ "javascript": false,
+ "emailTemplates": false,
+ "acpSearchKeywords": false,
+ "settings": false,
+ "tasks": false,
+ "modules": false,
+ "widgets": false,
+ "customOptions": false,
+ "customRoutines": false
+ },
+ "forceMainUpgrader": false,
+ "forceManualDownloadNoCiC": false,
+ "forceManualDownloadCiC": false
+}
\ No newline at end of file
diff --git a/applications/core/Application.php b/applications/core/Application.php
index 8069b6b0..8207376e 100644
--- a/applications/core/Application.php
+++ b/applications/core/Application.php
@@ -668,7 +668,7 @@ class Application extends SystemApplication
'member_delete' => Member::class,
'member_warned' => Warning::class,
'member_merged' => [ 'kept' => Member::class, 'removed' => Member::class],
- 'content_promoted' => Content::class,
+ 'content_promoted' => Feature::class,
'content_reported' => Content::class,
'content_followed' => Follow::class,
'content_unfollowed' => Follow::class,
diff --git a/applications/core/api/search.php b/applications/core/api/search.php
index c24b3718..19c3523b 100644
--- a/applications/core/api/search.php
+++ b/applications/core/api/search.php
@@ -189,7 +189,7 @@ class search extends Controller
break;
default:
- $$l = DateTime::ts( Request::i()->$$key );
+ $$l = DateTime::ts( (int)Request::i()->$$key );
break;
}
}
diff --git a/applications/core/data/acpsearch.json b/applications/core/data/acpsearch.json
index 7e480297..2239d34d 100644
--- a/applications/core/data/acpsearch.json
+++ b/applications/core/data/acpsearch.json
@@ -201,12 +201,15 @@
"bulk mail",
"easypost",
"email",
+ "embed",
"enhancements",
"enom",
"geo",
"giphy",
+ "iframely",
"indexnow",
"integration",
+ "mailchimp",
"mapbox",
"maps",
"matomo",
@@ -214,12 +217,11 @@
"omniture",
"piwik",
"pixabay",
+ "postmark",
"sendgrid",
"spam",
"tag manager",
- "zapier",
- "postmark",
- "mailchimp"
+ "zapier"
]
},
"app=core&module=applications&controller=enhancements&do=edit&id=core_FacebookPixel": {
@@ -246,6 +248,24 @@
"maps"
]
},
+ "app=core&module=applications&controller=enhancements&do=edit&id=core_Iframely": {
+ "lang_key": "menu__core_applications_enhancements",
+ "restriction": "enhancements_manage",
+ "keywords": [
+ "embeds",
+ "facebook",
+ "iframe",
+ "iframe.ly",
+ "meta"
+ ]
+ },
+ "app=core&module=applications&controller=enhancements&do=edit&id=core_Mailchimp": {
+ "lang_key": "enhancements__core_Mailchimp",
+ "restriction": "enhancements_manage",
+ "keywords": [
+ "mailchimp"
+ ]
+ },
"app=core&module=applications&controller=enhancements&do=edit&id=core_Pixabay": {
"lang_key": "enhancements__core_Pixabay",
"restriction": "enhancements_manage",
@@ -469,6 +489,14 @@
"exclude groups from search"
]
},
+ "app=core&module=discovery&controller=streams": {
+ "lang_key": "menu__core_discovery_streams",
+ "restriction": "streams_manage",
+ "keywords": [
+ "activity stream",
+ "streams"
+ ]
+ },
"app=core&module=discovery&controller=streams&do=allActivitySettings": {
"lang_key": "all_activity_stream_settings",
"restriction": "streams_manage",
@@ -1496,9 +1524,9 @@
"lang_key": "menu__core_moderation_report",
"restriction": "reportedContentTypes_manage",
"keywords": [
+ "automatic moderation",
"moderation",
- "report",
- "automatic moderation"
+ "report"
]
},
"app=core&module=moderation&controller=reportedContent": {
@@ -1704,12 +1732,12 @@
"lang_key": "menu__core_keystats_communityhealth",
"restriction": "mycharts_manage",
"keywords": [
+ "chart",
"community health",
"health",
- "chart",
"report",
- "stats",
- "statistics"
+ "statistics",
+ "stats"
]
},
"app=core&module=overview&controller=notifications&do=settings": {
@@ -2233,10 +2261,10 @@
"lang_key": "reg_welcome_email",
"restriction": "login_access",
"keywords": [
- "welcome",
- "welcome email",
"email",
- "register"
+ "register",
+ "welcome",
+ "welcome email"
]
},
"app=core&module=settings&controller=login&tab=registration&searchResult=use_coppa": {
@@ -3039,12 +3067,5 @@
"sql logs",
"system logs"
]
- },
- "app=core&module=applications&controller=enhancements&do=edit&id=core_Mailchimp": {
- "lang_key": "enhancements__core_Mailchimp",
- "restriction": "enhancements_manage",
- "keywords": [
- "mailchimp"
- ]
}
}
\ No newline at end of file
diff --git a/applications/core/data/build.xml b/applications/core/data/build.xml
index 253ef070..5636a2d0 100644
--- a/applications/core/data/build.xml
+++ b/applications/core/data/build.xml
@@ -240,6 +240,11 @@
+
+
+
+
+
@@ -541,10 +546,12 @@
-
+
+
+
@@ -570,8 +577,8 @@
-
+
@@ -683,7 +690,7 @@
-
+
@@ -706,7 +713,7 @@
-
+
@@ -761,7 +768,7 @@
-
+
@@ -849,7 +856,6 @@
-
diff --git a/applications/core/data/editorManifest.json b/applications/core/data/editorManifest.json
index 41310f9f..f4ff5cc9 100644
--- a/applications/core/data/editorManifest.json
+++ b/applications/core/data/editorManifest.json
@@ -75,7 +75,7 @@
"isDynamicEntry": true
},
"src/main.jsx": {
- "file": "assets/main-6RAkeGwz.js",
+ "file": "assets/main-Hp4FYAlM.js",
"name": "main",
"src": "src/main.jsx",
"isEntry": true,
diff --git a/applications/core/data/extensions.json b/applications/core/data/extensions.json
index a31b2152..455bf13c 100644
--- a/applications/core/data/extensions.json
+++ b/applications/core/data/extensions.json
@@ -42,6 +42,7 @@
"GoogleAnalytics": "IPS\\core\\extensions\\core\\CommunityEnhancements\\GoogleAnalytics",
"GoogleMaps": "IPS\\core\\extensions\\core\\CommunityEnhancements\\GoogleMaps",
"GoogleTagManager": "IPS\\core\\extensions\\core\\CommunityEnhancements\\GoogleTagManager",
+ "Iframely": "IPS\\core\\extensions\\core\\CommunityEnhancements\\Iframely",
"IndexNow": "IPS\\core\\extensions\\core\\CommunityEnhancements\\IndexNow",
"Mailchimp": "IPS\\core\\extensions\\core\\CommunityEnhancements\\Mailchimp",
"Mapbox": "IPS\\core\\extensions\\core\\CommunityEnhancements\\Mapbox",
diff --git a/applications/core/data/furl.json b/applications/core/data/furl.json
index b1205dbd..8126fdc7 100644
--- a/applications/core/data/furl.json
+++ b/applications/core/data/furl.json
@@ -264,7 +264,7 @@
"real": "app=core&module=modcp&controller=modcp&tab=hidden"
},
"modcp_approval": {
- "friendly": "modcp\/approval-queue",
+ "friendly": "modcp\/approval",
"real": "app=core&module=modcp&controller=modcp&tab=approval"
},
"modcp_recent_warnings": {
diff --git a/applications/core/data/javascript.xml b/applications/core/data/javascript.xml
index ea4b7390..cf7ff347 100644
--- a/applications/core/data/javascript.xml
+++ b/applications/core/data/javascript.xml
@@ -1,6 +1,6 @@
- {});
}
}]]>
-
- {
const raw = String.raw({raw:str}, ...values)
return ips.getString(raw) || raw
}]]>
- {
}( jQuery, _ ));
]]>
- {
}
});
}( jQuery, _ )); ]]>
- {
});
}( jQuery, _ ));]]>
-
-
-
- this._preview.fill(this._source.textContent));
}
}]]>
-
-
-
-
-
*/
class IThemeEditor extends HTMLElement {
@@ -4948,7 +4948,7 @@ class IThemeEditor extends HTMLElement {
}
}]]>
- {
+ {
"use strict";
/**
@@ -5134,7 +5134,7 @@ class IThemeEditor extends HTMLElement {
}
}
})(jQuery, _));]]>
-
- /* global ips, _, Debug */
+ /* global ips, _, Debug */
/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
@@ -5709,7 +5709,7 @@ class IThemeEditor extends HTMLElement {
};
}(jQuery, _));
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -8612,7 +8612,7 @@ window.turnstileCallback = function () {
};
});
}(jQuery, _));
-
- {
+ {
"use strict";
ips.createModule('ips.ui._codehighlighting', function() {
@@ -8880,7 +8880,7 @@ window.turnstileCallback = function () {
}
})
})(jQuery, _))]]>
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -10303,7 +10303,7 @@ window.turnstileCallback = function () {
};
});
}(jQuery, _));
-
-
-
-
') {
return "";
}
- return html;
+
+ // now let's strip out the box contents wrappers. We wrap the raw HTML in an actual HTML5 document juuust in case
+ const parserDoc = (new DOMParser()).parseFromString(` ${html}`, 'text/html');
+ let boxContentElement;
+ while ((boxContentElement = parserDoc.querySelector('i-richtext-box-content')) && boxContentElement instanceof Element) {
+ boxContentElement.before(...boxContentElement.childNodes);
+ boxContentElement.remove();
+ }
+
+ return parserDoc.body.innerHTML.trim();
}
/**
@@ -12447,7 +12456,7 @@ window.turnstileCallback = function () {
* @returns void
*/
function insertQuotes(quotes) {
- let isAutoSave = false, draftContent = '';
+ let isAutoSave = false, draftContent = '', _minimized = minimized;
// Wrapper method for inserting quotes into the editor
const _doInsert = function () {
@@ -12485,20 +12494,47 @@ window.turnstileCallback = function () {
.run();
setTimeout(() => {
+ let pos
instance
.chain()
- .insertContent(toInsert + "
", {parseOptions: {preserveWhitespace: false}})
+ .command(({tr}) => pos = tr.doc.resolve(0).end())
+ .insertContentAt(pos, toInsert + "
", {parseOptions: {preserveWhitespace: false}})
.setMeta('preventUpdate', true)
.showMessage('autosave')
.focus()
+ .command(({chain, tr}) => chain().setTextSelection(tr.doc.resolve(0).end() - 1))
.run();
}, 10);
return;
+ } else if (_minimized) {
+ // It's odd, but if we insert a new line and move the cursor inside it, then the quote before the new line in a second transaction it works.
+ let to, from;
+ instance
+ .chain()
+ .command(({tr}) => {
+ to = tr.doc.resolve(0).end();
+ from = to;
+ if (tr.doc.lastChild?.inlineContent && ![...tr.doc.lastChild.children].some(desc => desc.nodeSize)) {
+ from = tr.doc.resolve(0).posAtIndex(tr.doc.childCount - 1);
+ }
+ return true;
+ })
+ .insertContentAt(to, "
")
+ .setTextSelection(to + 1)
+ .focus()
+ .run();
+
+ instance
+ .chain()
+ .insertContentAt({from,to}, toInsert, {parseOptions: {preserveWhitespace: false}, updateSelection:false})
+ .focus()
+ .run();
+ return;
}
instance
.chain()
- .insertContent(toInsert + "
", {parseOptions: {preserveWhitespace: false}})
+ .insertContent(toInsert + (instance.state.selection.empty && instance.state.selection.$from.nodeAfter ? "" : "
"), {parseOptions: {preserveWhitespace: false}})
.focus()
.run();
};
@@ -12653,7 +12689,7 @@ window.turnstileCallback = function () {
}
}(jQuery, _));]]>
-
-
-
-
- ');
card
+ .attr("popover", "manual")
.attr( { id: cardId } )
.addClass( options.className )
.css( {
- width: actualWidth + 'px',
- zIndex: ips.ui.zIndex()
+ width: actualWidth + 'px'
});
if( _.isString( content ) ){
@@ -14808,7 +14836,66 @@ window.turnstileCallback = function () {
};
};
}(jQuery, _));]]>
- {
+ Debug.log('Iframely embed.js loaded.');
+ });
+ }
+ }
+
+ return {
+ loadIframelyAdHoc,
+ init() {
+ loadIframelyAdHoc(document.body);
+ if (!loaded) {
+ const contentChange = (elem) => {
+ $(elem).each(function() {
+ if (this instanceof Element) {
+ loadIframelyAdHoc(this);
+ }
+ });
+
+ if (loaded) {
+ $(document).off('contentChange', contentChange);
+ }
+ };
+ $(document).on('contentChange', contentChange);
+ }
+ }
+ }
+ })
+})(jQuery, _);]]>
+
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -18541,7 +18628,7 @@ window.turnstileCallback = function () {
});
}(jQuery, _));
};
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -18557,7 +18644,7 @@ window.turnstileCallback = function () {
});
}
}(jQuery, _));
-
-
- ;( function(){
+ ;( function(){
"use strict";
ips.createModule('ips.ui.readmore', function(){
@@ -18982,7 +19069,7 @@ window.turnstileCallback = function () {
});
}());
-
-
-
-
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -23639,7 +23726,7 @@ window.turnstileCallback = function () {
});
}(jQuery, _));
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -27451,7 +27538,7 @@ window.turnstileCallback = function () {
};
});
}(jQuery, _));
-
- {
+ {
"use strict";
ips.createModule('ips.utils.pagebuildericons', function() {
@@ -27718,7 +27805,7 @@ window.turnstileCallback = function () {
return {}
})
})(jQuery, _))]]>
-
-
-
-
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -31321,7 +31408,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
-
-
-
-
-
-
-
-
-
- Invision Power Services, Inc.
* @copyright (c) Invision Power Services, Inc.
@@ -33649,7 +33736,7 @@ var escapeRegExp;
}
});
}(jQuery, _));]]>
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -33714,7 +33801,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
-
-
- } */
const OLD_TIME_ELEMENTS = new WeakSet();
}(jQuery, _));]]>
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -37607,7 +37694,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* IPS Social Suite 4
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -37649,7 +37736,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -38282,7 +38369,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -39362,7 +39449,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
- /**
+ /**
* Invision Community 5
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -39891,7 +39978,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -39929,7 +40016,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -40478,7 +40565,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -41063,7 +41150,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -41645,7 +41732,7 @@ var escapeRegExp;
});
}(jQuery, _));
- /**
+ /**
* IPS Social Suite 4
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -41704,7 +41791,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -41729,7 +41816,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -42119,7 +42206,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* IPS Social Suite 4
* (c) 2018 Invision Power Services - http://www.invisionpower.com
*
@@ -42194,7 +42281,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -42215,7 +42302,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -42926,7 +43013,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -43047,7 +43134,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -43928,7 +44015,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -44817,7 +44904,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -45149,7 +45236,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -45535,7 +45622,7 @@ var escapeRegExp;
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -45598,7 +45685,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -47024,7 +47111,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -47159,7 +47246,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -47283,7 +47370,7 @@ var escapeRegExp;
});
}(jQuery, _));
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -47779,7 +47866,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -47825,7 +47912,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -49992,7 +50078,7 @@ var escapeRegExp;
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -50055,7 +50141,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -50675,7 +50761,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -51906,7 +51992,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
-
-
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -55247,7 +55333,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -55625,7 +55711,7 @@ var escapeRegExp;
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -55689,7 +55775,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -55806,7 +55892,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -55856,7 +55942,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -55908,7 +55994,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -56320,7 +56406,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -56700,7 +56786,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
-
-
-
- \x20\t\r\n\f]*)[^>]*)\/>/gi;s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.migrateEnablePatches("self-closed-tags")},i(s,"htmlPrefilter",function(e){var t,r;return(r=(t=e).replace(F,"<$1>$2>"))!==t&&T(t)!==T(r)&&u("self-closed-tags","HTML tags must be properly nested and closed: "+t),e.replace(F,"<$1>$2>")},"self-closed-tags"),s.migrateDisablePatches("self-closed-tags");var D,W,_,I=s.fn.offset;return i(s.fn,"offset",function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?I.apply(this,arguments):(u("offset-valid-elem","jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},"offset-valid-elem"),s.ajax&&(D=s.param,i(s,"param",function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(u("param-ajax-traditional","jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),D.call(this,e,t)},"param-ajax-traditional")),c(s.fn,"andSelf",s.fn.addBack,"andSelf","jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),s.Deferred&&(W=s.Deferred,_=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],i(s,"Deferred",function(e){var a=W(),i=a.promise();function t(){var o=arguments;return s.Deferred(function(n){s.each(_,function(e,t){var r="function"==typeof o[e]&&o[e];a[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===i?n.promise():this,r?[e]:arguments)})}),o=null}).promise()}return c(a,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),c(i,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),e&&e.call(a,a),a},"deferred-pipe"),s.Deferred.exceptionHook=W.exceptionHook),s});]]>
-
- +~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML=" ",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(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(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML=" ",le.option=!!xe.lastChild;var ke={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0
- =0;r--)e.insertBefore(n[r],i),i=n[r]}function r(e,t,n){for(var i=[],r=e,a=Array.isArray(r),o=0,r=a?r:r[Symbol.iterator]();;){var l;if(a){if(o>=r.length)break;l=r[o++]}else{if(o=r.next(),o.done)break;l=o.value}var f=l;if("nl"===f.type&&t.nl2br)i.push(n.createElement("br"));else if(f.isLink&&t.check(f)){var s=t.resolve(f),c=s.formatted,u=s.formattedHref,d=s.tagName,m=s.className,y=s.target,h=s.events,k=s.attributes,v=n.createElement(d);if(v.setAttribute("href",u),m&&v.setAttribute("class",m),y&&v.setAttribute("target",y),k)for(var g in k)v.setAttribute(g,k[g]);if(h)for(var b in h)v.addEventListener?v.addEventListener(b,h[b]):v.attachEvent&&v.attachEvent("on"+b,h[b]);v.appendChild(n.createTextNode(c)),i.push(v)}else i.push(n.createTextNode(f.toString()))}return i}function a(e,t,n){if(!e||e.nodeType!==d)throw new Error("Cannot linkify "+e+" - Invalid DOM Node type");var o=t.ignoreTags;if("A"===e.tagName||s.contains(o,e.tagName))return e;for(var l=e.firstChild;l;){switch(l.nodeType){case d:a(l,t,n);break;case m:var c=l.nodeValue,y=f(c);if(0===y.length||1===y.length&&y[0]instanceof u)break;var h=r(y,t,n);i(e,l,h),l=h[h.length-1]}l=l.nextSibling}return e}function o(t,n){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];try{i=i||document||e&&e.document||global&&global.document}catch(r){}if(!i)throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the third argument to linkifyElement.");return n=new c(n),a(t,n,i)}function l(t){function n(e){return e=o.normalize(e),this.each(function(){o.helper(this,e,i)})}var i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];t.fn=t.fn||{};try{i=i||document||e&&e.document||global&&global.document}catch(r){}if(!i)throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the second argument to linkify/jquery");"function"!=typeof t.fn.linkify&&(t.fn.linkify=n,t(i).ready(function(){t("[data-linkify]").each(function(){var e=t(this),n=e.data(),i=n.linkify,r=n.linkifyNlbr,a={attributes:n.linkifyAttributes,defaultProtocol:n.linkifyDefaultProtocol,events:n.linkifyEvents,format:n.linkifyFormat,formatHref:n.linkifyFormatHref,nl2br:!!r&&0!==r&&"false"!==r,tagName:n.linkifyTagname,target:n.linkifyTarget,className:n.linkifyClassName||n.linkifyLinkclass,validate:n.linkifyValidate,ignoreTags:n.linkifyIgnoreTags},o="this"===i?e:e.find(i);o.linkify(a)})}))}t="default"in t?t["default"]:t;var f=n.tokenize,s=n.options,c=s.Options,u=n.parser.TOKENS.TEXT,d=1,m=3;o.helper=a,o.normalize=function(e){return new c(e)};try{!define&&(e.linkifyElement=o)}catch(y){}return l}(n,t);"function"!=typeof n.fn.linkify&&i(n)}(window,linkify,jQuery);]]>
- 2&&void 0!==arguments[2]?arguments[2]:{},o=Object.create(t.prototype);for(var a in n)o[a]=n[a];return o.constructor=e,e.prototype=o,e}function o(t){t=t||{},this.defaultProtocol=t.defaultProtocol||h.defaultProtocol,this.events=t.events||h.events,this.format=t.format||h.format,this.formatHref=t.formatHref||h.formatHref,this.nl2br=t.nl2br||h.nl2br,this.tagName=t.tagName||h.tagName,this.target=t.target||h.target,this.validate=t.validate||h.validate,this.ignoreTags=[],this.attributes=t.attributes||t.linkAttributes||h.attributes,this.className=t.className||t.linkClass||h.className;for(var e=t.ignoreTags||h.ignoreTags,n=0;n=r)return[];for(;a1&&void 0!==arguments[1]?arguments[1]:null,n=this.next(new t(""));return n===this.defaultTransition?(n=new this.constructor(e),this.on(t,n)):e&&(n.T=e),n},test:function(t,e){return t instanceof e}}),b=l();b.prototype={toString:function(){return this.v+""}};var v=u(),y=u("@"),k=u(":"),w=u("."),j=u(),x=u(),z=u("\n"),O=u(),S=u("+"),N=u("#"),T=u(),A=u("mailto:"),L=u("?"),E=u("/"),C=u("_"),P=u(),R=u(),q=u(),H=u("{"),B=u("["),U=u("<"),M=u("("),D=u("}"),I=u("]"),K=u(">"),_=u(")"),G=u("&"),Y=Object.freeze({Base:b,DOMAIN:v,AT:y,COLON:k,DOT:w,PUNCTUATION:j,LOCALHOST:x,NL:z,NUM:O,PLUS:S,POUND:N,QUERY:L,PROTOCOL:T,MAILTO:A,SLASH:E,UNDERSCORE:C,SYM:P,TLD:R,WS:q,OPENBRACE:H,OPENBRACKET:B,OPENANGLEBRACKET:U,OPENPAREN:M,CLOSEBRACE:D,CLOSEBRACKET:I,CLOSEANGLEBRACKET:K,CLOSEPAREN:_,AMPERSAND:G}),Q="aaa|aarp|abb|abbott|abogado|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|af|afl|ag|agency|ai|aig|airforce|airtel|al|alibaba|alipay|allfinanz|alsace|am|amica|amsterdam|an|analytics|android|ao|apartments|app|apple|aq|aquarelle|ar|aramco|archi|army|arpa|arte|as|asia|associates|at|attorney|au|auction|audi|audio|author|auto|autos|avianca|aw|ax|axa|az|azure|ba|baidu|band|bank|bar|barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bb|bbc|bbva|bcg|bcn|bd|be|beats|beer|bentley|berlin|best|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bom|bond|boo|book|boots|bosch|bostik|bot|boutique|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|camera|camp|cancerresearch|canon|capetown|capital|car|caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|chase|chat|cheap|chloe|christmas|chrome|church|ci|cipriani|circle|cisco|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|date|dating|datsun|day|dclk|de|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dj|dk|dm|dnp|do|docs|dog|doha|domains|download|drive|dubai|durban|dvag|dz|earth|eat|ec|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epson|equipment|er|erni|es|esq|estate|et|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|fage|fail|fairwinds|faith|family|fan|fans|farm|fashion|fast|feedback|ferrero|fi|film|final|finance|financial|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|florist|flowers|flsmidth|fly|fm|fo|foo|football|ford|forex|forsale|forum|foundation|fox|fr|fresenius|frl|frogans|frontier|fund|furniture|futbol|fyi|ga|gal|gallery|gallup|game|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|gold|goldpoint|golf|goo|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|group|gs|gt|gu|gucci|guge|guide|guitars|guru|gw|gy|hamburg|hangout|haus|hdfcbank|health|healthcare|help|helsinki|here|hermes|hiphop|hitachi|hiv|hk|hm|hn|hockey|holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hr|hsbc|ht|hu|hyundai|ibm|icbc|ice|icu|id|ie|ifm|iinet|il|im|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insurance|insure|int|international|investments|io|ipiranga|iq|ir|irish|is|iselect|ist|istanbul|it|itau|iwc|jaguar|java|jcb|je|jetzt|jewelry|jlc|jll|jm|jmp|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kitchen|kiwi|km|kn|koeln|komatsu|kp|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|lamborghini|lamer|lancaster|land|landrover|lanxess|lasalle|lat|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|legal|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|limited|limo|lincoln|linde|link|live|living|lixil|lk|loan|loans|local|locus|lol|london|lotte|lotto|love|lr|ls|lt|ltd|ltda|lu|lupin|luxe|luxury|lv|ly|ma|madrid|maif|maison|makeup|man|management|mango|market|marketing|markets|marriott|mba|mc|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|mg|mh|miami|microsoft|mil|mini|mk|ml|mm|mma|mn|mo|mobi|mobily|moda|moe|moi|mom|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mp|mq|mr|ms|mt|mtn|mtpc|mtr|mu|museum|mutuelle|mv|mw|mx|my|mz|na|nadex|nagoya|name|natura|navy|nc|ne|nec|net|netbank|network|neustar|new|news|nexus|nf|ng|ngo|nhk|ni|nico|nikon|ninja|nissan|nl|no|nokia|norton|nowruz|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|office|okinawa|om|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|origins|osaka|otsuka|ovh|pa|page|pamperedchef|panerai|paris|pars|partners|parts|party|passagens|pe|pet|pf|pg|ph|pharmacy|philips|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pohl|poker|porn|post|pr|praxi|press|pro|prod|productions|prof|promo|properties|property|protection|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|racing|re|read|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|ricoh|rio|rip|ro|rocher|rocks|rodeo|room|rs|rsvp|ru|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|sas|saxo|sb|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scor|scot|sd|se|seat|security|seek|select|sener|services|seven|sew|sex|sexy|sfr|sg|sh|sharp|shell|shia|shiksha|shoes|show|shriram|si|singles|site|sj|sk|ski|skin|sky|skype|sl|sm|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|spot|spreadbetting|sr|srl|st|stada|star|starhub|statefarm|statoil|stc|stcgroup|stockholm|storage|store|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|taobao|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|team|tech|technology|tel|telecity|telefonica|temasek|tennis|tf|tg|th|thd|theater|theatre|tickets|tienda|tiffany|tips|tires|tirol|tj|tk|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tp|tr|trade|trading|training|travel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubs|ug|uk|unicom|university|uno|uol|us|uy|uz|va|vacations|vana|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|viking|villas|vin|vip|virgin|vision|vista|vistaprint|viva|vlaanderen|vn|vodka|volkswagen|vote|voting|voto|voyage|vu|vuelos|wales|walter|wang|wanggou|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|wme|wolterskluwer|work|works|world|ws|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|youtube|yt|za|zara|zero|zip|zm|zone|zuerich|zw".split("|"),W="0123456789".split(""),X="0123456789abcdefghijklmnopqrstuvwxyz".split(""),Z=[" ","\f","\r","\t","\x0B"," "," ",""],F=[],J=function(t){return new m(t)},V=J(),$=J(O),tt=J(v),et=J(),nt=J(q);V.on("@",J(y)).on(".",J(w)).on("+",J(S)).on("#",J(N)).on("?",J(L)).on("/",J(E)).on("_",J(C)).on(":",J(k)).on("{",J(H)).on("[",J(B)).on("<",J(U)).on("(",J(M)).on("}",J(D)).on("]",J(I)).on(">",J(K)).on(")",J(_)).on("&",J(G)).on([",",";","!",'"',"'"],J(j)),V.on("\n",J(z)).on(Z,nt),nt.on(Z,nt);for(var ot=0;ot=0&&u++,c++,a++;if(!(u<0)){a-=u,c-=u;var p=l.emit();o.push(new p(t.substr(a-c,c)))}}return o},yt=V,kt=Object.freeze({State:m,TOKENS:Y,run:vt,start:yt}),wt=l();wt.prototype={type:"token",isLink:!1,toString:function(){for(var t=[],e=0;e0&&void 0!==arguments[0]?arguments[0]:"http";return{type:this.type,value:this.toString(),href:this.toHref(t)}}};var jt=n(wt,l(),{type:"email",isLink:!0}),xt=n(wt,l(),{type:"email",isLink:!0,toHref:function(){this.v;return"mailto:"+this.toString()}}),zt=n(wt,l(),{type:"text"}),Ot=n(wt,l(),{type:"nl"}),St=n(wt,l(),{type:"url",isLink:!0,toHref:function(){for(var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"http",e=!1,n=!1,o=this.v,a=[],r=0;o[r]instanceof T;)e=!0,a.push(o[r].toString().toLowerCase()),r++;for(;o[r]instanceof E;)n=!0,a.push(o[r].toString()),r++;for(;p(o[r]);)a.push(o[r].toString().toLowerCase()),r++;for(;r=0&&u++,n++,c++;if(u<0)for(var p=n-c;p0&&(o.push(new zt(a)),a=[]),n-=u,c-=u;var h=l.emit();o.push(new h(t.slice(n-c,n)))}}return a.length>0&&o.push(new zt(a)),o},fe=Object.freeze({State:d,TOKENS:Nt,run:ge,start:At});Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)});var me=function(t){return ge(vt(t))},de=function(t){for(var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=me(t),o=[],a=0;a1&&void 0!==arguments[1]?arguments[1]:null,n=me(t);return 1===n.length&&n[0].isLink&&(!e||n[0].type===e)};e.find=de,e.inherits=n,e.options=g,e.parser=fe,e.scanner=kt,e.test=be,e.tokenize=me}(self.linkify=self.linkify||{})}();]]>
- =0;r--)e.insertBefore(n[r],i),i=n[r]}function r(e,t,n){for(var i=[],r=e,a=Array.isArray(r),o=0,r=a?r:r[Symbol.iterator]();;){var l;if(a){if(o>=r.length)break;l=r[o++]}else{if(o=r.next(),o.done)break;l=o.value}var f=l;if("nl"===f.type&&t.nl2br)i.push(n.createElement("br"));else if(f.isLink&&t.check(f)){var s=t.resolve(f),c=s.formatted,u=s.formattedHref,d=s.tagName,m=s.className,y=s.target,h=s.events,k=s.attributes,v=n.createElement(d);if(v.setAttribute("href",u),m&&v.setAttribute("class",m),y&&v.setAttribute("target",y),k)for(var g in k)v.setAttribute(g,k[g]);if(h)for(var b in h)v.addEventListener?v.addEventListener(b,h[b]):v.attachEvent&&v.attachEvent("on"+b,h[b]);v.appendChild(n.createTextNode(c)),i.push(v)}else i.push(n.createTextNode(f.toString()))}return i}function a(e,t,n){if(!e||e.nodeType!==d)throw new Error("Cannot linkify "+e+" - Invalid DOM Node type");var o=t.ignoreTags;if("A"===e.tagName||s.contains(o,e.tagName))return e;for(var l=e.firstChild;l;){switch(l.nodeType){case d:a(l,t,n);break;case m:var c=l.nodeValue,y=f(c);if(0===y.length||1===y.length&&y[0]instanceof u)break;var h=r(y,t,n);i(e,l,h),l=h[h.length-1]}l=l.nextSibling}return e}function o(t,n){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];try{i=i||document||e&&e.document||global&&global.document}catch(r){}if(!i)throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the third argument to linkifyElement.");return n=new c(n),a(t,n,i)}function l(t){function n(e){return e=o.normalize(e),this.each(function(){o.helper(this,e,i)})}var i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];t.fn=t.fn||{};try{i=i||document||e&&e.document||global&&global.document}catch(r){}if(!i)throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the second argument to linkify/jquery");"function"!=typeof t.fn.linkify&&(t.fn.linkify=n,t(i).ready(function(){t("[data-linkify]").each(function(){var e=t(this),n=e.data(),i=n.linkify,r=n.linkifyNlbr,a={attributes:n.linkifyAttributes,defaultProtocol:n.linkifyDefaultProtocol,events:n.linkifyEvents,format:n.linkifyFormat,formatHref:n.linkifyFormatHref,nl2br:!!r&&0!==r&&"false"!==r,tagName:n.linkifyTagname,target:n.linkifyTarget,className:n.linkifyClassName||n.linkifyLinkclass,validate:n.linkifyValidate,ignoreTags:n.linkifyIgnoreTags},o="this"===i?e:e.find(i);o.linkify(a)})}))}t="default"in t?t["default"]:t;var f=n.tokenize,s=n.options,c=s.Options,u=n.parser.TOKENS.TEXT,d=1,m=3;o.helper=a,o.normalize=function(e){return new c(e)};try{!define&&(e.linkifyElement=o)}catch(y){}return l}(n,t);"function"!=typeof n.fn.linkify&&i(n)}(window,linkify,jQuery);]]>
+ 2&&void 0!==arguments[2]?arguments[2]:{},o=Object.create(t.prototype);for(var a in n)o[a]=n[a];return o.constructor=e,e.prototype=o,e}function o(t){t=t||{},this.defaultProtocol=t.defaultProtocol||h.defaultProtocol,this.events=t.events||h.events,this.format=t.format||h.format,this.formatHref=t.formatHref||h.formatHref,this.nl2br=t.nl2br||h.nl2br,this.tagName=t.tagName||h.tagName,this.target=t.target||h.target,this.validate=t.validate||h.validate,this.ignoreTags=[],this.attributes=t.attributes||t.linkAttributes||h.attributes,this.className=t.className||t.linkClass||h.className;for(var e=t.ignoreTags||h.ignoreTags,n=0;n=r)return[];for(;a1&&void 0!==arguments[1]?arguments[1]:null,n=this.next(new t(""));return n===this.defaultTransition?(n=new this.constructor(e),this.on(t,n)):e&&(n.T=e),n},test:function(t,e){return t instanceof e}}),b=l();b.prototype={toString:function(){return this.v+""}};var v=u(),y=u("@"),k=u(":"),w=u("."),j=u(),x=u(),z=u("\n"),O=u(),S=u("+"),N=u("#"),T=u(),A=u("mailto:"),L=u("?"),E=u("/"),C=u("_"),P=u(),R=u(),q=u(),H=u("{"),B=u("["),U=u("<"),M=u("("),D=u("}"),I=u("]"),K=u(">"),_=u(")"),G=u("&"),Y=Object.freeze({Base:b,DOMAIN:v,AT:y,COLON:k,DOT:w,PUNCTUATION:j,LOCALHOST:x,NL:z,NUM:O,PLUS:S,POUND:N,QUERY:L,PROTOCOL:T,MAILTO:A,SLASH:E,UNDERSCORE:C,SYM:P,TLD:R,WS:q,OPENBRACE:H,OPENBRACKET:B,OPENANGLEBRACKET:U,OPENPAREN:M,CLOSEBRACE:D,CLOSEBRACKET:I,CLOSEANGLEBRACKET:K,CLOSEPAREN:_,AMPERSAND:G}),Q="aaa|aarp|abb|abbott|abogado|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|af|afl|ag|agency|ai|aig|airforce|airtel|al|alibaba|alipay|allfinanz|alsace|am|amica|amsterdam|an|analytics|android|ao|apartments|app|apple|aq|aquarelle|ar|aramco|archi|army|arpa|arte|as|asia|associates|at|attorney|au|auction|audi|audio|author|auto|autos|avianca|aw|ax|axa|az|azure|ba|baidu|band|bank|bar|barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bb|bbc|bbva|bcg|bcn|bd|be|beats|beer|bentley|berlin|best|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bom|bond|boo|book|boots|bosch|bostik|bot|boutique|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|camera|camp|cancerresearch|canon|capetown|capital|car|caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|chase|chat|cheap|chloe|christmas|chrome|church|ci|cipriani|circle|cisco|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|date|dating|datsun|day|dclk|de|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dj|dk|dm|dnp|do|docs|dog|doha|domains|download|drive|dubai|durban|dvag|dz|earth|eat|ec|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epson|equipment|er|erni|es|esq|estate|et|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|fage|fail|fairwinds|faith|family|fan|fans|farm|fashion|fast|feedback|ferrero|fi|film|final|finance|financial|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|florist|flowers|flsmidth|fly|fm|fo|foo|football|ford|forex|forsale|forum|foundation|fox|fr|fresenius|frl|frogans|frontier|fund|furniture|futbol|fyi|ga|gal|gallery|gallup|game|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|gold|goldpoint|golf|goo|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|group|gs|gt|gu|gucci|guge|guide|guitars|guru|gw|gy|hamburg|hangout|haus|hdfcbank|health|healthcare|help|helsinki|here|hermes|hiphop|hitachi|hiv|hk|hm|hn|hockey|holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hr|hsbc|ht|hu|hyundai|ibm|icbc|ice|icu|id|ie|ifm|iinet|il|im|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insurance|insure|int|international|investments|io|ipiranga|iq|ir|irish|is|iselect|ist|istanbul|it|itau|iwc|jaguar|java|jcb|je|jetzt|jewelry|jlc|jll|jm|jmp|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kitchen|kiwi|km|kn|koeln|komatsu|kp|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|lamborghini|lamer|lancaster|land|landrover|lanxess|lasalle|lat|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|legal|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|limited|limo|lincoln|linde|link|live|living|lixil|lk|loan|loans|local|locus|lol|london|lotte|lotto|love|lr|ls|lt|ltd|ltda|lu|lupin|luxe|luxury|lv|ly|ma|madrid|maif|maison|makeup|man|management|mango|market|marketing|markets|marriott|mba|mc|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|mg|mh|miami|microsoft|mil|mini|mk|ml|mm|mma|mn|mo|mobi|mobily|moda|moe|moi|mom|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mp|mq|mr|ms|mt|mtn|mtpc|mtr|mu|museum|mutuelle|mv|mw|mx|my|mz|na|nadex|nagoya|name|natura|navy|nc|ne|nec|net|netbank|network|neustar|new|news|nexus|nf|ng|ngo|nhk|ni|nico|nikon|ninja|nissan|nl|no|nokia|norton|nowruz|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|office|okinawa|om|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|origins|osaka|otsuka|ovh|pa|page|pamperedchef|panerai|paris|pars|partners|parts|party|passagens|pe|pet|pf|pg|ph|pharmacy|philips|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pohl|poker|porn|post|pr|praxi|press|pro|prod|productions|prof|promo|properties|property|protection|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|racing|re|read|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|ricoh|rio|rip|ro|rocher|rocks|rodeo|room|rs|rsvp|ru|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|sas|saxo|sb|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scor|scot|sd|se|seat|security|seek|select|sener|services|seven|sew|sex|sexy|sfr|sg|sh|sharp|shell|shia|shiksha|shoes|show|shriram|si|singles|site|sj|sk|ski|skin|sky|skype|sl|sm|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|spot|spreadbetting|sr|srl|st|stada|star|starhub|statefarm|statoil|stc|stcgroup|stockholm|storage|store|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|taobao|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|team|tech|technology|tel|telecity|telefonica|temasek|tennis|tf|tg|th|thd|theater|theatre|tickets|tienda|tiffany|tips|tires|tirol|tj|tk|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tp|tr|trade|trading|training|travel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubs|ug|uk|unicom|university|uno|uol|us|uy|uz|va|vacations|vana|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|viking|villas|vin|vip|virgin|vision|vista|vistaprint|viva|vlaanderen|vn|vodka|volkswagen|vote|voting|voto|voyage|vu|vuelos|wales|walter|wang|wanggou|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|wme|wolterskluwer|work|works|world|ws|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|youtube|yt|za|zara|zero|zip|zm|zone|zuerich|zw".split("|"),W="0123456789".split(""),X="0123456789abcdefghijklmnopqrstuvwxyz".split(""),Z=[" ","\f","\r","\t","\x0B"," "," ",""],F=[],J=function(t){return new m(t)},V=J(),$=J(O),tt=J(v),et=J(),nt=J(q);V.on("@",J(y)).on(".",J(w)).on("+",J(S)).on("#",J(N)).on("?",J(L)).on("/",J(E)).on("_",J(C)).on(":",J(k)).on("{",J(H)).on("[",J(B)).on("<",J(U)).on("(",J(M)).on("}",J(D)).on("]",J(I)).on(">",J(K)).on(")",J(_)).on("&",J(G)).on([",",";","!",'"',"'"],J(j)),V.on("\n",J(z)).on(Z,nt),nt.on(Z,nt);for(var ot=0;ot=0&&u++,c++,a++;if(!(u<0)){a-=u,c-=u;var p=l.emit();o.push(new p(t.substr(a-c,c)))}}return o},yt=V,kt=Object.freeze({State:m,TOKENS:Y,run:vt,start:yt}),wt=l();wt.prototype={type:"token",isLink:!1,toString:function(){for(var t=[],e=0;e0&&void 0!==arguments[0]?arguments[0]:"http";return{type:this.type,value:this.toString(),href:this.toHref(t)}}};var jt=n(wt,l(),{type:"email",isLink:!0}),xt=n(wt,l(),{type:"email",isLink:!0,toHref:function(){this.v;return"mailto:"+this.toString()}}),zt=n(wt,l(),{type:"text"}),Ot=n(wt,l(),{type:"nl"}),St=n(wt,l(),{type:"url",isLink:!0,toHref:function(){for(var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"http",e=!1,n=!1,o=this.v,a=[],r=0;o[r]instanceof T;)e=!0,a.push(o[r].toString().toLowerCase()),r++;for(;o[r]instanceof E;)n=!0,a.push(o[r].toString()),r++;for(;p(o[r]);)a.push(o[r].toString().toLowerCase()),r++;for(;r=0&&u++,n++,c++;if(u<0)for(var p=n-c;p0&&(o.push(new zt(a)),a=[]),n-=u,c-=u;var h=l.emit();o.push(new h(t.slice(n-c,n)))}}return a.length>0&&o.push(new zt(a)),o},fe=Object.freeze({State:d,TOKENS:Nt,run:ge,start:At});Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)});var me=function(t){return ge(vt(t))},de=function(t){for(var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=me(t),o=[],a=0;a1&&void 0!==arguments[1]?arguments[1]:null,n=me(t);return 1===n.length&&n[0].isLink&&(!e||n[0].type===e)};e.find=de,e.inherits=n,e.options=g,e.parser=fe,e.scanner=kt,e.test=be,e.tokenize=me}(self.linkify=self.linkify||{})}();]]>
+
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -58799,7 +58885,7 @@ var escapeRegExp;
}
});
}(jQuery, _));
-
-
- ":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var lineHasNonSpace=false;var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;var indentation="";var tagIndex=0;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i"){token=[type,value,start,scanner.pos,indentation,tagIndex,lineHasNonSpace]}else{token=[type,value,start,scanner.pos]}tagIndex++;tokens.push(token);if(type==="#"||type==="^"){sections.push(token)}else if(type==="/"){openSection=sections.pop();if(!openSection)throw new Error('Unopened section "'+value+'" at '+start);if(openSection[1]!==value)throw new Error('Unclosed section "'+openSection[1]+'" at '+start)}else if(type==="name"||type==="{"||type==="&"){nonSpace=true}else if(type==="="){compileTags(value)}}stripSpace();openSection=sections.pop();if(openSection)throw new Error('Unclosed section "'+openSection[1]+'" at '+scanner.pos);return nestTokens(squashTokens(tokens))}function squashTokens(tokens){var squashedTokens=[];var token,lastToken;for(var i=0,numTokens=tokens.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,intermediateValue,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){intermediateValue=context.view;names=name.split(".");index=0;while(intermediateValue!=null&&index")value=this.renderPartial(token,context,partials,config);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context,config);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate,config){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials,config)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j0||!lineHasNonSpace)){partialByNl[i]=filteredIndentation+partialByNl[i]}}return partialByNl.join("\n")};Writer.prototype.renderPartial=function renderPartial(token,context,partials,config){if(!partials)return;var tags=this.getConfigTags(config);var value=isFunction(partials)?partials(token[1]):partials[token[1]];if(value!=null){var lineHasNonSpace=token[6];var tagIndex=token[5];var indentation=token[4];var indentedValue=value;if(tagIndex==0&&indentation){indentedValue=this.indentPartial(value,indentation,lineHasNonSpace)}var tokens=this.parse(indentedValue,tags);return this.renderTokens(tokens,context,partials,indentedValue,config)}};Writer.prototype.unescapedValue=function unescapedValue(token,context){var value=context.lookup(token[1]);if(value!=null)return value};Writer.prototype.escapedValue=function escapedValue(token,context,config){var escape=this.getConfigEscape(config)||mustache.escape;var value=context.lookup(token[1]);if(value!=null)return typeof value==="number"&&escape===mustache.escape?String(value):escape(value)};Writer.prototype.rawValue=function rawValue(token){return token[1]};Writer.prototype.getConfigTags=function getConfigTags(config){if(isArray(config)){return config}else if(config&&typeof config==="object"){return config.tags}else{return undefined}};Writer.prototype.getConfigEscape=function getConfigEscape(config){if(config&&typeof config==="object"&&!isArray(config)){return config.escape}else{return undefined}};var mustache={name:"mustache.js",version:"4.2.0",tags:["{{","}}"],clearCache:undefined,escape:undefined,parse:undefined,render:undefined,Scanner:undefined,Context:undefined,Writer:undefined,set templateCache(cache){defaultWriter.templateCache=cache},get templateCache(){return defaultWriter.templateCache}};var defaultWriter=new Writer;mustache.clearCache=function clearCache(){return defaultWriter.clearCache()};mustache.parse=function parse(template,tags){return defaultWriter.parse(template,tags)};mustache.render=function render(template,view,partials,config){if(typeof template!=="string"){throw new TypeError('Invalid template! Template should be a "string" '+'but "'+typeStr(template)+'" was given as the first '+"argument for mustache#render(template, view, partials)")}return defaultWriter.render(template,view,partials,config)};mustache.escape=escapeHtml;mustache.Scanner=Scanner;mustache.Context=Context;mustache.Writer=Writer;return mustache});]]>
- \
");
@@ -59104,7 +59190,7 @@ ips.templates.set('support.ticket.supportSummary', " \
{{#lang}}health_ticket_beforeproceeding{{/lang}}\
\
");]]>
- \
{{{contents}}}\
\
@@ -59121,7 +59207,7 @@ ips.templates.set( 'templates.customizationMedia.noSearchResults', "\
{{#lang}}mediaNoResults{{/lang}}\
\
");]]>
-
@@ -59142,7 +59228,7 @@ ips.templates.set('dashboard.widget', `
`);]]>
- \
\
@@ -59155,7 +59241,7 @@ ips.templates.set( 'moderatorPermissions.checkUncheckAll', "\
\
\
");]]>
- \
\
{{#lang}}menuManagerNewItem{{/lang}}\
@@ -59189,7 +59275,7 @@ ips.templates.set( 'menuManager.temporaryMenuItem', "\
ips.templates.set( 'menuManager.emptyList', "\
\
");]]>
- \
\
@@ -59279,7 +59365,7 @@ ips.templates.set('core.autocomplete.memberItem', " \
ips.templates.set('core.autocomplete.optional', " \
{{langString}}... \
");]]>
-
-
-
-
-
- {{#canEdit}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{/canEdit}}
-
+
+
+
+ {{#canEdit}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{/canEdit}}
`);
@@ -60363,7 +60447,7 @@ ips.templates.set('ips.ui.controls.cannot_load', `
return ips.getString('ips.ui.controls.cannot_load')
}
})]]>
- \
\
\
@@ -60382,7 +60466,7 @@ ips.templates.set('club.request.decline', "\
ips.templates.set('club.menu.dragHandle', "\
\
");]]>
- \
\
@@ -60393,7 +60477,7 @@ ips.templates.set('messages.view.placeholder', " \
ips.templates.set('messages.main.folderMenu', "\
{{name}} \
");]]>
-
{{{words}}}
@@ -60412,7 +60496,7 @@ ips.templates.set('core.streams.noMore', `
ips.templates.set('core.streams.loadMore', `
{{#lang}}loadNewActivity{{/lang}}
`);]]>
- \
{{/hasNotifications}}\
@@ -60421,7 +60505,7 @@ ips.templates.set('core.streams.loadMore', `
{{/hasNotifications}}\
{{text}}\
");]]>
- {{title}}\
");
@@ -60567,7 +60651,7 @@ ips.templates.set('vse.colorizer.panel', " \
{{#lang}}vseColorizer_revert{{/lang}} \
\
");]]>
-
-
-
- /**
+ /**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -61200,7 +61284,7 @@ ips.templates.set('vse.colorizer.panel', " \
};
});
}(jQuery, _));
-
- =0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e":">",'"':""","'":"'","`":"`"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o0?0:u-1;o>=0&&o0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ao&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);ir?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ae||void 0===t)return 1;if(t
-
diff --git a/applications/core/data/lang.xml b/applications/core/data/lang.xml
index cd2291cf..ff28f399 100644
--- a/applications/core/data/lang.xml
+++ b/applications/core/data/lang.xml
@@ -1,6 +1,6 @@
-
+
This distribution is Nulled! You can't use this function.
Delete logs
System
@@ -4286,13 +4286,31 @@
Allow links to be converted to iframes?
When this is enabled, users with permission will see a button to convert the link to an iframe if the URL's Domain is allowed.
Allowed Domain Patterns
- * as a wildcard. Note that subdomains must be explicitly specified in a pattern to be allowed. For example, the pattern google.com would not allow https://www.google.com/, but *.google.com or www.google.com would. This setting only applies when saving new content and edits in the future.]]>
+ * as a wildcard. Note that subdomains must be explicitly specified in a pattern to be allowed. For example, the pattern google.com would not allow https://www.google.com/, but *.google.com or www.google.com would. This setting only applies when saving new content and edits in the future.]]>
Moderate iframes in Posts
Allow
Any iframe can be directly posted.
Moderate
If an iframe with a custom source is posted, the content will be held for moderator approval.
Facebook
+ Facebook embeds have been deprecated. While you can edit the current configuration to retain functionality, this feature will be removed at some point in the future.
+ Iframely
+ Iframely allows you to embed rich content from hundreds of online providers in the Invision Community Editor.
+ Iframely.com to create your account and get an API key.]]>
+ Editor Permission Settings .]]>
+ Enable Iframely
+ Iframely for available embeddable content from the URL.]]>
+ Iframely Client Key Hash
+ The key hash can be copied from your Iframely account overview. Note the Client Key Hash is different from the Server API Key itself.
+ Popular Content Providers
+ If a URL's domain belongs to one of these services, the system will check Iframely for embeddable content from that URL.
+ Facebook / Meta]]>
+ Instagram]]>
+ Custom Domain Patterns
+ In addition to the default content providers, you can check Iframely for embeddable content for any URL whose domain matches one of these patterns. Use * as a wildcard. Note that subdomains must be explicitly specified in a pattern to be allowed For example, the pattern google.com would not allow https://www.google.com/, but *.google.com or www.google.com would. Only allow embeds for websites that you trust, embedding content from untrusted sources could introduce security risks. ]]>
+ No API key specified
+ API Key invalid
+ Iframely Integration can be used to embed content from additional third party sources, including Facebook and Instagram.]]>
Can manage Simplified Editing mode
Editor Permissions
Member Group Settings for a group.]]>
@@ -7257,6 +7275,7 @@
Action to complete the step
Show on Registration
Include this step in the registration process
+ Quick Registration is currently enabled. This setting is only supported with full registration.
Title
Action
Required
@@ -7425,6 +7444,7 @@
System Information
Member Accounts
Commerce
+ Other
An important message from Invision Power Services about your community:
Important message about your community
Custom Notification
diff --git a/applications/core/data/settings.json b/applications/core/data/settings.json
index 272bdf0a..071e342b 100644
--- a/applications/core/data/settings.json
+++ b/applications/core/data/settings.json
@@ -834,6 +834,31 @@
"default": "",
"report": "bool"
},
+ {
+ "key": "iframely_api_key",
+ "default": "",
+ "report": "none"
+ },
+ {
+ "key": "iframely_enabled",
+ "default": "0",
+ "report": "full"
+ },
+ {
+ "key": "iframely_facebook_enabled",
+ "default": "0",
+ "report": "full"
+ },
+ {
+ "key": "iframely_instagram_enabled",
+ "default": "0",
+ "report": "full"
+ },
+ {
+ "key": "iframely_url_whitelist",
+ "default": "",
+ "report": "none"
+ },
{
"key": "ignore_system_on",
"default": "1",
diff --git a/applications/core/data/theme.xml b/applications/core/data/theme.xml
index 0a8cf3a0..a7f57194 100644
--- a/applications/core/data/theme.xml
+++ b/applications/core/data/theme.xml
@@ -1469,7 +1469,7 @@
{{foreach $rows[1] as $key => $data}}
-
+
{lang="$data['title']"}
{{if $data['enabled'] == 1}}
@@ -1505,7 +1505,7 @@
]]>
getVi
{{if $comment->author()->hasHighlightedReplies() || ( \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\Reactable' ) and $comment->isHighlighted() ) OR ( \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\MetaData' ) and $comment->isFeatured() ) }}
{{if $comment->author()->hasHighlightedReplies()}}
- {expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->name" raw="true"}
+ {expression="\IPS\Member\Group::load( $comment->author()->highlightedGroup() )->name" raw="true"}
{{endif}}
{{if \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\MetaData' ) and $comment->isFeatured() }}
{lang="this_is_a_featured_post"}
@@ -9595,7 +9599,7 @@ data-view-tracking-data="{expression="base64_encode(json_encode( $comment->getVi
{lang='language'}