76e7c5a5 by Acetousk Committed by GitHub

Merge pull request #2 from moqui/test-upstream

Test upstream
2 parents 76e88ff2 3db488ac
......@@ -11,3 +11,4 @@ To install run (with moqui-framework):
### Setup
- Have all email templates setup as a ProductStoreEmail to EmailTemplate see: the ProductStore's Emails page
......
/*
* This software is in the public domain under CC0 1.0 Universal plus a
* Grant of Patent License.
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software to the
* public domain worldwide. This software is distributed without any
* warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software (see the LICENSE.md file). If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
apply plugin: 'groovy'
version = '3.0.0'
// sourceCompatibility = '1.8'
def moquiDir = file(projectDir.absolutePath + '/../../..')
def frameworkDir = file(moquiDir.absolutePath + '/framework')
repositories {
flatDir name: 'localLib', dirs: frameworkDir.absolutePath + '/lib'
mavenCentral()
}
// Log4J has annotation processors, disable to avoid warning
tasks.withType(JavaCompile) { options.compilerArgs << "-proc:none" }
tasks.withType(GroovyCompile) { options.compilerArgs << "-proc:none" }
dependencies {
implementation project(':framework')
testImplementation project(':framework').configurations.testImplementation.allDependencies
}
// by default the Java plugin runs test on build, change to not do that (only run test if explicit task)
// no longer workds as of gradle 4.8 or possibly earlier, use clear() instead: check.dependsOn.remove(test)
check.dependsOn.clear()
jar {
destinationDirectory = file(projectDir.absolutePath + '/lib')
// this is required to change from the default that includes the path to this module (ie 'runtime/component/mjml')
archiveBaseName = 'moqui-mjml'
}
task cleanLib(type: Delete) { delete file(jar.archivePath) }
clean.dependsOn cleanLib
test {
useJUnitPlatform()
testLogging { events "passed", "skipped", "failed" }
testLogging.showStandardStreams = true; testLogging.showExceptions = true
maxParallelForks 1
dependsOn cleanTest
systemProperty 'moqui.runtime', moquiDir.absolutePath + '/runtime'
systemProperty 'moqui.conf', 'conf/MoquiDevConf.xml'
systemProperty 'moqui.init.static', 'true'
maxHeapSize = "512M"
classpath += files(sourceSets.main.output.classesDirs)
// filter out classpath entries that don't exist (gradle adds a bunch of these), or ElasticSearch JarHell will blow up
classpath = classpath.filter { it.exists() }
beforeTest { descriptor ->
logger.lifecycle("Running test: ${descriptor}")
}
}
......@@ -13,6 +13,7 @@ along with this software (see the LICENSE.md file). If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
-->
<entity-facade-xml type="seed">
<!-- ========= Screen Theme Resource for GrapesJs / mjml -->
<moqui.basic.Enumeration description="Mjml Theme Type" enumId="STT_MJML" enumTypeId="ScreenThemeType"/>
<moqui.screen.ScreenTheme screenThemeId="MJML_DEFAULT" screenThemeTypeEnumId="STT_MJML"
description="Mjml Default Theme"/>
......@@ -26,13 +27,20 @@ along with this software (see the LICENSE.md file). If not, see
<moqui.screen.ScreenThemeResource screenThemeId="MJML_DEFAULT" sequenceNum="110" resourceTypeEnumId="STRT_HEADER_TITLE"
resourceValue="Email Editor"/>
<!-- ========= DB Resource for storing project and template files -->
<moqui.resource.DbResource resourceId="GRAPESJS" filename="grapesjs" isFile="N"/>
<moqui.resource.DbResource resourceId="GRAPESJS_PROJECT" filename="project" isFile="N" parentResourceId="GRAPESJS"/>
<moqui.resource.DbResource resourceId="GRAPESJS_TEMPLATE" filename="template" isFile="N" parentResourceId="GRAPESJS"/>
<dbResources resourceId="GRAPESJS_TEMPLATE_DEFAULT" filename="default.json" isFile="Y" parentResourceId="GRAPESJS_TEMPLATE">
<file rootVersionName="01" mimeType="text/json" versionName="01">
<fileData><![CDATA[eyJhc3NldHMiOltdLCJzdHlsZXMiOlt7InNlbGVjdG9ycyI6W10sInNlbGVjdG9yc0FkZCI6IiNvdXRsb29rIGEiLCJzdHlsZSI6eyJwYWRkaW5nLXRvcCI6IjBweCIsInBhZGRpbmctcmlnaHQiOiIwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjBweCIsInBhZGRpbmctbGVmdCI6IjBweCJ9fSx7InNlbGVjdG9ycyI6W10sInNlbGVjdG9yc0FkZCI6ImJvZHkiLCJzdHlsZSI6eyJtYXJnaW4tdG9wIjoiMHB4IiwibWFyZ2luLXJpZ2h0IjoiMHB4IiwibWFyZ2luLWJvdHRvbSI6IjBweCIsIm1hcmdpbi1sZWZ0IjoiMHB4IiwicGFkZGluZy10b3AiOiIwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMHB4IiwicGFkZGluZy1ib3R0b20iOiIwcHgiLCJwYWRkaW5nLWxlZnQiOiIwcHgiLCJ0ZXh0LXNpemUtYWRqdXN0IjoiMTAwJSJ9fSx7InNlbGVjdG9ycyI6W10sInNlbGVjdG9yc0FkZCI6InRhYmxlLCB0ZCIsInN0eWxlIjp7ImJvcmRlci1jb2xsYXBzZSI6ImNvbGxhcHNlIn19LHsic2VsZWN0b3JzIjpbXSwic2VsZWN0b3JzQWRkIjoiaW1nIiwic3R5bGUiOnsiYm9yZGVyLXRvcC13aWR0aCI6IjBweCIsImJvcmRlci1yaWdodC13aWR0aCI6IjBweCIsImJvcmRlci1ib3R0b20td2lkdGgiOiIwcHgiLCJib3JkZXItbGVmdC13aWR0aCI6IjBweCIsImJvcmRlci10b3Atc3R5bGUiOiJpbml0aWFsIiwiYm9yZGVyLXJpZ2h0LXN0eWxlIjoiaW5pdGlhbCIsImJvcmRlci1ib3R0b20tc3R5bGUiOiJpbml0aWFsIiwiYm9yZGVyLWxlZnQtc3R5bGUiOiJpbml0aWFsIiwiYm9yZGVyLXRvcC1jb2xvciI6ImluaXRpYWwiLCJib3JkZXItcmlnaHQtY29sb3IiOiJpbml0aWFsIiwiYm9yZGVyLWJvdHRvbS1jb2xvciI6ImluaXRpYWwiLCJib3JkZXItbGVmdC1jb2xvciI6ImluaXRpYWwiLCJib3JkZXItaW1hZ2Utc291cmNlIjoiaW5pdGlhbCIsImJvcmRlci1pbWFnZS1zbGljZSI6ImluaXRpYWwiLCJib3JkZXItaW1hZ2Utd2lkdGgiOiJpbml0aWFsIiwiYm9yZGVyLWltYWdlLW91dHNldCI6ImluaXRpYWwiLCJib3JkZXItaW1hZ2UtcmVwZWF0IjoiaW5pdGlhbCIsImhlaWdodCI6ImF1dG8iLCJsaW5lLWhlaWdodCI6IjEwMCUiLCJvdXRsaW5lLWNvbG9yIjoiaW5pdGlhbCIsIm91dGxpbmUtc3R5bGUiOiJub25lIiwib3V0bGluZS13aWR0aCI6ImluaXRpYWwiLCJ0ZXh0LWRlY29yYXRpb24tbGluZSI6Im5vbmUiLCJ0ZXh0LWRlY29yYXRpb24tdGhpY2tuZXNzIjoiaW5pdGlhbCIsInRleHQtZGVjb3JhdGlvbi1zdHlsZSI6ImluaXRpYWwiLCJ0ZXh0LWRlY29yYXRpb24tY29sb3IiOiJpbml0aWFsIn19LHsic2VsZWN0b3JzIjpbXSwic2VsZWN0b3JzQWRkIjoicCIsInN0eWxlIjp7ImRpc3BsYXkiOiJibG9jayIsIm1hcmdpbi10b3AiOiIxM3B4IiwibWFyZ2luLXJpZ2h0IjoiMHB4IiwibWFyZ2luLWJvdHRvbSI6IjEzcHgiLCJtYXJnaW4tbGVmdCI6IjBweCJ9fSx7InNlbGVjdG9ycyI6WyJtai1jb2x1bW4tcGVyLTEwMCJdLCJzdHlsZSI6eyJ3aWR0aCI6IjEwMCUgIWltcG9ydGFudCIsIm1heC13aWR0aCI6IjEwMCUifSwibWVkaWFUZXh0Ijoib25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDQ4MHB4KSIsImF0UnVsZVR5cGUiOiJtZWRpYSJ9LHsic2VsZWN0b3JzIjpbXSwic2VsZWN0b3JzQWRkIjoiLm1vei10ZXh0LWh0bWwgLm1qLWNvbHVtbi1wZXItMTAwIiwic3R5bGUiOnsid2lkdGgiOiIxMDAlICFpbXBvcnRhbnQiLCJtYXgtd2lkdGgiOiIxMDAlIn19LHsic2VsZWN0b3JzIjpbIm1qLWNvbHVtbi1wZXItNTAiXSwic3R5bGUiOnsid2lkdGgiOiI1MCUgIWltcG9ydGFudCIsIm1heC13aWR0aCI6IjUwJSJ9LCJtZWRpYVRleHQiOiJvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNDgwcHgpIiwiYXRSdWxlVHlwZSI6Im1lZGlhIn0seyJzZWxlY3RvcnMiOltdLCJzZWxlY3RvcnNBZGQiOiIubW96LXRleHQtaHRtbCAubWotY29sdW1uLXBlci01MCIsInN0eWxlIjp7IndpZHRoIjoiNTAlICFpbXBvcnRhbnQiLCJtYXgtd2lkdGgiOiI1MCUifX0seyJzZWxlY3RvcnMiOlsibWotY29sdW1uLXBlci0zMy0zMzMzMzMzMzMzMzMzMzYiXSwic3R5bGUiOnsid2lkdGgiOiIzMy4zMzMzJSAhaW1wb3J0YW50IiwibWF4LXdpZHRoIjoiMzMuMzMzMyUifSwibWVkaWFUZXh0Ijoib25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDQ4MHB4KSIsImF0UnVsZVR5cGUiOiJtZWRpYSJ9LHsic2VsZWN0b3JzIjpbXSwic2VsZWN0b3JzQWRkIjoiLm1vei10ZXh0LWh0bWwgLm1qLWNvbHVtbi1wZXItMzMtMzMzMzMzMzMzMzMzMzM2Iiwic3R5bGUiOnsid2lkdGgiOiIzMy4zMzMzJSAhaW1wb3J0YW50IiwibWF4LXdpZHRoIjoiMzMuMzMzMyUifX1dLCJwYWdlcyI6W3siZnJhbWVzIjpbeyJjb21wb25lbnQiOnsidHlwZSI6IndyYXBwZXIiLCJzdHlsYWJsZSI6WyJiYWNrZ3JvdW5kIiwiYmFja2dyb3VuZC1jb2xvciIsImJhY2tncm91bmQtaW1hZ2UiLCJiYWNrZ3JvdW5kLXJlcGVhdCIsImJhY2tncm91bmQtYXR0YWNobWVudCIsImJhY2tncm91bmQtcG9zaXRpb24iLCJiYWNrZ3JvdW5kLXNpemUiXSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qbWwiLCJ0eXBlIjoibWptbCIsImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai1oZWFkIiwidHlwZSI6Im1qLWhlYWQiLCJjb21wb25lbnRzIjpbeyJ0YWdOYW1lIjoibWotZm9udCIsInR5cGUiOiJtai1mb250Iiwic3R5bGUiOnsibmFtZSI6IkJhcmxvdyIsImhyZWYiOiJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9QmFybG93In0sImF0dHJpYnV0ZXMiOnsibmFtZSI6IkJhcmxvdyIsImhyZWYiOiJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9QmFybG93Iiwic3R5bGUiOiJuYW1lOkJhcmxvdztocmVmOmh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1CYXJsb3c7In19LHsidGFnTmFtZSI6Im1qLXN0eWxlIiwidHlwZSI6Im1qLXN0eWxlIiwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zbG9nYW4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICMwMDA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgIn1dfV19LHsidGFnTmFtZSI6Im1qLWJvZHkiLCJ0eXBlIjoibWotYm9keSIsInN0eWxlIjp7IndpZHRoIjoiNjAwcHgifSwiYXR0cmlidXRlcyI6eyJ3aWR0aCI6IjYwMHB4Iiwic3R5bGUiOiJ3aWR0aDo2MDBweDsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6ImNvbW1lbnQiLCJjb250ZW50IjoiIENvbXBhbnkgSGVhZGVyICJ9LHsidGFnTmFtZSI6Im1qLXNlY3Rpb24iLCJ0eXBlIjoibWotc2VjdGlvbiIsInN0eWxlIjp7ImJhY2tncm91bmQtY29sb3IiOiIjZjBmMGYwIiwicGFkZGluZy1sZWZ0IjoiMHB4IiwicGFkZGluZy1yaWdodCI6IjBweCIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInRleHQtYWxpZ24iOiJjZW50ZXIifSwiYXR0cmlidXRlcyI6eyJiYWNrZ3JvdW5kLWNvbG9yIjoiI2YwZjBmMCIsInBhZGRpbmctbGVmdCI6IjBweCIsInBhZGRpbmctcmlnaHQiOiIwcHgiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJ0ZXh0LWFsaWduIjoiY2VudGVyIiwic3R5bGUiOiJiYWNrZ3JvdW5kLWNvbG9yOiNmMGYwZjA7cGFkZGluZy1sZWZ0OjBweDtwYWRkaW5nLXJpZ2h0OjBweDtwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7dGV4dC1hbGlnbjpjZW50ZXI7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai1jb2x1bW4iLCJ0eXBlIjoibWotY29sdW1uIiwic3R5bGUiOnsiYm9yZGVyIjoiMTBweCBzb2xpZCAjRjQ1RTQzIiwidmVydGljYWwtYWxpZ24iOiJ0b3AifSwiYXR0cmlidXRlcyI6eyJib3JkZXIiOiIxMHB4IHNvbGlkICNGNDVFNDMiLCJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCIsInN0eWxlIjoiYm9yZGVyOjEwcHggc29saWQgI0Y0NUU0Mzt2ZXJ0aWNhbC1hbGlnbjp0b3A7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai10ZXh0IiwidHlwZSI6Im1qLXRleHQiLCJzdHlsZSI6eyJmb250LWZhbWlseSI6IkJhcmxvdyIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJhbGlnbiI6ImxlZnQifSwiYXR0cmlidXRlcyI6eyJmb250LWZhbWlseSI6IkJhcmxvdyIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJhbGlnbiI6ImxlZnQiLCJzdHlsZSI6ImZvbnQtZmFtaWx5OkJhcmxvdztwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7cGFkZGluZy1yaWdodDoyNXB4O3BhZGRpbmctbGVmdDoyNXB4O2ZvbnQtc2l6ZToxM3B4O2xpbmUtaGVpZ2h0OjIycHg7YWxpZ246bGVmdDsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IkEgZmlyc3QgbGluZSBvZiB0ZXh0In1dfSx7InRhZ05hbWUiOiJtai1zcGFjZXIiLCJ0eXBlIjoibWotc3BhY2VyIiwic3R5bGUiOnsiaGVpZ2h0IjoiNTBweCJ9LCJhdHRyaWJ1dGVzIjp7ImhlaWdodCI6IjUwcHgiLCJzdHlsZSI6ImhlaWdodDo1MHB4OyJ9LCJjb21wb25lbnRzIjpbeyJ0eXBlIjoidGV4dG5vZGUiLCJjb250ZW50IjoiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1dfV19XX0seyJ0eXBlIjoiY29tbWVudCIsImNvbnRlbnQiOiIgSW1hZ2UgSGVhZGVyICJ9LHsidGFnTmFtZSI6Im1qLXNlY3Rpb24iLCJ0eXBlIjoibWotc2VjdGlvbiIsInN0eWxlIjp7ImJhY2tncm91bmQtdXJsIjoiaHR0cDovLzEuYnAuYmxvZ3Nwb3QuY29tLy1UUHJmaHhiWXBEWS9VaDNSZWZ6azAySS9BQUFBQUFBQUx3OC81c1VKMFVVR1l1dy9zMTYwMC9OZXcrWW9yaytpbitUaGUrMTk2MCdzKy0rNzAncysoMikuanBnIiwiYmFja2dyb3VuZC1zaXplIjoiY292ZXIiLCJiYWNrZ3JvdW5kLXJlcGVhdCI6Im5vLXJlcGVhdCIsInBhZGRpbmctbGVmdCI6IjBweCIsInBhZGRpbmctcmlnaHQiOiIwcHgiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJ0ZXh0LWFsaWduIjoiY2VudGVyIn0sImF0dHJpYnV0ZXMiOnsiYmFja2dyb3VuZC11cmwiOiJodHRwOi8vMS5icC5ibG9nc3BvdC5jb20vLVRQcmZoeGJZcERZL1VoM1JlZnprMDJJL0FBQUFBQUFBTHc4LzVzVUowVVVHWXV3L3MxNjAwL05ldytZb3JrK2luK1RoZSsxOTYwJ3MrLSs3MCdzKygyKS5qcGciLCJiYWNrZ3JvdW5kLXNpemUiOiJjb3ZlciIsImJhY2tncm91bmQtcmVwZWF0Ijoibm8tcmVwZWF0IiwicGFkZGluZy1sZWZ0IjoiMHB4IiwicGFkZGluZy1yaWdodCI6IjBweCIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInRleHQtYWxpZ24iOiJjZW50ZXIiLCJzdHlsZSI6ImJhY2tncm91bmQtdXJsOmh0dHA6Ly8xLmJwLmJsb2dzcG90LmNvbS8tVFByZmh4YllwRFkvVWgzUmVmemswMkkvQUFBQUFBQUFMdzgvNXNVSjBVVUdZdXcvczE2MDAvTmV3K1lvcmsraW4rVGhlKzE5NjAncystKzcwJ3MrKDIpLmpwZztiYWNrZ3JvdW5kLXNpemU6Y292ZXI7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O3BhZGRpbmctbGVmdDowcHg7cGFkZGluZy1yaWdodDowcHg7cGFkZGluZy10b3A6MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O3RleHQtYWxpZ246Y2VudGVyOyJ9LCJjb21wb25lbnRzIjpbeyJ0YWdOYW1lIjoibWotY29sdW1uIiwidHlwZSI6Im1qLWNvbHVtbiIsInN0eWxlIjp7InZlcnRpY2FsLWFsaWduIjoidG9wIn0sImF0dHJpYnV0ZXMiOnsidmVydGljYWwtYWxpZ24iOiJ0b3AiLCJzdHlsZSI6InZlcnRpY2FsLWFsaWduOnRvcDsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLXRleHQiLCJ0eXBlIjoibWotdGV4dCIsInN0eWxlIjp7ImNzcy1jbGFzcyI6InNsb2dhbiIsImFsaWduIjoiY2VudGVyIiwiY29sb3IiOiIjZmZmIiwiZm9udC1zaXplIjoiNDBweCIsImZvbnQtZmFtaWx5IjoiSGVsdmV0aWNhIE5ldWUiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJsaW5lLWhlaWdodCI6IjIycHgifSwiYXR0cmlidXRlcyI6eyJjc3MtY2xhc3MiOiJzbG9nYW4iLCJhbGlnbiI6ImNlbnRlciIsImNvbG9yIjoiI2ZmZiIsImZvbnQtc2l6ZSI6IjQwcHgiLCJmb250LWZhbWlseSI6IkhlbHZldGljYSBOZXVlIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwibGluZS1oZWlnaHQiOiIyMnB4Iiwic3R5bGUiOiJjc3MtY2xhc3M6c2xvZ2FuO2FsaWduOmNlbnRlcjtjb2xvcjojZmZmO2ZvbnQtc2l6ZTo0MHB4O2ZvbnQtZmFtaWx5OkhlbHZldGljYSBOZXVlO3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDtwYWRkaW5nLXJpZ2h0OjI1cHg7cGFkZGluZy1sZWZ0OjI1cHg7bGluZS1oZWlnaHQ6MjJweDsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IlNsb2dhbiBoZXJlIn1dfV19XX0seyJ0eXBlIjoiY29tbWVudCIsImNvbnRlbnQiOiIgSW50cm8gdGV4dCAifSx7InRhZ05hbWUiOiJtai13cmFwcGVyIiwidHlwZSI6Im1qLXdyYXBwZXIiLCJzdHlsZSI6eyJiYWNrZ3JvdW5kLWNvbG9yIjoiI2ZmZTlmNyIsInBhZGRpbmciOiIxMHB4In0sImF0dHJpYnV0ZXMiOnsiYmFja2dyb3VuZC1jb2xvciI6IiNmZmU5ZjciLCJwYWRkaW5nIjoiMTBweCIsInN0eWxlIjoiYmFja2dyb3VuZC1jb2xvcjojZmZlOWY3O3BhZGRpbmc6MTBweDsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLXNlY3Rpb24iLCJ0eXBlIjoibWotc2VjdGlvbiIsInN0eWxlIjp7ImJhY2tncm91bmQtY29sb3IiOiIjZWFlZmZhIiwicGFkZGluZy1sZWZ0IjoiMHB4IiwicGFkZGluZy1yaWdodCI6IjBweCIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInRleHQtYWxpZ24iOiJjZW50ZXIifSwiYXR0cmlidXRlcyI6eyJiYWNrZ3JvdW5kLWNvbG9yIjoiI2VhZWZmYSIsInBhZGRpbmctbGVmdCI6IjBweCIsInBhZGRpbmctcmlnaHQiOiIwcHgiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJ0ZXh0LWFsaWduIjoiY2VudGVyIiwic3R5bGUiOiJiYWNrZ3JvdW5kLWNvbG9yOiNlYWVmZmE7cGFkZGluZy1sZWZ0OjBweDtwYWRkaW5nLXJpZ2h0OjBweDtwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7dGV4dC1hbGlnbjpjZW50ZXI7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai1ncm91cCIsInR5cGUiOiJtai1ncm91cCIsInN0eWxlIjp7ImJhY2tncm91bmQtY29sb3IiOiIjZmZmYWRkIiwidmVydGljYWwtYWxpZ24iOiJ0b3AifSwiYXR0cmlidXRlcyI6eyJiYWNrZ3JvdW5kLWNvbG9yIjoiI2ZmZmFkZCIsInZlcnRpY2FsLWFsaWduIjoidG9wIiwic3R5bGUiOiJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZhZGQ7dmVydGljYWwtYWxpZ246dG9wOyJ9LCJjb21wb25lbnRzIjpbeyJ0YWdOYW1lIjoibWotY29sdW1uIiwidHlwZSI6Im1qLWNvbHVtbiIsInN0eWxlIjp7InZlcnRpY2FsLWFsaWduIjoidG9wIn0sImF0dHJpYnV0ZXMiOnsidmVydGljYWwtYWxpZ24iOiJ0b3AiLCJzdHlsZSI6InZlcnRpY2FsLWFsaWduOnRvcDsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLXRleHQiLCJ0eXBlIjoibWotdGV4dCIsInN0eWxlIjp7ImZvbnQtc3R5bGUiOiJpdGFsaWMiLCJmb250LXNpemUiOiIyMHB4IiwiZm9udC1mYW1pbHkiOiJIZWx2ZXRpY2EgTmV1ZSIsImNvbG9yIjoiIzYyNjI2MiIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImxpbmUtaGVpZ2h0IjoiMjJweCIsImFsaWduIjoibGVmdCJ9LCJhdHRyaWJ1dGVzIjp7ImZvbnQtc3R5bGUiOiJpdGFsaWMiLCJmb250LXNpemUiOiIyMHB4IiwiZm9udC1mYW1pbHkiOiJIZWx2ZXRpY2EgTmV1ZSIsImNvbG9yIjoiIzYyNjI2MiIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImxpbmUtaGVpZ2h0IjoiMjJweCIsImFsaWduIjoibGVmdCIsInN0eWxlIjoiZm9udC1zdHlsZTppdGFsaWM7Zm9udC1zaXplOjIwcHg7Zm9udC1mYW1pbHk6SGVsdmV0aWNhIE5ldWU7Y29sb3I6IzYyNjI2MjtwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7cGFkZGluZy1yaWdodDoyNXB4O3BhZGRpbmctbGVmdDoyNXB4O2xpbmUtaGVpZ2h0OjIycHg7YWxpZ246bGVmdDsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6Ik15IEF3ZXNvbWUgVGV4dCJ9XX0seyJ0YWdOYW1lIjoibWotdGV4dCIsInR5cGUiOiJtai10ZXh0Iiwic3R5bGUiOnsiY29sb3IiOiIjNTI1MjUyIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwiZm9udC1zaXplIjoiMTNweCIsImxpbmUtaGVpZ2h0IjoiMjJweCIsImFsaWduIjoibGVmdCJ9LCJhdHRyaWJ1dGVzIjp7ImNvbG9yIjoiIzUyNTI1MiIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJhbGlnbiI6ImxlZnQiLCJzdHlsZSI6ImNvbG9yOiM1MjUyNTI7cGFkZGluZy10b3A6MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O3BhZGRpbmctcmlnaHQ6MjVweDtwYWRkaW5nLWxlZnQ6MjVweDtmb250LXNpemU6MTNweDtsaW5lLWhlaWdodDoyMnB4O2FsaWduOmxlZnQ7In0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJ0ZXh0bm9kZSIsImNvbnRlbnQiOiJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gUHJvaW4gcnV0cnVtIGVuaW0gZWdldCBtYWduYSBlZmZpY2l0dXIsIGV1IHNlbXBlciBhdWd1ZSBzZW1wZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gQ3JhcyBpZCBkdWkgbGVjdHVzLiBWZXN0aWJ1bHVtIHNlZCBmaW5pYnVzIGxlY3R1cywgc2l0IGFtZXQgc3VzY2lwaXQgbmliaC4gUHJvaW4gbmVjXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vZG8gcHVydXMuIFNlZCBlZ2V0IG51bGxhIGVsaXQuIE51bGxhIGFsaXF1ZXQgbW9sbGlzIGZhdWNpYnVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9XX0seyJ0YWdOYW1lIjoibWotYnV0dG9uIiwidHlwZSI6Im1qLWJ1dHRvbiIsInN0eWxlIjp7ImJhY2tncm91bmQtY29sb3IiOiIjRjQ1RTQzIiwiaHJlZiI6IiMiLCJib3JkZXItcmFkaXVzIjoiM3B4IiwiZm9udC1zaXplIjoiMTNweCIsImZvbnQtd2VpZ2h0IjoiNDAwIiwiY29sb3IiOiIjZmZmZmZmIiwidmVydGljYWwtYWxpZ24iOiJtaWRkbGUiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciJ9LCJhdHRyaWJ1dGVzIjp7ImJhY2tncm91bmQtY29sb3IiOiIjRjQ1RTQzIiwiaHJlZiI6IiMiLCJib3JkZXItcmFkaXVzIjoiM3B4IiwiZm9udC1zaXplIjoiMTNweCIsImZvbnQtd2VpZ2h0IjoiNDAwIiwiY29sb3IiOiIjZmZmZmZmIiwidmVydGljYWwtYWxpZ24iOiJtaWRkbGUiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciIsInN0eWxlIjoiYmFja2dyb3VuZC1jb2xvcjojRjQ1RTQzO2hyZWY6Iztib3JkZXItcmFkaXVzOjNweDtmb250LXNpemU6MTNweDtmb250LXdlaWdodDo0MDA7Y29sb3I6I2ZmZmZmZjt2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7cGFkZGluZy10b3A6MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O3BhZGRpbmctcmlnaHQ6MjVweDtwYWRkaW5nLWxlZnQ6MjVweDthbGlnbjpjZW50ZXI7In0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJ0ZXh0bm9kZSIsImNvbnRlbnQiOiJMZWFybiBtb3JlIn1dfV19XX1dfV19LHsidHlwZSI6ImNvbW1lbnQiLCJjb250ZW50IjoiIFNpZGUgaW1hZ2UgIn0seyJ0YWdOYW1lIjoibWotc2VjdGlvbiIsInR5cGUiOiJtai1zZWN0aW9uIiwic3R5bGUiOnsiYmFja2dyb3VuZC1jb2xvciI6IndoaXRlIiwicGFkZGluZy1sZWZ0IjoiMHB4IiwicGFkZGluZy1yaWdodCI6IjBweCIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInRleHQtYWxpZ24iOiJjZW50ZXIifSwiYXR0cmlidXRlcyI6eyJiYWNrZ3JvdW5kLWNvbG9yIjoid2hpdGUiLCJwYWRkaW5nLWxlZnQiOiIwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMHB4IiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwidGV4dC1hbGlnbiI6ImNlbnRlciIsInN0eWxlIjoiYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTtwYWRkaW5nLWxlZnQ6MHB4O3BhZGRpbmctcmlnaHQ6MHB4O3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDt0ZXh0LWFsaWduOmNlbnRlcjsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLWNvbHVtbiIsInR5cGUiOiJtai1jb2x1bW4iLCJzdHlsZSI6eyJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCJ9LCJhdHRyaWJ1dGVzIjp7InZlcnRpY2FsLWFsaWduIjoidG9wIiwic3R5bGUiOiJ2ZXJ0aWNhbC1hbGlnbjp0b3A7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai1pbWFnZSIsInR5cGUiOiJtai1pbWFnZSIsInN0eWxlIjp7IndpZHRoIjoiMjAwcHgiLCJzcmMiOiJodHRwczovL2Rlc2lnbnNwZWxsLmZpbGVzLndvcmRwcmVzcy5jb20vMjAxMi8wMS9zY2lvbGluby1wYXJpcy1idy5qcGciLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciJ9LCJhdHRyaWJ1dGVzIjp7IndpZHRoIjoiMjAwcHgiLCJzcmMiOiJodHRwczovL2Rlc2lnbnNwZWxsLmZpbGVzLndvcmRwcmVzcy5jb20vMjAxMi8wMS9zY2lvbGluby1wYXJpcy1idy5qcGciLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciIsInN0eWxlIjoid2lkdGg6MjAwcHg7c3JjOmh0dHBzOi8vZGVzaWduc3BlbGwuZmlsZXMud29yZHByZXNzLmNvbS8yMDEyLzAxL3NjaW9saW5vLXBhcmlzLWJ3LmpwZztwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7cGFkZGluZy1yaWdodDoyNXB4O3BhZGRpbmctbGVmdDoyNXB4O2FsaWduOmNlbnRlcjsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9XX1dfSx7InRhZ05hbWUiOiJtai1jb2x1bW4iLCJ0eXBlIjoibWotY29sdW1uIiwic3R5bGUiOnsidmVydGljYWwtYWxpZ24iOiJ0b3AifSwiYXR0cmlidXRlcyI6eyJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCIsInN0eWxlIjoidmVydGljYWwtYWxpZ246dG9wOyJ9LCJjb21wb25lbnRzIjpbeyJ0YWdOYW1lIjoibWotdGV4dCIsInR5cGUiOiJtai10ZXh0Iiwic3R5bGUiOnsiZm9udC1zdHlsZSI6Iml0YWxpYyIsImZvbnQtc2l6ZSI6IjIwcHgiLCJmb250LWZhbWlseSI6IkhlbHZldGljYSBOZXVlIiwiY29sb3IiOiIjNjI2MjYyIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwibGluZS1oZWlnaHQiOiIyMnB4IiwiYWxpZ24iOiJsZWZ0In0sImF0dHJpYnV0ZXMiOnsiZm9udC1zdHlsZSI6Iml0YWxpYyIsImZvbnQtc2l6ZSI6IjIwcHgiLCJmb250LWZhbWlseSI6IkhlbHZldGljYSBOZXVlIiwiY29sb3IiOiIjNjI2MjYyIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwibGluZS1oZWlnaHQiOiIyMnB4IiwiYWxpZ24iOiJsZWZ0Iiwic3R5bGUiOiJmb250LXN0eWxlOml0YWxpYztmb250LXNpemU6MjBweDtmb250LWZhbWlseTpIZWx2ZXRpY2EgTmV1ZTtjb2xvcjojNjI2MjYyO3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDtwYWRkaW5nLXJpZ2h0OjI1cHg7cGFkZGluZy1sZWZ0OjI1cHg7bGluZS1oZWlnaHQ6MjJweDthbGlnbjpsZWZ0OyJ9LCJjb21wb25lbnRzIjpbeyJ0eXBlIjoidGV4dG5vZGUiLCJjb250ZW50IjoiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaW5kIGFtYXppbmcgcGxhY2VzIC4uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAifV19LHsidGFnTmFtZSI6Im1qLXRleHQiLCJ0eXBlIjoibWotdGV4dCIsInN0eWxlIjp7ImNvbG9yIjoiIzUyNTI1MiIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJhbGlnbiI6ImxlZnQifSwiYXR0cmlidXRlcyI6eyJjb2xvciI6IiM1MjUyNTIiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJmb250LXNpemUiOiIxM3B4IiwibGluZS1oZWlnaHQiOiIyMnB4IiwiYWxpZ24iOiJsZWZ0Iiwic3R5bGUiOiJjb2xvcjojNTI1MjUyO3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDtwYWRkaW5nLXJpZ2h0OjI1cHg7cGFkZGluZy1sZWZ0OjI1cHg7Zm9udC1zaXplOjEzcHg7bGluZS1oZWlnaHQ6MjJweDthbGlnbjpsZWZ0OyJ9LCJjb21wb25lbnRzIjpbeyJ0eXBlIjoidGV4dG5vZGUiLCJjb250ZW50IjoiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LiBQcm9pbiBydXRydW0gZW5pbSBlZ2V0IG1hZ25hIGVmZmljaXR1ciwgZXUgc2VtcGVyIGF1Z3VlIHNlbXBlci5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gQ3JhcyBpZCBkdWkgbGVjdHVzLiBWZXN0aWJ1bHVtIHNlZCBmaW5pYnVzIGxlY3R1cy4ifV19XX1dfSx7InRhZ05hbWUiOiJtai1zZWN0aW9uIiwidHlwZSI6Im1qLXNlY3Rpb24iLCJzdHlsZSI6eyJwYWRkaW5nLWxlZnQiOiIwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMHB4IiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwidGV4dC1hbGlnbiI6ImNlbnRlciJ9LCJhdHRyaWJ1dGVzIjp7InBhZGRpbmctbGVmdCI6IjBweCIsInBhZGRpbmctcmlnaHQiOiIwcHgiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJ0ZXh0LWFsaWduIjoiY2VudGVyIiwic3R5bGUiOiJwYWRkaW5nLWxlZnQ6MHB4O3BhZGRpbmctcmlnaHQ6MHB4O3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDt0ZXh0LWFsaWduOmNlbnRlcjsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLWNvbHVtbiIsInR5cGUiOiJtai1jb2x1bW4iLCJzdHlsZSI6eyJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCJ9LCJhdHRyaWJ1dGVzIjp7InZlcnRpY2FsLWFsaWduIjoidG9wIiwic3R5bGUiOiJ2ZXJ0aWNhbC1hbGlnbjp0b3A7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai10ZXh0IiwidHlwZSI6Im1qLXRleHQiLCJzdHlsZSI6eyJmb250LXN0eWxlIjoiaXRhbGljIiwiZm9udC1zaXplIjoiMjBweCIsImZvbnQtZmFtaWx5IjoiSGVsdmV0aWNhIE5ldWUiLCJjb2xvciI6IiM2MjYyNjIiLCJhbGlnbiI6ImNlbnRlciIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImxpbmUtaGVpZ2h0IjoiMjJweCJ9LCJhdHRyaWJ1dGVzIjp7ImZvbnQtc3R5bGUiOiJpdGFsaWMiLCJmb250LXNpemUiOiIyMHB4IiwiZm9udC1mYW1pbHkiOiJIZWx2ZXRpY2EgTmV1ZSIsImNvbG9yIjoiIzYyNjI2MiIsImFsaWduIjoiY2VudGVyIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwibGluZS1oZWlnaHQiOiIyMnB4Iiwic3R5bGUiOiJmb250LXN0eWxlOml0YWxpYztmb250LXNpemU6MjBweDtmb250LWZhbWlseTpIZWx2ZXRpY2EgTmV1ZTtjb2xvcjojNjI2MjYyO2FsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7cGFkZGluZy1yaWdodDoyNXB4O3BhZGRpbmctbGVmdDoyNXB4O2xpbmUtaGVpZ2h0OjIycHg7In0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJ0ZXh0bm9kZSIsImNvbnRlbnQiOiJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLiB3aXRoIHJlYWwtbGlmZSBpbWFnZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1dfV19XX0seyJ0YWdOYW1lIjoibWotcmF3IiwidHlwZSI6Im1qLXJhdyIsImNvbXBvbmVudHMiOlt7ImNsYXNzZXMiOlsiY29udGFpbmVyIl0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJpbWFnZSIsInJlc2l6YWJsZSI6eyJyYXRpb0RlZmF1bHQiOjF9LCJjbGFzc2VzIjpbIml0ZW0iXSwiYXR0cmlidXRlcyI6eyJzcmMiOiJodHRwczovL3NvdXJjZS51bnNwbGFzaC5jb20vcmFuZG9tLzIwMHgxNDE/cmFuZG9tIiwiYWx0IjoiRXhhbXBsZSBpbWFnZSJ9fSx7InR5cGUiOiJpbWFnZSIsInJlc2l6YWJsZSI6eyJyYXRpb0RlZmF1bHQiOjF9LCJjbGFzc2VzIjpbIml0ZW0iXSwiYXR0cmlidXRlcyI6eyJzcmMiOiJodHRwczovL3NvdXJjZS51bnNwbGFzaC5jb20vcmFuZG9tLzIwMHgxNDI/cmFuZG9tIiwiYWx0IjoiRXhhbXBsZSBpbWFnZSJ9fSx7InR5cGUiOiJpbWFnZSIsInJlc2l6YWJsZSI6eyJyYXRpb0RlZmF1bHQiOjF9LCJjbGFzc2VzIjpbIml0ZW0iXSwiYXR0cmlidXRlcyI6eyJzcmMiOiJodHRwczovL3NvdXJjZS51bnNwbGFzaC5jb20vcmFuZG9tLzIwMHgxNDM/cmFuZG9tIiwiYWx0IjoiRXhhbXBsZSBpbWFnZSJ9fSx7InR5cGUiOiJpbWFnZSIsInJlc2l6YWJsZSI6eyJyYXRpb0RlZmF1bHQiOjF9LCJjbGFzc2VzIjpbIml0ZW0iXSwiYXR0cmlidXRlcyI6eyJzcmMiOiJodHRwczovL3NvdXJjZS51bnNwbGFzaC5jb20vcmFuZG9tLzIwMHgxNDQ/cmFuZG9tIiwiYWx0IjoiRXhhbXBsZSBpbWFnZSJ9fSx7InR5cGUiOiJpbWFnZSIsInJlc2l6YWJsZSI6eyJyYXRpb0RlZmF1bHQiOjF9LCJjbGFzc2VzIjpbIml0ZW0iXSwiYXR0cmlidXRlcyI6eyJzcmMiOiJodHRwczovL3NvdXJjZS51bnNwbGFzaC5jb20vcmFuZG9tLzIwMHgxNDU/cmFuZG9tIiwiYWx0IjoiRXhhbXBsZSBpbWFnZSJ9fSx7InR5cGUiOiJpbWFnZSIsInJlc2l6YWJsZSI6eyJyYXRpb0RlZmF1bHQiOjF9LCJjbGFzc2VzIjpbIml0ZW0iXSwiYXR0cmlidXRlcyI6eyJzcmMiOiJodHRwczovL3NvdXJjZS51bnNwbGFzaC5jb20vcmFuZG9tLzIwMHgxNDY/cmFuZG9tIiwiYWx0IjoiRXhhbXBsZSBpbWFnZSJ9fV19XX0seyJ0eXBlIjoiY29tbWVudCIsImNvbnRlbnQiOiIgSWNvbnMgIn0seyJ0YWdOYW1lIjoibWotc2VjdGlvbiIsInR5cGUiOiJtai1zZWN0aW9uIiwic3R5bGUiOnsiYmFja2dyb3VuZC1jb2xvciI6IiNmYmZiZmIiLCJwYWRkaW5nLWxlZnQiOiIwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMHB4IiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwidGV4dC1hbGlnbiI6ImNlbnRlciJ9LCJhdHRyaWJ1dGVzIjp7ImJhY2tncm91bmQtY29sb3IiOiIjZmJmYmZiIiwicGFkZGluZy1sZWZ0IjoiMHB4IiwicGFkZGluZy1yaWdodCI6IjBweCIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInRleHQtYWxpZ24iOiJjZW50ZXIiLCJzdHlsZSI6ImJhY2tncm91bmQtY29sb3I6I2ZiZmJmYjtwYWRkaW5nLWxlZnQ6MHB4O3BhZGRpbmctcmlnaHQ6MHB4O3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDt0ZXh0LWFsaWduOmNlbnRlcjsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLWNvbHVtbiIsInR5cGUiOiJtai1jb2x1bW4iLCJzdHlsZSI6eyJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCJ9LCJhdHRyaWJ1dGVzIjp7InZlcnRpY2FsLWFsaWduIjoidG9wIiwic3R5bGUiOiJ2ZXJ0aWNhbC1hbGlnbjp0b3A7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai1pbWFnZSIsInR5cGUiOiJtai1pbWFnZSIsInN0eWxlIjp7IndpZHRoIjoiMTAwcHgiLCJzcmMiOiJodHRwOi8vMTkxbi5tai5hbS9pbWcvMTkxbi8zcy94MGwucG5nIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwiYWxpZ24iOiJjZW50ZXIifSwiYXR0cmlidXRlcyI6eyJ3aWR0aCI6IjEwMHB4Iiwic3JjIjoiaHR0cDovLzE5MW4ubWouYW0vaW1nLzE5MW4vM3MveDBsLnBuZyIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImFsaWduIjoiY2VudGVyIiwic3R5bGUiOiJ3aWR0aDoxMDBweDtzcmM6aHR0cDovLzE5MW4ubWouYW0vaW1nLzE5MW4vM3MveDBsLnBuZztwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7cGFkZGluZy1yaWdodDoyNXB4O3BhZGRpbmctbGVmdDoyNXB4O2FsaWduOmNlbnRlcjsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9XX1dfSx7InRhZ05hbWUiOiJtai1jb2x1bW4iLCJ0eXBlIjoibWotY29sdW1uIiwic3R5bGUiOnsidmVydGljYWwtYWxpZ24iOiJ0b3AifSwiYXR0cmlidXRlcyI6eyJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCIsInN0eWxlIjoidmVydGljYWwtYWxpZ246dG9wOyJ9LCJjb21wb25lbnRzIjpbeyJ0YWdOYW1lIjoibWotaW1hZ2UiLCJ0eXBlIjoibWotaW1hZ2UiLCJzdHlsZSI6eyJ3aWR0aCI6IjEwMHB4Iiwic3JjIjoiaHR0cDovLzE5MW4ubWouYW0vaW1nLzE5MW4vM3MveDAxLnBuZyIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInBhZGRpbmctcmlnaHQiOiIyNXB4IiwicGFkZGluZy1sZWZ0IjoiMjVweCIsImFsaWduIjoiY2VudGVyIn0sImF0dHJpYnV0ZXMiOnsid2lkdGgiOiIxMDBweCIsInNyYyI6Imh0dHA6Ly8xOTFuLm1qLmFtL2ltZy8xOTFuLzNzL3gwMS5wbmciLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciIsInN0eWxlIjoid2lkdGg6MTAwcHg7c3JjOmh0dHA6Ly8xOTFuLm1qLmFtL2ltZy8xOTFuLzNzL3gwMS5wbmc7cGFkZGluZy10b3A6MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O3BhZGRpbmctcmlnaHQ6MjVweDtwYWRkaW5nLWxlZnQ6MjVweDthbGlnbjpjZW50ZXI7In0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJ0ZXh0bm9kZSIsImNvbnRlbnQiOiJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAifV19XX0seyJ0YWdOYW1lIjoibWotY29sdW1uIiwidHlwZSI6Im1qLWNvbHVtbiIsInN0eWxlIjp7InZlcnRpY2FsLWFsaWduIjoidG9wIn0sImF0dHJpYnV0ZXMiOnsidmVydGljYWwtYWxpZ24iOiJ0b3AiLCJzdHlsZSI6InZlcnRpY2FsLWFsaWduOnRvcDsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLWltYWdlIiwidHlwZSI6Im1qLWltYWdlIiwic3R5bGUiOnsid2lkdGgiOiIxMDBweCIsInNyYyI6Imh0dHA6Ly8xOTFuLm1qLmFtL2ltZy8xOTFuLzNzL3gwcy5wbmciLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciJ9LCJhdHRyaWJ1dGVzIjp7IndpZHRoIjoiMTAwcHgiLCJzcmMiOiJodHRwOi8vMTkxbi5tai5hbS9pbWcvMTkxbi8zcy94MHMucG5nIiwicGFkZGluZy10b3AiOiIxMHB4IiwicGFkZGluZy1ib3R0b20iOiIxMHB4IiwicGFkZGluZy1yaWdodCI6IjI1cHgiLCJwYWRkaW5nLWxlZnQiOiIyNXB4IiwiYWxpZ24iOiJjZW50ZXIiLCJzdHlsZSI6IndpZHRoOjEwMHB4O3NyYzpodHRwOi8vMTkxbi5tai5hbS9pbWcvMTkxbi8zcy94MHMucG5nO3BhZGRpbmctdG9wOjEwcHg7cGFkZGluZy1ib3R0b206MTBweDtwYWRkaW5nLXJpZ2h0OjI1cHg7cGFkZGluZy1sZWZ0OjI1cHg7YWxpZ246Y2VudGVyOyJ9LCJjb21wb25lbnRzIjpbeyJ0eXBlIjoidGV4dG5vZGUiLCJjb250ZW50IjoiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1dfV19XX0seyJ0eXBlIjoiY29tbWVudCIsImNvbnRlbnQiOiIgRm9vdGVyICJ9LHsidGFnTmFtZSI6Im1qLXNlY3Rpb24iLCJ0eXBlIjoibWotc2VjdGlvbiIsInN0eWxlIjp7ImJhY2tncm91bmQtY29sb3IiOiIjZTdlN2U3IiwicGFkZGluZy1sZWZ0IjoiMHB4IiwicGFkZGluZy1yaWdodCI6IjBweCIsInBhZGRpbmctdG9wIjoiMTBweCIsInBhZGRpbmctYm90dG9tIjoiMTBweCIsInRleHQtYWxpZ24iOiJjZW50ZXIifSwiYXR0cmlidXRlcyI6eyJiYWNrZ3JvdW5kLWNvbG9yIjoiI2U3ZTdlNyIsInBhZGRpbmctbGVmdCI6IjBweCIsInBhZGRpbmctcmlnaHQiOiIwcHgiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJ0ZXh0LWFsaWduIjoiY2VudGVyIiwic3R5bGUiOiJiYWNrZ3JvdW5kLWNvbG9yOiNlN2U3ZTc7cGFkZGluZy1sZWZ0OjBweDtwYWRkaW5nLXJpZ2h0OjBweDtwYWRkaW5nLXRvcDoxMHB4O3BhZGRpbmctYm90dG9tOjEwcHg7dGV4dC1hbGlnbjpjZW50ZXI7In0sImNvbXBvbmVudHMiOlt7InRhZ05hbWUiOiJtai1jb2x1bW4iLCJ0eXBlIjoibWotY29sdW1uIiwic3R5bGUiOnsidmVydGljYWwtYWxpZ24iOiJ0b3AifSwiYXR0cmlidXRlcyI6eyJ2ZXJ0aWNhbC1hbGlnbiI6InRvcCIsInN0eWxlIjoidmVydGljYWwtYWxpZ246dG9wOyJ9LCJjb21wb25lbnRzIjpbeyJ0YWdOYW1lIjoibWotYnV0dG9uIiwidHlwZSI6Im1qLWJ1dHRvbiIsInN0eWxlIjp7ImhyZWYiOiIjIiwiYmFja2dyb3VuZC1jb2xvciI6IiM0MTQxNDEiLCJib3JkZXItcmFkaXVzIjoiM3B4IiwiZm9udC1zaXplIjoiMTNweCIsImZvbnQtd2VpZ2h0IjoiNDAwIiwiY29sb3IiOiIjZmZmZmZmIiwidmVydGljYWwtYWxpZ24iOiJtaWRkbGUiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciJ9LCJhdHRyaWJ1dGVzIjp7ImhyZWYiOiIjIiwiYmFja2dyb3VuZC1jb2xvciI6IiM0MTQxNDEiLCJib3JkZXItcmFkaXVzIjoiM3B4IiwiZm9udC1zaXplIjoiMTNweCIsImZvbnQtd2VpZ2h0IjoiNDAwIiwiY29sb3IiOiIjZmZmZmZmIiwidmVydGljYWwtYWxpZ24iOiJtaWRkbGUiLCJwYWRkaW5nLXRvcCI6IjEwcHgiLCJwYWRkaW5nLWJvdHRvbSI6IjEwcHgiLCJwYWRkaW5nLXJpZ2h0IjoiMjVweCIsInBhZGRpbmctbGVmdCI6IjI1cHgiLCJhbGlnbiI6ImNlbnRlciIsInN0eWxlIjoiaHJlZjojO2JhY2tncm91bmQtY29sb3I6IzQxNDE0MTtib3JkZXItcmFkaXVzOjNweDtmb250LXNpemU6MTNweDtmb250LXdlaWdodDo0MDA7Y29sb3I6I2ZmZmZmZjt2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7cGFkZGluZy10b3A6MTBweDtwYWRkaW5nLWJvdHRvbToxMHB4O3BhZGRpbmctcmlnaHQ6MjVweDtwYWRkaW5nLWxlZnQ6MjVweDthbGlnbjpjZW50ZXI7In0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJ0ZXh0bm9kZSIsImNvbnRlbnQiOiJIZWxsbyBUaGVyZSEifV19LHsidGFnTmFtZSI6Im1qLXNvY2lhbCIsInR5cGUiOiJtai1zb2NpYWwiLCJzdHlsZSI6eyJmb250LXNpemUiOiIxNXB4IiwiaWNvbi1zaXplIjoiMzBweCIsIm1vZGUiOiJob3Jpem9udGFsIiwiYWxpZ24iOiJjZW50ZXIiLCJsaW5lLWhlaWdodCI6IjIycHgifSwiYXR0cmlidXRlcyI6eyJmb250LXNpemUiOiIxNXB4IiwiaWNvbi1zaXplIjoiMzBweCIsIm1vZGUiOiJob3Jpem9udGFsIiwiYWxpZ24iOiJjZW50ZXIiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJzdHlsZSI6ImZvbnQtc2l6ZToxNXB4O2ljb24tc2l6ZTozMHB4O21vZGU6aG9yaXpvbnRhbDthbGlnbjpjZW50ZXI7bGluZS1oZWlnaHQ6MjJweDsifSwiY29tcG9uZW50cyI6W3sidGFnTmFtZSI6Im1qLXNvY2lhbC1lbGVtZW50IiwidHlwZSI6Im1qLXNvY2lhbC1lbGVtZW50Iiwic3R5bGUiOnsibmFtZSI6ImZhY2Vib29rIiwiaHJlZiI6Imh0dHBzOi8vbWptbC5pby8iLCJhbGlnbiI6ImNlbnRlciIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJ2ZXJ0aWNhbC1hbGlnbiI6Im1pZGRsZSJ9LCJhdHRyaWJ1dGVzIjp7Im5hbWUiOiJmYWNlYm9vayIsImhyZWYiOiJodHRwczovL21qbWwuaW8vIiwiYWxpZ24iOiJjZW50ZXIiLCJmb250LXNpemUiOiIxM3B4IiwibGluZS1oZWlnaHQiOiIyMnB4IiwidmVydGljYWwtYWxpZ24iOiJtaWRkbGUiLCJzdHlsZSI6Im5hbWU6ZmFjZWJvb2s7aHJlZjpodHRwczovL21qbWwuaW8vO2FsaWduOmNlbnRlcjtmb250LXNpemU6MTNweDtsaW5lLWhlaWdodDoyMnB4O3ZlcnRpY2FsLWFsaWduOm1pZGRsZTsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhY2Vib29rXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAifV19LHsidGFnTmFtZSI6Im1qLXNvY2lhbC1lbGVtZW50IiwidHlwZSI6Im1qLXNvY2lhbC1lbGVtZW50Iiwic3R5bGUiOnsibmFtZSI6Imdvb2dsZSIsImhyZWYiOiJodHRwczovL21qbWwuaW8vIiwiYWxpZ24iOiJjZW50ZXIiLCJmb250LXNpemUiOiIxM3B4IiwibGluZS1oZWlnaHQiOiIyMnB4IiwidmVydGljYWwtYWxpZ24iOiJtaWRkbGUifSwiYXR0cmlidXRlcyI6eyJuYW1lIjoiZ29vZ2xlIiwiaHJlZiI6Imh0dHBzOi8vbWptbC5pby8iLCJhbGlnbiI6ImNlbnRlciIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJ2ZXJ0aWNhbC1hbGlnbiI6Im1pZGRsZSIsInN0eWxlIjoibmFtZTpnb29nbGU7aHJlZjpodHRwczovL21qbWwuaW8vO2FsaWduOmNlbnRlcjtmb250LXNpemU6MTNweDtsaW5lLWhlaWdodDoyMnB4O3ZlcnRpY2FsLWFsaWduOm1pZGRsZTsifSwiY29tcG9uZW50cyI6W3sidHlwZSI6InRleHRub2RlIiwiY29udGVudCI6IlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdvb2dsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1dfSx7InRhZ05hbWUiOiJtai1zb2NpYWwtZWxlbWVudCIsInR5cGUiOiJtai1zb2NpYWwtZWxlbWVudCIsInN0eWxlIjp7Im5hbWUiOiJ0d2l0dGVyIiwiaHJlZiI6Imh0dHBzOi8vbWptbC5pby8iLCJhbGlnbiI6ImNlbnRlciIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJ2ZXJ0aWNhbC1hbGlnbiI6Im1pZGRsZSJ9LCJhdHRyaWJ1dGVzIjp7Im5hbWUiOiJ0d2l0dGVyIiwiaHJlZiI6Imh0dHBzOi8vbWptbC5pby8iLCJhbGlnbiI6ImNlbnRlciIsImZvbnQtc2l6ZSI6IjEzcHgiLCJsaW5lLWhlaWdodCI6IjIycHgiLCJ2ZXJ0aWNhbC1hbGlnbiI6Im1pZGRsZSIsInN0eWxlIjoibmFtZTp0d2l0dGVyO2hyZWY6aHR0cHM6Ly9tam1sLmlvLzthbGlnbjpjZW50ZXI7Zm9udC1zaXplOjEzcHg7bGluZS1oZWlnaHQ6MjJweDt2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7In0sImNvbXBvbmVudHMiOlt7InR5cGUiOiJ0ZXh0bm9kZSIsImNvbnRlbnQiOiJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUd2l0dGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAifV19XX1dfV19LHsidHlwZSI6ImNvbW1lbnQiLCJjb250ZW50IjoiIEZvb3RlciAifV19XX1dfSwiaWQiOiI3cERSTzdjS1R3V2hXSXJ4In1dLCJpZCI6IjU2czJHNlVkVVhHMlpidngifV19]]></fileData>
<fileData><![CDATA[{"assets":[],"styles":[{"selectors":[],"selectorsAdd":"#outlook a","style":{"padding-top":"0px","padding-right":"0px","padding-bottom":"0px","padding-left":"0px"}},{"selectors":[],"selectorsAdd":"body","style":{"margin-top":"0px","margin-right":"0px","margin-bottom":"0px","margin-left":"0px","padding-top":"0px","padding-right":"0px","padding-bottom":"0px","padding-left":"0px","text-size-adjust":"100%"}},{"selectors":[],"selectorsAdd":"table, td","style":{"border-collapse":"collapse"}},{"selectors":[],"selectorsAdd":"img","style":{"border-top-width":"0px","border-right-width":"0px","border-bottom-width":"0px","border-left-width":"0px","border-top-style":"initial","border-right-style":"initial","border-bottom-style":"initial","border-left-style":"initial","border-top-color":"initial","border-right-color":"initial","border-bottom-color":"initial","border-left-color":"initial","border-image-source":"initial","border-image-slice":"initial","border-image-width":"initial","border-image-outset":"initial","border-image-repeat":"initial","height":"auto","line-height":"100%","outline-color":"initial","outline-style":"none","outline-width":"initial","text-decoration-line":"none","text-decoration-thickness":"initial","text-decoration-style":"initial","text-decoration-color":"initial"}},{"selectors":[],"selectorsAdd":"p","style":{"display":"block","margin-top":"13px","margin-right":"0px","margin-bottom":"13px","margin-left":"0px"}},{"selectors":["mj-column-per-100"],"style":{"width":"100% !important","max-width":"100%"},"mediaText":"only screen and (min-width: 480px)","atRuleType":"media"},{"selectors":[],"selectorsAdd":".moz-text-html .mj-column-per-100","style":{"width":"100% !important","max-width":"100%"}},{"selectors":["mj-column-per-50"],"style":{"width":"50% !important","max-width":"50%"},"mediaText":"only screen and (min-width: 480px)","atRuleType":"media"},{"selectors":[],"selectorsAdd":".moz-text-html .mj-column-per-50","style":{"width":"50% !important","max-width":"50%"}},{"selectors":["mj-column-per-33-333333333333336"],"style":{"width":"33.3333% !important","max-width":"33.3333%"},"mediaText":"only screen and (min-width: 480px)","atRuleType":"media"},{"selectors":[],"selectorsAdd":".moz-text-html .mj-column-per-33-333333333333336","style":{"width":"33.3333% !important","max-width":"33.3333%"}}],"pages":[{"frames":[{"component":{"type":"wrapper","stylable":["background","background-color","background-image","background-repeat","background-attachment","background-position","background-size"],"components":[{"tagName":"mjml","type":"mjml","components":[{"tagName":"mj-head","type":"mj-head","components":[{"tagName":"mj-font","type":"mj-font","style":{"name":"Barlow","href":"https://fonts.googleapis.com/css?family=Barlow"},"attributes":{"name":"Barlow","href":"https://fonts.googleapis.com/css?family=Barlow","style":"name:Barlow;href:https://fonts.googleapis.com/css?family=Barlow;"}},{"tagName":"mj-style","type":"mj-style","components":[{"type":"textnode","content":"\n .slogan {\n background: #000;\n }\n "}]}]},{"tagName":"mj-body","type":"mj-body","style":{"width":"600px"},"attributes":{"width":"600px","style":"width:600px;"},"components":[{"type":"comment","content":" Company Header "},{"tagName":"mj-section","type":"mj-section","style":{"background-color":"#f0f0f0","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"background-color":"#f0f0f0","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"background-color:#f0f0f0;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"border":"10px solid #F45E43","vertical-align":"top"},"attributes":{"border":"10px solid #F45E43","vertical-align":"top","style":"border:10px solid #F45E43;vertical-align:top;"},"components":[{"tagName":"mj-text","type":"mj-text","style":{"font-family":"Barlow","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","font-size":"13px","line-height":"22px","align":"left"},"attributes":{"font-family":"Barlow","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","font-size":"13px","line-height":"22px","align":"left","style":"font-family:Barlow;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;font-size:13px;line-height:22px;align:left;"},"components":[{"type":"textnode","content":"A first line of text"}]},{"tagName":"mj-spacer","type":"mj-spacer","style":{"height":"50px"},"attributes":{"height":"50px","style":"height:50px;"},"components":[{"type":"textnode","content":"\n "}]}]}]},{"type":"comment","content":" Image Header "},{"tagName":"mj-section","type":"mj-section","style":{"background-url":"http://1.bp.blogspot.com/-TPrfhxbYpDY/Uh3Refzk02I/AAAAAAAALw8/5sUJ0UUGYuw/s1600/New+York+in+The+1960's+-+70's+(2).jpg","background-size":"cover","background-repeat":"no-repeat","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"background-url":"http://1.bp.blogspot.com/-TPrfhxbYpDY/Uh3Refzk02I/AAAAAAAALw8/5sUJ0UUGYuw/s1600/New+York+in+The+1960's+-+70's+(2).jpg","background-size":"cover","background-repeat":"no-repeat","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"background-url:http://1.bp.blogspot.com/-TPrfhxbYpDY/Uh3Refzk02I/AAAAAAAALw8/5sUJ0UUGYuw/s1600/New+York+in+The+1960's+-+70's+(2).jpg;background-size:cover;background-repeat:no-repeat;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-text","type":"mj-text","style":{"css-class":"slogan","align":"center","color":"#fff","font-size":"40px","font-family":"Helvetica Neue","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px"},"attributes":{"css-class":"slogan","align":"center","color":"#fff","font-size":"40px","font-family":"Helvetica Neue","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px","style":"css-class:slogan;align:center;color:#fff;font-size:40px;font-family:Helvetica Neue;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;line-height:22px;"},"components":[{"type":"textnode","content":"Slogan here"}]}]}]},{"type":"comment","content":" Intro text "},{"tagName":"mj-wrapper","type":"mj-wrapper","style":{"background-color":"#ffe9f7","padding":"10px"},"attributes":{"background-color":"#ffe9f7","padding":"10px","style":"background-color:#ffe9f7;padding:10px;"},"components":[{"tagName":"mj-section","type":"mj-section","style":{"background-color":"#eaeffa","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"background-color":"#eaeffa","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"background-color:#eaeffa;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-group","type":"mj-group","style":{"background-color":"#fffadd","vertical-align":"top"},"attributes":{"background-color":"#fffadd","vertical-align":"top","style":"background-color:#fffadd;vertical-align:top;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-text","type":"mj-text","style":{"font-style":"italic","font-size":"20px","font-family":"Helvetica Neue","color":"#626262","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px","align":"left"},"attributes":{"font-style":"italic","font-size":"20px","font-family":"Helvetica Neue","color":"#626262","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px","align":"left","style":"font-style:italic;font-size:20px;font-family:Helvetica Neue;color:#626262;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;line-height:22px;align:left;"},"components":[{"type":"textnode","content":"My Awesome Text"}]},{"tagName":"mj-text","type":"mj-text","style":{"color":"#525252","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","font-size":"13px","line-height":"22px","align":"left"},"attributes":{"color":"#525252","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","font-size":"13px","line-height":"22px","align":"left","style":"color:#525252;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;font-size:13px;line-height:22px;align:left;"},"components":[{"type":"textnode","content":"\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper.\n Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus, sit amet suscipit nibh. Proin nec\n commodo purus. Sed eget nulla elit. Nulla aliquet mollis faucibus.\n "}]},{"tagName":"mj-button","type":"mj-button","style":{"background-color":"#F45E43","href":"#","border-radius":"3px","font-size":"13px","font-weight":"400","color":"#ffffff","vertical-align":"middle","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center"},"attributes":{"background-color":"#F45E43","href":"#","border-radius":"3px","font-size":"13px","font-weight":"400","color":"#ffffff","vertical-align":"middle","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center","style":"background-color:#F45E43;href:#;border-radius:3px;font-size:13px;font-weight:400;color:#ffffff;vertical-align:middle;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;align:center;"},"components":[{"type":"textnode","content":"Learn more"}]}]}]}]}]},{"type":"comment","content":" Side image "},{"tagName":"mj-section","type":"mj-section","style":{"background-color":"white","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"background-color":"white","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"background-color:white;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-image","type":"mj-image","style":{"width":"200px","src":"https://designspell.files.wordpress.com/2012/01/sciolino-paris-bw.jpg","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center"},"attributes":{"width":"200px","src":"https://designspell.files.wordpress.com/2012/01/sciolino-paris-bw.jpg","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center","style":"width:200px;src:https://designspell.files.wordpress.com/2012/01/sciolino-paris-bw.jpg;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;align:center;"},"components":[{"type":"textnode","content":"\n "}]}]},{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-text","type":"mj-text","style":{"font-style":"italic","font-size":"20px","font-family":"Helvetica Neue","color":"#626262","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px","align":"left"},"attributes":{"font-style":"italic","font-size":"20px","font-family":"Helvetica Neue","color":"#626262","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px","align":"left","style":"font-style:italic;font-size:20px;font-family:Helvetica Neue;color:#626262;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;line-height:22px;align:left;"},"components":[{"type":"textnode","content":"\n Find amazing places ...\n "}]},{"tagName":"mj-text","type":"mj-text","style":{"color":"#525252","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","font-size":"13px","line-height":"22px","align":"left"},"attributes":{"color":"#525252","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","font-size":"13px","line-height":"22px","align":"left","style":"color:#525252;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;font-size:13px;line-height:22px;align:left;"},"components":[{"type":"textnode","content":"\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum enim eget magna efficitur, eu semper augue semper.\n Aliquam erat volutpat. Cras id dui lectus. Vestibulum sed finibus lectus."}]}]}]},{"tagName":"mj-section","type":"mj-section","style":{"padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-text","type":"mj-text","style":{"font-style":"italic","font-size":"20px","font-family":"Helvetica Neue","color":"#626262","align":"center","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px"},"attributes":{"font-style":"italic","font-size":"20px","font-family":"Helvetica Neue","color":"#626262","align":"center","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","line-height":"22px","style":"font-style:italic;font-size:20px;font-family:Helvetica Neue;color:#626262;align:center;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;line-height:22px;"},"components":[{"type":"textnode","content":"\n ... with real-life images\n "}]}]}]},{"tagName":"mj-raw","type":"mj-raw","components":[{"classes":["container"],"components":[{"type":"image","resizable":{"ratioDefault":1},"classes":["item"],"attributes":{"src":"https://source.unsplash.com/random/200x141?random","alt":"Example image"}},{"type":"image","resizable":{"ratioDefault":1},"classes":["item"],"attributes":{"src":"https://source.unsplash.com/random/200x142?random","alt":"Example image"}},{"type":"image","resizable":{"ratioDefault":1},"classes":["item"],"attributes":{"src":"https://source.unsplash.com/random/200x143?random","alt":"Example image"}},{"type":"image","resizable":{"ratioDefault":1},"classes":["item"],"attributes":{"src":"https://source.unsplash.com/random/200x144?random","alt":"Example image"}},{"type":"image","resizable":{"ratioDefault":1},"classes":["item"],"attributes":{"src":"https://source.unsplash.com/random/200x145?random","alt":"Example image"}},{"type":"image","resizable":{"ratioDefault":1},"classes":["item"],"attributes":{"src":"https://source.unsplash.com/random/200x146?random","alt":"Example image"}}]}]},{"type":"comment","content":" Icons "},{"tagName":"mj-section","type":"mj-section","style":{"background-color":"#fbfbfb","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"background-color":"#fbfbfb","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"background-color:#fbfbfb;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-image","type":"mj-image","style":{"width":"100px","src":"http://191n.mj.am/img/191n/3s/x0l.png","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center"},"attributes":{"width":"100px","src":"http://191n.mj.am/img/191n/3s/x0l.png","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center","style":"width:100px;src:http://191n.mj.am/img/191n/3s/x0l.png;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;align:center;"},"components":[{"type":"textnode","content":"\n "}]}]},{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-image","type":"mj-image","style":{"width":"100px","src":"http://191n.mj.am/img/191n/3s/x01.png","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center"},"attributes":{"width":"100px","src":"http://191n.mj.am/img/191n/3s/x01.png","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center","style":"width:100px;src:http://191n.mj.am/img/191n/3s/x01.png;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;align:center;"},"components":[{"type":"textnode","content":"\n "}]}]},{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-image","type":"mj-image","style":{"width":"100px","src":"http://191n.mj.am/img/191n/3s/x0s.png","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center"},"attributes":{"width":"100px","src":"http://191n.mj.am/img/191n/3s/x0s.png","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center","style":"width:100px;src:http://191n.mj.am/img/191n/3s/x0s.png;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;align:center;"},"components":[{"type":"textnode","content":"\n "}]}]}]},{"type":"comment","content":" Footer "},{"tagName":"mj-section","type":"mj-section","style":{"background-color":"#e7e7e7","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center"},"attributes":{"background-color":"#e7e7e7","padding-left":"0px","padding-right":"0px","padding-top":"10px","padding-bottom":"10px","text-align":"center","style":"background-color:#e7e7e7;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;text-align:center;"},"components":[{"tagName":"mj-column","type":"mj-column","style":{"vertical-align":"top"},"attributes":{"vertical-align":"top","style":"vertical-align:top;"},"components":[{"tagName":"mj-button","type":"mj-button","style":{"href":"#","background-color":"#414141","border-radius":"3px","font-size":"13px","font-weight":"400","color":"#ffffff","vertical-align":"middle","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center"},"attributes":{"href":"#","background-color":"#414141","border-radius":"3px","font-size":"13px","font-weight":"400","color":"#ffffff","vertical-align":"middle","padding-top":"10px","padding-bottom":"10px","padding-right":"25px","padding-left":"25px","align":"center","style":"href:#;background-color:#414141;border-radius:3px;font-size:13px;font-weight:400;color:#ffffff;vertical-align:middle;padding-top:10px;padding-bottom:10px;padding-right:25px;padding-left:25px;align:center;"},"components":[{"type":"textnode","content":"Hello There!"}]},{"tagName":"mj-social","type":"mj-social","style":{"font-size":"15px","icon-size":"30px","mode":"horizontal","align":"center","line-height":"22px"},"attributes":{"font-size":"15px","icon-size":"30px","mode":"horizontal","align":"center","line-height":"22px","style":"font-size:15px;icon-size:30px;mode:horizontal;align:center;line-height:22px;"},"components":[{"tagName":"mj-social-element","type":"mj-social-element","style":{"name":"facebook","href":"https://mjml.io/","align":"center","font-size":"13px","line-height":"22px","vertical-align":"middle"},"attributes":{"name":"facebook","href":"https://mjml.io/","align":"center","font-size":"13px","line-height":"22px","vertical-align":"middle","style":"name:facebook;href:https://mjml.io/;align:center;font-size:13px;line-height:22px;vertical-align:middle;"},"components":[{"type":"textnode","content":"\n Facebook\n "}]},{"tagName":"mj-social-element","type":"mj-social-element","style":{"name":"google","href":"https://mjml.io/","align":"center","font-size":"13px","line-height":"22px","vertical-align":"middle"},"attributes":{"name":"google","href":"https://mjml.io/","align":"center","font-size":"13px","line-height":"22px","vertical-align":"middle","style":"name:google;href:https://mjml.io/;align:center;font-size:13px;line-height:22px;vertical-align:middle;"},"components":[{"type":"textnode","content":"\n Google\n "}]},{"tagName":"mj-social-element","type":"mj-social-element","style":{"name":"twitter","href":"https://mjml.io/","align":"center","font-size":"13px","line-height":"22px","vertical-align":"middle"},"attributes":{"name":"twitter","href":"https://mjml.io/","align":"center","font-size":"13px","line-height":"22px","vertical-align":"middle","style":"name:twitter;href:https://mjml.io/;align:center;font-size:13px;line-height:22px;vertical-align:middle;"},"components":[{"type":"textnode","content":"\n Twitter\n "}]}]}]}]},{"type":"comment","content":" Footer "}]}]}]},"id":"7pDRO7cKTwWhWIrx"}],"id":"56s2G6UdUXG2Zbvx"}]}]]></fileData>
</file>
</dbResources>
<!-- ========= Service Jobs -->
<moqui.service.job.ServiceJob jobName="remove_ExcessMjmlEmailResourceHistories" description="Remove any excess mjml resource histories for email templates"
serviceName="mjml.MjmlServices.remove#ExcessMjmlEmailResourceHistories" cronExpression="0 0 * * * ?" paused="N"
transactionTimeout="3600"/>
</entity-facade-xml>
......
......@@ -16,7 +16,9 @@ along with this software (see the LICENSE.md file). If not, see
<extend-entity entity-name="EmailTemplate" package="moqui.basic.email">
<field name="grapesLocation" type="text-medium"/>
<field name="grapesPublishedVersionName" type="text-short"/>
<field name="htmlLocation" type="text-medium"/>
<field name="htmlPublishedVersionName" type="text-short"/>
</extend-entity>
<view-entity entity-name="ProductStoreEmailDetail" package="mantle.product.store">
<member-entity entity-alias="PSE" entity-name="mantle.product.store.ProductStoreEmail"/>
......
JAR files go in this directory and are picked up automatically by Moqui Framework based on the convention of the directory name 'lib'.
The build.gradle file uses this directory as the target for the built jar file, and deletes the built jar file as part of the clean task.
......@@ -69,17 +69,6 @@ along with this software (see the LICENSE.md file). If not, see
</mj-column>
</mj-section>
<!-- Image Header -->
<mj-section background-url="http://1.bp.blogspot.com/-TPrfhxbYpDY/Uh3Refzk02I/AAAAAAAALw8/5sUJ0UUGYuw/s1600/New+York+in+The+1960's+-+70's+(2).jpg"
background-size="cover" background-repeat="no-repeat">
<mj-column>
<mj-text css-class="slogan" align="center" color="#fff" font-size="40px" font-family="Helvetica Neue">Slogan here</mj-text>
<mj-button background-color="#F63A4D" href="#">
Promotion
</mj-button>
</mj-column>
</mj-section>
<!-- Intro text -->
<mj-wrapper background-color="#ffe9f7" padding="10px">
<mj-section background-color="#eaeffa">
......@@ -100,9 +89,6 @@ along with this software (see the LICENSE.md file). If not, see
<!-- Side image -->
<mj-section background-color="white">
<mj-column>
<mj-image width="200px" src="https://designspell.files.wordpress.com/2012/01/sciolino-paris-bw.jpg" />
</mj-column>
<mj-column>
<mj-text font-style="italic" font-size="20px" font-family="Helvetica Neue" color="#626262">
Find amazing places ...
</mj-text>
......@@ -118,41 +104,19 @@ along with this software (see the LICENSE.md file). If not, see
</mj-text>
</mj-column>
</mj-section>
<mj-raw>
<div class="container">
<img class="item" src="https://source.unsplash.com/random/200x141?random" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/200x142?random" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/200x143?random" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/200x144?random" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/200x145?random" alt="Example image">
<img class="item" src="https://source.unsplash.com/random/200x146?random" alt="Example image">
</div>
</mj-raw>
<!-- Icons -->
<mj-section background-color="#fbfbfb">
<mj-column>
<mj-image width="100px" src="http://191n.mj.am/img/191n/3s/x0l.png" />
</mj-column>
<mj-column>
<mj-image width="100px" src="http://191n.mj.am/img/191n/3s/x01.png" />
</mj-column>
<mj-column>
<mj-image width="100px" src="http://191n.mj.am/img/191n/3s/x0s.png" />
</mj-column>
</mj-section>
<!-- Footer -->
<mj-section background-color="#e7e7e7">
<mj-column>
<mj-button href="#">Hello There!</mj-button>
<mj-social font-size="15px" icon-size="30px" mode="horizontal">
<mj-social-element name="facebook" href="https://mjml.io/">
<mj-social-element name="facebook" href="https://moqui.org/">
Facebook
</mj-social-element>
<mj-social-element name="google" href="https://mjml.io/">
<mj-social-element name="google" href="https://moqui.org/">
Google
</mj-social-element>
<mj-social-element name="twitter" href="https://mjml.io/">
<mj-social-element name="twitter" href="https://moqui.org/">
Twitter
</mj-social-element>
</mj-social>
......@@ -180,15 +144,82 @@ along with this software (see the LICENSE.md file). If not, see
}
// console.log('response ', response)
window.htmlLocation = response.htmlLocation;
window.htmlVersionName = response.htmlVersionName;
window.htmlPublishedVersionName = response.htmlPublishedVersionName;
window.grapesLocation = response.grapesLocation;
const url = new URL(window.location.href)
url.searchParams.set('htmlLocation', response.htmlLocation);
url.searchParams.set('grapesLocation', response.grapesLocation);
window.history.pushState({}, '', url)
window.grapesVersionName = response.grapesVersionName;
window.grapesPublishedVersionName = response.grapesPublishedVersionName;
// const url = new URL(window.location.href)
// url.searchParams.set('htmlLocation', response.htmlLocation);
// url.searchParams.set('grapesLocation', response.grapesLocation);
// window.history.pushState({}, '', url)
window.moquiVars = response.moquiVars;
// console.log('init window.moquiVars ', window.moquiVars)
const projectData = JSON.parse(response.data);
// console.log('window.projectData ', window.projectData)
function moquiPlugin(editor) {
// Use the API: https://grapesjs.com/docs/api/
window.moquiPublishText = 'moqui-publish';
editor.Commands.add(window.moquiPublishText, () => {
const request = new XMLHttpRequest();
request.open("POST", "${baseLinkUrl}/rest/s1/moqui-mjml/mjml?emailTemplateId="+window.emailTemplateId, false); // `false` makes the request synchronous
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.setRequestHeader("X-CSRF-Token", document.getElementById('confMoquiSessionToken').value);
request.send(JSON.stringify({ publish:true, data: window.editor.getProjectData(), moquiVars:window.moquiVars, html:window.editor.runCommand('mjml-code-to-html')?.html }));
// console.log('request ', request)
if (request.status === 200) {
const result = JSON.parse(request.responseText);
window.htmlLocation = result.htmlLocation;
window.htmlVersionName = result.htmlVersionName;
window.htmlPublishedVersionName = result.htmlPublishedVersionName;
window.grapesLocation = result.grapesLocation;
window.grapesVersionName = result.grapesVersionName;
window.grapesPublishedVersionName = result.grapesPublishedVersionName;
if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
editor.Panels.addButton('options', window.moquiPublishButtonSettings);
} else {
editor.Panels.removeButton('options', window.moquiPublishText);
}
}
});
editor.on('storage:end:store', () => {
// console.log('Storage store request ended');
const request = new XMLHttpRequest();
request.open("GET", "${baseLinkUrl}/rest/s1/moqui-mjml/mjml/afterMjmlStore?emailTemplateId="+window.emailTemplateId, false); // `false` makes the request synchronous
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.setRequestHeader("X-CSRF-Token", document.getElementById('confMoquiSessionToken').value);
request.send();
if (request.status === 200) {
const result = JSON.parse(request.responseText);
window.htmlLocation = result.htmlLocation;
window.htmlVersionName = result.htmlVersionName;
window.htmlPublishedVersionName = result.htmlPublishedVersionName;
window.grapesLocation = result.grapesLocation;
window.grapesVersionName = result.grapesVersionName;
window.grapesPublishedVersionName = result.grapesPublishedVersionName;
if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
editor.Panels.addButton('options', window.moquiPublishButtonSettings);
} else {
editor.Panels.removeButton('options', window.moquiPublishText);
}
}
});
// Add Publish button
window.moquiPublishButtonSettings = {
id: window.moquiPublishText,
command: 'moqui-publish',
attributes: { title: 'publish' },
label: `<div style="background-color: #f45e43; color:#2c2e35; padding: 0px 10px; border: none; border-radius: 10px; cursor: pointer;">Publish</div>`,
};
if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
editor.Panels.addButton('options', window.moquiPublishButtonSettings);
}
}
window.editor = grapesjs.init({
projectData: projectData,
height: '100%',
......@@ -215,18 +246,28 @@ along with this software (see the LICENSE.md file). If not, see
// we have to properly update the body before the store and extract the
// project data from the response result.
onStore: data => {
return { id: window.grapesLocation, data, html:window.editor.runCommand('mjml-code-to-html')?.html }
return { id: window.grapesLocation, data, moquiVars:window.moquiVars, html:window.editor.runCommand('mjml-code-to-html')?.html }
},
onLoad: result => {
if (result.resourceId !== null) {
const url = new URL(window.location.href)
url.searchParams.set('grapesLocation', result.grapesLocation);
url.searchParams.set('htmlLocation', result.htmlLocation);
url.searchParams.set('emailTemplateId', result.emailTemplateId);
// url.searchParams.set('htmlLocation', result.htmlLocation);
// url.searchParams.set('emailTemplateId', result.emailTemplateId);
window.history.pushState({}, '', url)
window.grapesLocation = result.grapesLocation;
window.htmlLocation = result.htmlLocation;
window.htmlVersionName = result.htmlVersionName;
window.htmlPublishedVersionName = result.htmlPublishedVersionName;
window.grapesLocation = result.grapesLocation;
window.grapesVersionName = result.grapesVersionName;
window.grapesPublishedVersionName = result.grapesPublishedVersionName;
window.emailTemplateId = result.emailTemplateId;
window.moquiVars = result.moquiVars;
if (window.grapesVersionName !== window.grapesPublishedVersionName && window.htmlVersionName !== window.htmlPublishedVersionName) {
editor.Panels.addButton('options', window.moquiPublishButtonSettings);
} else {
editor.Panels.removeButton('options', window.moquiPublishText);
}
}
// console.log('onLoad ', result)
return result.data
......@@ -237,7 +278,7 @@ along with this software (see the LICENSE.md file). If not, see
fromElement: true,
container: '#gjs',
plugins: ['grapesjs-mjml'],
plugins: ['grapesjs-mjml',moquiPlugin],
pluginsOpts: {
'grapesjs-mjml': {}
}
......
......@@ -17,11 +17,71 @@ along with this software (see the LICENSE.md file). If not, see
<actions>
<entity-find-one entity-name="moqui.basic.email.EmailTemplate" value-field="emailTemplate" auto-field-map="[emailTemplateId:emailTemplateId]"/>
<if condition="!emailTemplate">
<if condition="!emailTemplate || !emailTemplate.htmlLocation || !emailTemplate.htmlPublishedVersionName">
<return error="true" message="Email Template not found"/>
</if>
<set field="dataPre" from="ec.resource.getLocationReference(emailTemplate.htmlLocation).getText(emailTemplate.htmlPublishedVersionName)"/>
<if condition="dataPre == null">
<return error="true" message="Email Template does not exist at ${emailTemplate.htmlLocation} with version ${emailTemplate.htmlPublishedVersionName}"/>
</if>
<set field="doc" from="org.jsoup.Jsoup.parse(dataPre)"/>
<script><![CDATA[
doc.outputSettings().escapeMode(org.jsoup.nodes.Entities.EscapeMode.xhtml).prettyPrint(false);
doc.traverse(new org.jsoup.select.NodeVisitor() {
public void head(org.jsoup.nodes.Node node, int depth) {
if (node instanceof org.jsoup.nodes.TextNode) {
def text = node.getWholeText();
if(text.trim().length() > 0) {
def newText = "";
def lines = text.split("\n");
for (line in lines) {
if (line.startsWith("<br>")) {
line = line.replaceFirst(/^<br>/, "");
}
if (line.endsWith("<br>")) {
newText += line;
} else {
newText += line + "<br>";
}
}
if (newText.startsWith("<br>")) {
newText = newText.replaceFirst(/^<br>/, "");
}
node = org.jsoup.nodes.TextNode.createFromEncoded(newText);
}
}
}
public void tail(org.jsoup.nodes.Node node, int depth) {
// No action needed on tail
}
});
]]></script>
<set field="dataPre" from="doc.html()"/>
<script><![CDATA[
String location = emailTemplate?.htmlLocation ?: "template.ftl";
freemarker.template.Template newTemplate;
Reader templateReader = null;
<set field="renderedText" from="ec.resource.template(emailTemplate.htmlLocation, 'ftl')"/>
try {
templateReader = new StringReader(context.dataPre);
// Use the getFtlConfiguration method from ec.resource.templateRenderers.ftl
newTemplate = new freemarker.template.Template(location, templateReader, ec.resource.templateRenderers.ftl.getFtlConfiguration());
} catch (Exception e) {
throw new org.moqui.BaseArtifactException("Error while initializing template at " + location, e);
} finally {
if (templateReader != null) {
try { templateReader.close(); }
catch (Exception e) { logger.error("Error closing template reader", e); }
}
}
StringWriter sw = new StringWriter()
try {
newTemplate.createProcessingEnvironment(ec.contextStack, sw).process();
} catch (Exception e) { throw new org.moqui.BaseArtifactException("Error rendering template at " + location, e); }
context.renderedText = sw.toString();
]]></script>
</actions>
<widgets>
......
......@@ -21,6 +21,9 @@ along with this software (see the LICENSE.md file). If not, see
<resource name="mjml">
<method type="get"><service name="mjml.MjmlServices.load#GrapeJs"/></method>
<method type="post"><service name="mjml.MjmlServices.store#GrapeJs"/></method>
<resource name="afterMjmlStore">
<method type="get"><service name="mjml.MjmlServices.get#AfterMjmlStore"/></method>
</resource>
</resource>
</resource>
......
......@@ -14,6 +14,17 @@ along with this software (see the LICENSE.md file). If not, see
-->
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-definition-3.xsd">
<service verb="get" noun="GlobalGrapeVarList">
<out-parameters>
<parameter name="baseLinkUrl"/>
<parameter name="currentYear"/>
</out-parameters>
<actions>
<set field="baseLinkUrl" from="!'production'.equals(System.getProperty('instance_purpose')) ? 'http://localhost:8080' : ec.web.getWebappRootUrl(true,true)" />
<set field="currentYear" from="ec.user.nowTimestamp.format('yyyy')"/>
</actions>
</service>
<service verb="load" noun="GrapeJs">
<description>Load GrapesJs resource. Can be adapted to entity other than EmailTemplate, but must have data for the grapesLocation and htmlLocation to ensure safety of read and write of resources.</description>
<in-parameters>
......@@ -23,18 +34,24 @@ along with this software (see the LICENSE.md file). If not, see
</in-parameters>
<out-parameters>
<parameter name="grapesLocation"/>
<parameter name="grapesVersionName"/>
<parameter name="grapesPublishedVersionName"/>
<parameter name="htmlLocation"/>
<parameter name="htmlVersionName"/>
<parameter name="htmlPublishedVersionName"/>
<parameter name="data"/>
<parameter name="emailTemplateId"/>
<parameter name="moquiVars"/>
</out-parameters>
<actions>
<if condition="grapesLocation == 'null'"><set field="grapesLocation" from="null"/></if>
<if condition="htmlLocation == 'null'"><set field="htmlLocation" from="null"/></if>
<!-- <log level="warn" message="resourceId is ${resourceId} resourceId.getClass().getName() ${resourceId.getClass().getName()} resourceId == 'null' ${resourceId == 'null'} resourceId == null ${resourceId == null}"/>-->
<!-- <log level="warn" message="load context.toString() ${context.toString()}"/>-->
<entity-find-one entity-name="moqui.basic.email.EmailTemplate" value-field="emailTemplate" auto-field-map="[emailTemplateId:emailTemplateId]"/>
<if condition="!emailTemplate"><return error="true" message="Resource not found"/></if>
<set field="grapesLocation" from="emailTemplate?.grapesLocation"/>
<set field="grapesPublishedVersionName" from="emailTemplate?.grapesPublishedVersionName"/>
<set field="htmlLocation" from="emailTemplate?.htmlLocation"/>
<set field="htmlPublishedVersionName" from="emailTemplate?.htmlPublishedVersionName"/>
<set field="grapesJsResource" from="ec.resource.getLocationReference('dbresource://grapesjs/project')"/>
<if condition="!grapesLocation &amp;&amp; !htmlLocation">
......@@ -42,25 +59,132 @@ along with this software (see the LICENSE.md file). If not, see
<set field="htmlFile" from="grapesJsResource.makeFile(java.util.UUID.randomUUID().toString()+'.html')"/>
<set field="grapesFile" from="grapesJsResource.makeFile(java.util.UUID.randomUUID().toString()+'.json')"/>
<set field="data" from="ec.resource.getLocationReference('dbresource://grapesjs/template/default.json').getText()"/>
<service-call name="mjml.MjmlServices.get#GlobalGrapeVarList" out-map="context"/>
<set field="defaultLocation" value="dbresource://grapesjs/template/default.json"/>
<set field="dataRaw" from="ec.resource.getLocationReference(defaultLocation).getText()"/>
<if condition="!dataRaw"><log level="error" message="Template not found at ${defaultLocation}. Please load seed data for moqui-mjml."/></if>
<set field="htmlLocation" from="grapesJsResource.location + '/' + htmlFile?.dbResourceId + '.html'"/>
<set field="grapesLocation" from="grapesJsResource.location + '/' + grapesFile?.dbResourceId + '.json'"/>
<script><![CDATA[
htmlFile.move(htmlLocation)
grapesFile.putText(data)
grapesFile.putText(dataRaw)
grapesFile.move(grapesLocation)
]]></script>
<set field="htmlVersionName" from="htmlFile?.getCurrentVersion()?.getVersionName() ?: htmlFile?.getRootVersion()?.getVersionName() ?: '01'"/>
<set field="grapesVersionName" from="grapesFile?.getCurrentVersion()?.getVersionName() ?: grapesFile?.getRootVersion()?.getVersionName() ?: '01'"/>
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,grapesLocation:grapesLocation,htmlLocation:htmlLocation]"/>
<service-call name="mjml.MjmlServices.get#GlobalGrapeVarList" out-map="globalGrapeVarList"/>
<script><![CDATA[
context.putAll(globalGrapeVarList)
context.varList = globalGrapeVarList*.key.collect { '\\\$\\{'+it+'\\}' }
context.replaceVarRegexPattern = context.varList.join('|')
if (context.replaceVarRegexPattern) {
context.dataPre = context.dataRaw.replaceAll(context.replaceVarRegexPattern) { match ->
return "${match}"
}
}
context.allVarsRegexPattern = /\$\{[a-zA-Z_][a-zA-Z0-9_.]*\}/
context.errorVarList = context.dataRaw.findAll(context.allVarsRegexPattern).unique().collect { it - '${' - '}' } - globalGrapeVarList*.key
context.errorTemplateRegexPattern = errorVarList.collect { '\\\$\\{'+it+'\\}' }.join('|')
if (context.errorTemplateRegexPattern) {
context.dataPre = context.dataPre.replaceAll(context.errorTemplateRegexPattern) { match ->
def cleanMatch = match - '${' - '}'
return "\${" + cleanMatch + "!'\$\\{" + cleanMatch + "}'}"
}
}
]]></script>
<!-- <log level="warn" message="dataPre is ${dataPre}"/>-->
<script><![CDATA[
String location = defaultLocation;
freemarker.template.Template newTemplate;
Reader templateReader = null;
try {
templateReader = new StringReader(context.dataPre);
// Use the getFtlConfiguration method from ec.resource.templateRenderers.ftl
newTemplate = new freemarker.template.Template(location, templateReader, ec.resource.templateRenderers.ftl.getFtlConfiguration());
} catch (Exception e) {
throw new org.moqui.BaseArtifactException("Error while initializing template at " + location, e);
} finally {
if (templateReader != null) {
try { templateReader.close(); }
catch (Exception e) { logger.error("Error closing template reader", e); }
}
}
StringWriter sw = new StringWriter()
try {
newTemplate.createProcessingEnvironment(ec.contextStack, sw).process();
} catch (Exception e) { throw new org.moqui.BaseArtifactException("Error rendering template at " + location, e); }
context.data = sw.toString();
]]></script>
<!-- <log level="warn" message="data is ${data}"/>-->
<set field="moquiVars" from="globalGrapeVarList"/>
</then>
<else-if condition="grapesLocation &amp;&amp; htmlLocation">
<set field="putDbResource" from="ec.resource.getLocationReference(grapesLocation)"/>
<set field="grapesFile" from="ec.resource.getLocationReference(grapesLocation)"/>
<!-- TODO: Is this a strong enough check to prevent unauthorized access? -->
<if condition="!putDbResource || putDbResource.parent?.location != grapesJsResource.location">
<if condition="!grapesFile || grapesFile.parent?.location != grapesJsResource.location">
<return error="true" message="Resource not found"/>
</if>
<set field="grapesVersionName" from="grapesFile?.getCurrentVersion()?.getVersionName() ?: grapesFile?.getRootVersion()?.getVersionName() ?: '01'"/>
<set field="tempHtmlFile" from="ec.resource.getLocationReference(htmlLocation)"/>
<set field="htmlVersionName" from="tempHtmlFile?.getCurrentVersion()?.getVersionName() ?: tempHtmlFile?.getRootVersion()?.getVersionName() ?: '01'"/>
<set field="tempHtmlFile" from="null"/>
<service-call name="mjml.MjmlServices.get#GlobalGrapeVarList" out-map="globalGrapeVarList"/>
<set field="dataRaw" from="grapesFile.getText()"/>
<script><![CDATA[
context.putAll(globalGrapeVarList)
context.varList = globalGrapeVarList*.key.collect { '\\\$\\{'+it+'\\}' }
context.replaceVarRegexPattern = context.varList.join('|')
if (context.replaceVarRegexPattern) {
context.dataPre = context.dataRaw.replaceAll(context.replaceVarRegexPattern) { match ->
return "${match}"
}
}
context.allVarsRegexPattern = /\$\{[a-zA-Z_][a-zA-Z0-9_.]*\}/
context.errorVarList = context.dataRaw.findAll(context.allVarsRegexPattern).unique().collect { it - '${' - '}' } - globalGrapeVarList*.key
context.errorTemplateRegexPattern = errorVarList.collect { '\\\$\\{'+it+'\\}' }.join('|')
if (context.errorTemplateRegexPattern) {
context.dataPre = context.dataPre.replaceAll(context.errorTemplateRegexPattern) { match ->
def cleanMatch = match - '${' - '}'
return "\${" + cleanMatch + "!'\$\\{" + cleanMatch + "}'}"
}
}
]]></script>
<!-- <log level="warn" message="dataPre is ${dataPre}"/>-->
<script><![CDATA[
String location = grapesFile.location;
<set field="data" from="putDbResource.getText()"/>
freemarker.template.Template newTemplate;
Reader templateReader = null;
try {
templateReader = new StringReader(context.dataPre);
// Use the getFtlConfiguration method from ec.resource.templateRenderers.ftl
newTemplate = new freemarker.template.Template(location, templateReader, ec.resource.templateRenderers.ftl.getFtlConfiguration());
} catch (Exception e) {
throw new org.moqui.BaseArtifactException("Error while initializing template at " + location, e);
} finally {
if (templateReader != null) {
try { templateReader.close(); }
catch (Exception e) { logger.error("Error closing template reader", e); }
}
}
StringWriter sw = new StringWriter()
try {
newTemplate.createProcessingEnvironment(ec.contextStack, sw).process();
} catch (Exception e) { throw new org.moqui.BaseArtifactException("Error rendering template at " + location, e); }
context.data = sw.toString();
]]></script>
<!-- <log level="warn" message="data is ${data}"/>-->
<set field="moquiVars" from="globalGrapeVarList"/>
</else-if>
<else>
<return error="true" message="Resource not found"/>
......@@ -73,13 +197,19 @@ along with this software (see the LICENSE.md file). If not, see
<in-parameters>
<parameter name="htmlLocation"/>
<parameter name="grapesLocation"/>
<parameter name="emailTemplateId"/>
<parameter name="data"/>
<parameter name="html" allow-html="any"/>
<parameter name="emailTemplateId" required="true"/>
<parameter name="data" required="true"/>
<parameter name="moquiVars" required="true"/>
<parameter name="html" allow-html="any" required="true"/>
<parameter name="publish" default="false" type="Boolean" required="true"/>
</in-parameters>
<out-parameters>
<parameter name="htmlLocation"/>
<parameter name="htmlVersionName"/>
<parameter name="htmlPublishedVersionName"/>
<parameter name="grapesLocation"/>
<parameter name="grapesVersionName"/>
<parameter name="grapesPublishedVersionName"/>
</out-parameters>
<actions>
<if condition="htmlLocation == 'null'"><set field="htmlLocation" from="null"/></if>
......@@ -87,13 +217,18 @@ along with this software (see the LICENSE.md file). If not, see
<entity-find-one entity-name="moqui.basic.email.EmailTemplate" value-field="emailTemplate" auto-field-map="[emailTemplateId:emailTemplateId]"/>
<if condition="!emailTemplate"><return error="true" message="Resource not found"/></if>
<set field="grapesLocation" from="emailTemplate?.grapesLocation"/>
<set field="grapesPublishedVersionName" from="emailTemplate?.grapesPublishedVersionName"/>
<set field="htmlLocation" from="emailTemplate?.htmlLocation"/>
<set field="data" from="groovy.json.JsonOutput.toJson(new groovy.json.JsonSlurper().parseText(ec.web.secureRequestParameters._requestBodyText).data)"/>
<set field="htmlPublishedVersionName" from="emailTemplate?.htmlPublishedVersionName"/>
<set field="dataMap" from="new groovy.json.JsonSlurper().parseText(ec.web.secureRequestParameters._requestBodyText).data"/>
<!-- <log level="warn" message="dataMap is ${dataMap}"/>-->
<set field="moquiVars" from="new groovy.json.JsonSlurper().parseText(ec.web.secureRequestParameters._requestBodyText).moquiVars"/>
<set field="data" from="groovy.json.JsonOutput.toJson(dataMap)"/>
<set field="grapesJsResource" from="ec.resource.getLocationReference('dbresource://grapesjs/project')"/>
<if condition="!htmlLocation &amp;&amp; !grapesLocation">
<then>
<!-- TODO: This should work, but isn't used anywhere and is untested.
<!-- TODO: This should work as of 2024 May 14, but isn't used anywhere and is untested. There will need to be work done based on the dataMap code
<set field="htmlFile" from="grapesJsResource.makeFile(java.util.UUID.randomUUID().toString()+'.html')"/>
<set field="grapesFile" from="grapesJsResource.makeFile(java.util.UUID.randomUUID().toString()+'.json')"/>
......@@ -118,7 +253,18 @@ along with this software (see the LICENSE.md file). If not, see
<if condition="!grapesFile || grapesFile.parent?.location != grapesJsResource.location">
<return error="true" message="Resource not found"/>
</if>
<script>grapesFile.putText(data)</script>
<script><![CDATA[
context.replaceMoquiVarRegexPattern = context.moquiVars*.value.join('|')
if (context.replaceMoquiVarRegexPattern) {
context.dataPre = data.replaceAll(context.replaceMoquiVarRegexPattern) { match ->
def output = moquiVars.find { it.value == match }?.key
return '${' + output + '}'
}
}
]]></script>
<script>grapesFile.putText(dataPre)</script>
<set field="grapesVersionName" from="grapesFile?.getCurrentVersion()?.getVersionName()"/>
<set field="htmlFile" from="null"/>
<if condition="htmlLocation"><then>
......@@ -141,7 +287,22 @@ along with this software (see the LICENSE.md file). If not, see
<if condition="!htmlFile || htmlFile.parent?.location != grapesJsResource.location">
<return error="true" message="Resource not found"/>
</if>
<script><![CDATA[htmlFile.putText(html)]]></script>
<set field="htmlOut" from="null"/>
<script><![CDATA[
if (context.replaceMoquiVarRegexPattern) {
context.htmlOut = html.replaceAll(context.replaceMoquiVarRegexPattern) { match ->
def output = moquiVars.find { it.value == match }?.key
return '${' + output + '}'
}
}
htmlFile.putText(htmlOut)]]></script>
<set field="htmlVersionName" from="htmlFile?.getCurrentVersion()?.getVersionName()"/>
<if condition="publish">
<service-call name="update#moqui.basic.email.EmailTemplate" in-map="[emailTemplateId:emailTemplateId,
htmlPublishedVersionName:htmlVersionName,grapesPublishedVersionName:grapesVersionName]"/>
<set field="htmlPublishedVersionName" from="htmlVersionName"/>
<set field="grapesPublishedVersionName" from="grapesVersionName"/>
</if>
</else-if>
<else>
<return error="true" message="Resource not found"/>
......@@ -149,6 +310,102 @@ along with this software (see the LICENSE.md file). If not, see
</if>
</actions>
</service>
<service verb="get" noun="AfterMjmlStore">
<description>Get the data after storing the MJML data</description>
<in-parameters>
<parameter name="emailTemplateId" required="true"/>
</in-parameters>
<out-parameters>
<parameter name="htmlLocation"/>
<parameter name="htmlVersionName"/>
<parameter name="htmlPublishedVersionName"/>
<parameter name="grapesLocation"/>
<parameter name="grapesVersionName"/>
<parameter name="grapesPublishedVersionName"/>
</out-parameters>
<actions>
<entity-find-one entity-name="moqui.basic.email.EmailTemplate" value-field="emailTemplate" auto-field-map="[emailTemplateId:emailTemplateId]"/>
<if condition="!emailTemplate"><return error="true" message="Resource not found"/></if>
<set field="grapesLocation" from="emailTemplate?.grapesLocation"/>
<set field="grapesVersionName" from="ec.resource.getLocationReference(grapesLocation)?.getCurrentVersion()?.getVersionName()"/>
<set field="grapesPublishedVersionName" from="emailTemplate?.grapesPublishedVersionName"/>
<set field="htmlLocation" from="emailTemplate?.htmlLocation"/>
<set field="htmlVersionName" from="ec.resource.getLocationReference(htmlLocation)?.getCurrentVersion()?.getVersionName()"/>
<set field="htmlPublishedVersionName" from="emailTemplate?.htmlPublishedVersionName"/>
</actions>
</service>
<service verb="remove" noun="ExcessMjmlEmailResourceHistories" authenticate="anonymous-all">
<in-parameters>
<parameter name="runDate" default="Timestamp.from(java.time.Instant.now())" required="true" type="Timestamp"/>
</in-parameters>
<out-parameters>
<parameter name="removedHistoryList"/>
</out-parameters>
<actions>
<entity-find entity-name="moqui.basic.email.EmailTemplate" list="emailTemplateList">
<econdition field-name="grapesLocation" operator="is-not-null"/>
<econdition field-name="htmlLocation" operator="is-not-null"/>
<select-field field-name="emailTemplateId,grapesLocation,htmlLocation,grapesPublishedVersionName,htmlPublishedVersionName"/>
<order-by field-name="-lastUpdatedStamp"/>
</entity-find>
<set field="resourceList" from="[]"/>
<iterate list="emailTemplateList" entry="emailTemplate">
<set field="grapesFile" from="ec.resource.getLocationReference(emailTemplate.grapesLocation)"/>
<if condition="grapesFile">
<script><![CDATA[
def versionWhitelist = []
if (grapesFile?.getCurrentVersion()?.getVersionName()) versionWhitelist.add(grapesFile.getCurrentVersion().getVersionName())
if (emailTemplate?.grapesPublishedVersionName) versionWhitelist.add(emailTemplate.grapesPublishedVersionName)
resourceList.add([location:grapesFile.location,resourceId:grapesFile.dbResourceId,versionWhitelist:versionWhitelist.size()>0?versionWhitelist:null])]]></script>
</if>
<set field="htmlFile" from="ec.resource.getLocationReference(emailTemplate.htmlLocation)"/>
<if condition="htmlFile">
<script><![CDATA[
def versionWhitelist = []
if (htmlFile?.getCurrentVersion()?.getVersionName()) versionWhitelist.add(htmlFile.getCurrentVersion().getVersionName())
if (emailTemplate?.htmlPublishedVersionName) versionWhitelist.add(emailTemplate.htmlPublishedVersionName)
resourceList.add([location:htmlFile.location,resourceId:htmlFile.dbResourceId,versionWhitelist:versionWhitelist.size()>0?versionWhitelist:null])]]></script>
</if>
</iterate>
<set field="oneHourAgo" from="Timestamp.from(runDate.toInstant().minus(1, java.time.temporal.ChronoUnit.HOURS))"/>
<set field="removedHistoryList" from="[]"/>
<iterate list="resourceList" entry="resource">
<entity-find entity-name="moqui.resource.DbResourceFileHistory" list="resourceHistoryPreList">
<econdition field-name="resourceId" from="resource.resourceId"/>
<econdition field-name="versionDate" operator="greater" from="oneHourAgo"/>
<econdition field-name="versionDate" operator="less-equals" from="runDate"/>
<select-field field-name="resourceId,versionName,versionDate,previousVersionName,userId"/>
<order-by field-name="-versionDate"/>
</entity-find>
<set field="skippedUserIds" from="[]"/>
<set field="resourceHistoryList" from="[]"/>
<iterate list="resourceHistoryPreList" entry="resourceHistory">
<!-- Add all but the single latest history per userId to resourceHistoryList -->
<if condition="resource.versionWhitelist.contains(resourceHistory.versionName) || !skippedUserIds.contains(resourceHistory.userId)">
<!-- <log level="warn" message="${resource.resourceId} ${resourceHistory.versionName} userId ${resourceHistory.userId}"/>-->
<set field="skippedUserIds" from="skippedUserIds + [resourceHistory.userId]"/><continue/></if>
<set field="resourceHistoryList" from="resourceHistoryList + [resourceHistory]"/>
</iterate>
<iterate list="resourceHistoryList" entry="resourceHistory">
<entity-find-one entity-name="moqui.resource.DbResourceFileHistory" value-field="usedResourceHistory" auto-field-map="[resourceId:resource.resourceId,previousVersionName:resourceHistory.versionName]" for-update="true">
<select-field field-name="resourceId,versionName,versionDate,previousVersionName,userId"/></entity-find-one>
<!-- <log level="warn" message="set versionName ${usedResourceHistory.versionName} of previousVersionName ${usedResourceHistory.previousVersionName} to ${resourceHistory.previousVersionName}"/>-->
<if condition="usedResourceHistory">
<set field="usedResourceHistory.previousVersionName" from="resourceHistory?.previousVersionName"/>
<log level="info" message="Removed resource history ${resourceHistory.resourceId} version ${resourceHistory.versionName}"/>
<set field="removedHistoryList" from="removedHistoryList + [resourceId:resource.resourceId, versionName:resourceHistory.versionName,versionDate:resourceHistory.versionDate,userId:resourceHistory.userId]"/>
<entity-update value-field="usedResourceHistory"/>
<entity-delete value-field="resourceHistory"/>
</if>
</iterate>
</iterate>
</actions>
</service>
</services>
......