diff --git a/.gradle/1.0-milestone-3/taskArtifacts/cache.bin b/.gradle/1.0-milestone-3/taskArtifacts/cache.bin new file mode 100644 index 0000000..53f255e Binary files /dev/null and b/.gradle/1.0-milestone-3/taskArtifacts/cache.bin differ diff --git a/.gradle/1.0-milestone-3/taskArtifacts/cache.properties b/.gradle/1.0-milestone-3/taskArtifacts/cache.properties new file mode 100644 index 0000000..c23c05b --- /dev/null +++ b/.gradle/1.0-milestone-3/taskArtifacts/cache.properties @@ -0,0 +1 @@ +#Thu Jul 28 16:50:19 CEST 2011 diff --git a/README b/README new file mode 100644 index 0000000..73f2881 --- /dev/null +++ b/README @@ -0,0 +1 @@ +This file was created by IntelliJ IDEA (Xena) IU-107.481 for binding GitHub repository \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..0ca8d2f --- /dev/null +++ b/build.gradle @@ -0,0 +1,125 @@ +import org.apache.ivy.plugins.resolver.URLResolver + +apply plugin: 'java' +apply plugin: 'groovy' +apply plugin: 'gae' +apply plugin: 'gaelyk' +apply plugin: 'eclipse' +apply plugin: 'idea' + +def compatibilityVersion = 1.5 +sourceCompatibility = compatibilityVersion +targetCompatibility = compatibilityVersion + +buildscript { + gitHub = { + def resolver = new URLResolver() + + resolver.with { + name = 'GitHub' + addArtifactPattern 'http://cloud.github.com/downloads/[organisation]/[module]/[module]-[revision].[ext]' + } + + resolver + } + + repositories { + add gitHub() + } + + dependencies { + classpath 'bmuschko:gradle-gae-plugin:0.5.1' + classpath 'bmuschko:gradle-gaelyk-plugin:0.1' + } +} + +repositories { + mavenCentral() + add gitHub() +} + +sourceSets { + main { + classesDir = file('war/WEB-INF/classes') + } +} + +dependencies { + def gaeVersion = '1.5.2' + groovy 'org.codehaus.groovy:groovy-all:1.8.1' + compile "com.google.appengine:appengine-api-1.0-sdk:$gaeVersion", + "com.google.appengine:appengine-api-labs:$gaeVersion", + 'glaforge:gaelyk:1.0' + + testCompile 'org.spockframework:spock-core:0.5-groovy-1.8', { + exclude group: 'org.codehaus.groovy', name: 'groovy-all' + } + testCompile 'marcoVermeulen:gaelyk-spock:0.1', + "com.google.appengine:appengine-api-stubs:$gaeVersion", + "com.google.appengine:appengine-testing:$gaeVersion", + 'javax.servlet:servlet-api:2.5', + 'cglib:cglib-nodep:2.2', + 'org.objenesis:objenesis:1.2' + gaeSdk "com.google.appengine:appengine-java-sdk:$gaeVersion" +} + +webAppDirName = file('war') + +gae { + warDir = file('war') + downloadSdk = true +} + +clean.doLast { + delete sourceSets*.classesDir +} + +task copyRuntimeLibraries { + def webAppLibDirName = 'war/WEB-INF/lib' + description = "Copies runtime libraries to $webAppLibDirName." + + copy { + into webAppLibDirName + from configurations.runtime.files + } +} + +ideaProject { + javaVersion = compatibilityVersion + + withXml { provider -> + def node = provider.asNode() + + // Set Gradle home + def gradleSettings = node.appendNode('component', [name: 'GradleSettings']) + gradleSettings.appendNode('option', [name: 'SDK_HOME', value: gradle.gradleHomeDir]) + } +} + +eclipseProject { + projectName = 'gaelyk-project' + + whenConfigured { project -> + project.natures << 'com.google.appengine.eclipse.core.gaeNature' + project.natures << 'com.google.gdt.eclipse.core.webAppNature' + project.buildCommands << [name: 'com.google.appengine.eclipse.core.enhancerbuilder'] + project.buildCommands << [name: 'com.google.appengine.eclipse.core.projectValidator'] + project.buildCommands << [name: 'com.google.gdt.eclipse.core.webAppProjectValidator'] + } +} + +eclipseClasspath { + withXml { xml -> + xml.asNode().classpathentry.find { it.@kind == 'output' && it.@path == 'bin' }.@path = 'war/WEB-INF/classes' + xml.asNode().appendNode('classpathentry', [kind: 'con', path: 'com.google.appengine.eclipse.core.GAE_CONTAINER']) + .appendNode('attributes') + .appendNode('attribute', [name: 'org.eclipse.jst.component.nondependency', value: '/war/WEB-INF/lib']) + xml.asNode().appendNode('classpathentry', [exported: 'true', kind: 'con', path: 'GROOVY_SUPPORT']) + .appendNode('attributes') + .appendNode('attribute', [name: 'org.eclipse.jst.component.nondependency', value: '/war/WEB-INF/lib']) + } +} + +task wrapper(type: Wrapper) { + gradleVersion = '1.0-milestone-3' +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..45bfb5c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..98d50de --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Jun 25 17:35:12 EDT 2011 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://repo.gradle.org/gradle/distributions/gradle-1.0-milestone-3-bin.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..d8809f1 --- /dev/null +++ b/gradlew @@ -0,0 +1,168 @@ +#!/bin/bash + +############################################################################## +## ## +## Gradle wrapper script for UN*X ## +## ## +############################################################################## + +# Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. +# GRADLE_OPTS="$GRADLE_OPTS -Xmx512m" +# JAVA_OPTS="$JAVA_OPTS -Xmx512m" + +GRADLE_APP_NAME=Gradle + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set JAVA_HOME if it's not already set. +if [ -z "$JAVA_HOME" ] ; then + if $darwin ; then + [ -z "$JAVA_HOME" -a -d "/Library/Java/Home" ] && export JAVA_HOME="/Library/Java/Home" + [ -z "$JAVA_HOME" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] && export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home" + else + javaExecutable="`which javac`" + [ -z "$javaExecutable" -o "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ] && die "JAVA_HOME not set and cannot find javac to deduce location, please set JAVA_HOME." + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + [ `expr "$readLink" : '\([^ ]*\)'` = "no" ] && die "JAVA_HOME not set and readlink not available, please set JAVA_HOME." + javaExecutable="`readlink -f \"$javaExecutable\"`" + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + export JAVA_HOME="$javaHome" + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVACMD" ] && JAVACMD=`cygpath --unix "$JAVACMD"` + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain +CLASSPATH=`dirname "$0"`/gradle/wrapper/gradle-wrapper.jar +WRAPPER_PROPERTIES=`dirname "$0"`/gradle/wrapper/gradle-wrapper.properties +# Determine the Java command to use to start the JVM. +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="java" + fi +fi +if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi +if [ -z "$JAVA_HOME" ] ; then + warn "JAVA_HOME environment variable is not set" +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add GRADLE_APP_NAME to the JAVA_OPTS as -Xdock:name +if $darwin; then + JAVA_OPTS="$JAVA_OPTS -Xdock:name=$GRADLE_APP_NAME" +# we may also want to set -Xdock:image +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +GRADLE_APP_BASE_NAME=`basename "$0"` + +exec "$JAVACMD" $JAVA_OPTS $GRADLE_OPTS \ + -classpath "$CLASSPATH" \ + -Dorg.gradle.appname="$GRADLE_APP_BASE_NAME" \ + -Dorg.gradle.wrapper.properties="$WRAPPER_PROPERTIES" \ + $STARTER_MAIN_CLASS \ + "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..479fddd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,82 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem ## +@rem Gradle startup script for Windows ## +@rem ## +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. +@rem set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512m +@rem set JAVA_OPTS=%JAVA_OPTS% -Xmx512m + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=.\ + +@rem Find java.exe +set JAVA_EXE=java.exe +if not defined JAVA_HOME goto init + +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. +echo. +goto end + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain +set CLASSPATH=%DIRNAME%\gradle\wrapper\gradle-wrapper.jar +set WRAPPER_PROPERTIES=%DIRNAME%\gradle\wrapper\gradle-wrapper.properties + +set GRADLE_OPTS=%JAVA_OPTS% %GRADLE_OPTS% -Dorg.gradle.wrapper.properties="%WRAPPER_PROPERTIES%" + +@rem Execute Gradle +"%JAVA_EXE%" %GRADLE_OPTS% -classpath "%CLASSPATH%" %STARTER_MAIN_CLASS% %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +if not "%OS%"=="Windows_NT" echo 1 > nul | choice /n /c:1 + +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit "%ERRORLEVEL%" +exit /b "%ERRORLEVEL%" + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega \ No newline at end of file diff --git a/sample.iml b/sample.iml new file mode 100644 index 0000000..6a44fa2 --- /dev/null +++ b/sample.iml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + /Library/GoogleAppEngine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gaelyk.dsld b/src/gaelyk.dsld new file mode 100644 index 0000000..2d2a09b --- /dev/null +++ b/src/gaelyk.dsld @@ -0,0 +1,1354 @@ + + +import java.util.concurrent.Future; + +// Things to discuss +// # are there any ways how to promote dsls to templates like gtpl? +// # are there any ways to check operators like left shift? +// # is there any way to handle generics like Key? +// # how to handle closure parameters? + +class EnvDescriptor { + String name + String version +} + +class GaelykDescriptor { + String version +} + +class AppDescriptor { + String id + String version + EnvDescriptor env + GaelykDescriptor gaelyk + +} + +def shortcutFor = { type -> + bind(clazz: currentType(type)) & enclosingScript(sourceFolderOfCurrentType('war/WEB-INF/groovy')) +} + +(sourceFolderOfCurrentType('war/WEB-INF/groovy') & enclosingScript()).accept { + provider = 'Gaelyk Groovlet' + property name: 'datastore', + type: 'com.google.appengine.api.datastore.DatastoreService' + + property name: 'request', type: 'javax.servlet.http.HttpServletRequest', doc: 'the HttpServletRequest object' + property name: 'response', type: 'javax.servlet.http.HttpServletResponse', doc: 'the HttpServletResponse object' + property name: 'context', type: 'javax.servlet.ServletContext', doc: 'the ServletContext object' + property name: 'application', type: 'javax.servlet.ServletContext', doc: 'same as context' + property name: 'session', type: 'javax.servlet.http.HttpSession', doc: 'shorthand for request.getSession(false) (can be null) which returns an HttpSession' + property name: 'params', type: Map, doc: 'map of all form parameters (can be empty)' + property name: 'headers', type: Map, doc: 'map of all request header fields' + property name: 'log', type: 'groovyx.gaelyk.logging.GroovyLogger', doc: 'a Groovy logger is available for logging messages through java.util.logging' + + property name: 'out', type: PrintWriter, doc:'shorthand for response.getWriter() which returns a PrintWriter' + property name: 'sout', type: 'javax.servlet.ServletOutputStream', doc: 'shorthand for response.getOutputStream() which returns a ServletOutputStream' + property name: 'html', type: 'groovy.xml.MarkupBuilder', doc: 'shorthand for new MarkupBuilder(response.getWriter()) which returns a MarkupBuilder' + + method name: 'forward', type: 'void', params: [path: 'java.lang.String'], doc: "forwards to given url, groovlet or template" + method name: 'include', type: 'void', params: [path: 'java.lang.String'], doc: "includes given template" + method name: 'redirect', type: 'void', params: [path: 'java.lang.String'], doc: "redirects to given url, groovlet or template" +} + +((sourceFolderOfCurrentType('war/WEB-INF/groovy') & enclosingScript()) | annotatedBy('groovyx.gaelyk.GaelykBindings')).accept { + property name: 'logger', type: Map, doc: 'a logger accessor can be used to get access to any logger' + property name: 'datastore', type: 'com.google.appengine.api.datastore.DatastoreService', doc: 'the Datastore service' + property name: 'memcache', type: 'com.google.appengine.api.memcache.MemcacheService', doc: 'the Memcache service' + property name: 'urlFetch', type: 'com.google.appengine.api.urlfetch.URLFetchService', doc: 'the URL Fetch service' + property name: 'mail', type: 'com.google.appengine.api.mail.MailService', doc: 'the Mail service' + + property name: 'images', type: 'groovyx.gaelyk.ImagesServiceWrapper', doc: 'the Images service (actually a convenient wrapper class combining both the methods of ImagesService and ImagesServiceFactory and implementing the ImagesService interface)' + property name: 'users', type: 'com.google.appengine.api.users.UserService', doc: 'the User service' + property name: 'user', type: 'com.google.appengine.api.users.User', doc: 'the currently logged in user (null if no user logged in)' + property name: 'defaultQueue', type: 'com.google.appengine.api.taskqueue.Queue', doc: 'the default queue' + property name: 'queues', type: Map, doc: 'a map-like object with which you can access the configured queues' + property name: 'xmpp', type: 'com.google.appengine.api.xmpp.XMPPService', doc: 'the Jabber/XMPP service.' + property name: 'blobstore', type: 'com.google.appengine.api.blobstore.BlobstoreService', doc: 'the Blobstore service.' + property name: 'oauth', type: 'com.google.appengine.api.oauth.OAuthService', doc: 'the OAuth service.' + property name: 'namespace', type: Class, doc: 'the Namespace manager' + property name: 'capabilities', type: 'com.google.appengine.api.capabilities.CapabilitiesService', doc: 'the Capabilities service' + property name: 'channel', type: 'com.google.appengine.api.channel.ChannelService', doc: 'the Channel service' + property name: 'files', type: 'com.google.appengine.api.files.FileService', doc: 'the File service' + property name: 'backends', type: 'com.google.appengine.api.backends.BackendService', doc: 'the Backend service' + property name: 'lifecycle', type: 'com.google.appengine.api.LifecycleManager', doc: 'the Lifecycle manager' + property name: 'localMode', type: Boolean, doc: 'a boolean variable which is true when the application is running in local development mode, and false when deployed on Google\'s cloud.' + + property name: 'app', type: AppDescriptor, doc: 'map of all form parameters (can be empty)' +} + +(sourceFolderOfCurrentFile('war/WEB-INF') & name("routes") & enclosingScript()).accept { + provider = 'Gaelyk' + method name: 'all', + useNamedArgs: true, + type: List, + params: [route: String, forward: String, redirect: String, validate: Closure, cache: int, ignore: boolean, namespace: String], + doc: 'Routes all HTTP methods.' + method name: 'get', + useNamedArgs: true, + type: List, + params: [route: String, forward: String, redirect: String, validate: Closure, cache: int, ignore: boolean, namespace: String], + doc: 'Routes GET HTTP method.' + method name: 'post', + useNamedArgs: true, + type: List, + params: [route: String, forward: String, redirect: String, validate: Closure, cache: int, ignore: boolean, namespace: String], + doc: 'Routes POST HTTP method.' + method name: 'put', + useNamedArgs: true, + type: List, + params: [route: String, forward: String, redirect: String, validate: Closure, cache: int, ignore: boolean, namespace: String], + doc: 'Routes PUT HTTP method.' + method name: 'delete', + useNamedArgs: true, + type: List, + params: [route: String, forward: String, redirect: String, validate: Closure, cache: int, ignore: boolean, namespace: String], + doc: 'Routes DELETE HTTP method.' + method name: 'email', + useNamedArgs: true, + type: List, + params: [to: String], + doc: 'Routes incoming email messages.' + method name: 'jabber', + useNamedArgs: true, + type: List, + params: [type: String, to: String], + doc: 'Routes incomming jabber messages and statuses.' +} + + +shortcutFor('com.google.appengine.api.taskqueue.Queue').accept { + provider = 'Gaelyk' + method name: 'add', + useNamedArgs: true, + type: 'com.google.appengine.api.taskqueue.TaskHandle', + params: [coundDownMillis: long, etaMillis: long, headers: Map, method: 'com.google.appengine.api.taskqueue.TaskOptions.Method', params: Map, payload: Object, taskName: String, url: String, retryOption: 'com.google.appengine.api.taskqueue.RetryOptions'], + doc: 'Add a new task on the queue using a map for holding the task attributes instead of a TaskOptions builder object.' + method name: 'getName', + type: 'java.lang.String', + doc: 'Shorcut to get the name of the Queue.' + property name: 'name', + type: 'java.lang.String', + doc: 'Shorcut to get the name of the Queue.' + method name: 'leftShift', + useNamedArgs: true, + type: 'com.google.appengine.api.taskqueue.TaskHandle', + params: [coundDownMillis: long, etaMillis: long, headers: Map, method: 'com.google.appengine.api.taskqueue.TaskOptions.Method', params: Map, payload: Object, taskName: String, url: String, retryOption: 'com.google.appengine.api.taskqueue.RetryOptions'], + doc: 'Add a new task on the queue using a map for holding the task attributes instead of a TaskOptions builder object.' +} + + +shortcutFor('com.google.appengine.api.datastore.Entity').accept { + provider = 'Gaelyk' + + method name: 'get', + type: 'java.lang.Object', + params: [name: 'java.lang.String'], + doc: 'Provides a shortcut notation to get a property of an entity.' + + method name: 'save', + type: 'com.google.appengine.api.datastore.Key', + doc: 'Save this entity in the data store.' + + method name: 'set', + type: 'void', + params: [name: 'java.lang.String', property: 'java.lang.Object'], + doc: 'Provides a shortcut notation to set a property of an entity.' + + method name: 'delete', + type: 'void', + doc: 'Delete this entity from the data store.' + + method name: 'leftShift', + type: 'com.google.appengine.api.datastore.Entity', + params: [params: 'java.util.Map'], + doc: '''Set the Entity properties with the key / value pairs of the map, +using the leftshift operator as follows: +entity << params''' + + method name: 'getAt', + type: 'java.lang.Object', + params: [name: 'java.lang.String'], + doc: 'Provides a shortcut notation to get a property of an entity.' + + method name: 'asType', + type: 'java.lang.Object', + params: [type: 'java.lang.Class'], + doc: '''Gaelyk supports a simplistic object/entity mapping, thanks to type coercion. + You can use this type coercion mechanism to coerce POJOs/POGOs and datastore Entities. + The Entity kind will be the simple name of the POJO/POGO (same approach as Objectify). + So with this mechanism, you can do: + +

+class Person { String name, int age }
+
+ def e = new Entity("Person")
+ e.name = "Guillaume"
+ e.age = 33
+ 
+ def p = e as Person
+
+ assert e.name == p.name
+ assert e.age == p.age
+
''' + + method name: 'setAt', + type: 'void', + params: [name: 'java.lang.String', property: 'java.lang.Object'], + doc: 'Provides a shortcut notation to set a property of an entity.' + + method name: 'asyncSave', + type: 'java.util.concurrent.Future', + doc: 'Save this entity in the data store asynchronously.' + + method name: 'asyncDelete', + type: 'java.util.concurrent.Future', + doc: 'Delete this entity from the data store.' +} + +shortcutFor('com.google.appengine.api.memcache.MemcacheService').accept { + provider = 'Gaelyk' + method name: 'get', + type: 'java.lang.Object', + params: [key: 'java.lang.String'], + doc: 'Get an object from the cache with a String key' + + method name: 'get', + type: 'java.lang.Object', + params: [key: 'groovy.lang.GString'], + doc: 'Get an object from the cache, with a GString key, coerced to a String.' + + method name: 'put', + type: 'void', + params: [key: 'groovy.lang.GString', value: 'java.lang.Object'], + doc: 'Put an object in the cache under a GString key, coerced to a String.' + + method name: 'put', + type: 'void', + params: [key: 'groovy.lang.GString', value: 'java.lang.Object', expiration: 'com.google.appengine.api.memcache.Expiration'], + doc: 'Put an object in the cache under a GString key, coerced to a String, with an expiration.' + + method name: 'put', + type: 'void', + params: [key: 'groovy.lang.GString', value: 'java.lang.Object', expiration: 'com.google.appengine.api.memcache.Expiration', policy: 'com.google.appengine.api.memcache.MemcacheService$SetPolicy'], + doc: 'Put an object in the cache under a GString key, coerced to a String, with an expiration and a SetPolicy.' + + method name: 'set', + type: 'void', + params: [key: 'java.lang.String', value: 'java.lang.Object'], + doc: 'Put an object in the cache under a String key.' + + method name: 'isCase', + type: 'boolean', + params: [key: 'java.lang.Object'], + doc: '''Shortcut to check whether a key is contained in the cache using the in operator: +key in memcache''' + + method name: 'memoize', + type: 'groovy.lang.Closure', + params: [closure: 'groovy.lang.Closure'], + doc: '''Memoize a closure invocation in memcache. +Closure call result are stored in memcache, retaining the closure hashCode and the argument values as key. +The results are kept in memcache only up to the 30 seconds request time limit of Google App Engine. + +

+def countEntities = memcache.memoize { String kind -> datastore.prepare( new Query(kind) ).countEntities() }
+def totalPhotos = countEntities('photos')
+
+''' + + method name: 'getAt', + type: 'java.lang.Object', + params: [key: 'java.lang.Object'], + doc: '''Get an object from the cache, identified by its key, using the subscript notation: +def obj = memcache[key]''' + + method name: 'getAt', + type: 'java.lang.Object', + params: [key: 'java.lang.String'], + doc: '''Get an object from the cache, identified by its key, using the subscript notation: +def obj = memcache[key]''' + + method name: 'putAt', + type: 'void', + params: [key: 'java.lang.String', value: 'java.lang.Object'], + doc: '''Put an object into the cache, identified by its key, using the subscript notation: +memcache[key] = value''' + + method name: 'putAt', + type: 'void', + params: [key: 'java.lang.Object', value: 'java.lang.Object'], + doc: '''Put an object into the cache, identified by its key, using the subscript notation: +memcache[key] = value''' + + method name: 'clearCacheForUri', + type: 'java.util.Set', + params: [uri: 'java.lang.String'], + doc: 'Clear the cached content for a given URI.' + +} + + +shortcutFor('java.net.URL').accept { + provider = 'Gaelyk' + method name: 'get', + type: 'java.lang.Object', + useNamedArgs: true, + params: [allowTruncate: boolean, followRedirects: boolean, deadline: double, headers: Map, payload: byte[], params: Map, async: boolean ], + doc: 'Use the URLFetch Service to do a GET on the URL.' + + method name: 'get', + type: 'java.lang.Object', + doc: 'Use the URLFetch Service to do a GET on the URL.' + + method name: 'put', + type: 'java.lang.Object', + useNamedArgs: true, + params: [allowTruncate: boolean, followRedirects: boolean, deadline: double, headers: Map, payload: byte[], params: Map, async: boolean ], + doc: 'Use the URLFetch Service to do a PUT on the URL.' + + method name: 'put', + type: 'java.lang.Object', + doc: 'Use the URLFetch Service to do a PUT on the URL.' + + method name: 'delete', + type: 'java.lang.Object', + useNamedArgs: true, + params: [allowTruncate: boolean, followRedirects: boolean, deadline: double, headers: Map, payload: byte[], params: Map, async: boolean ], + doc: 'Use the URLFetch Service to do a DELETE on the URL.' + + method name: 'delete', + type: 'java.lang.Object', + doc: 'Use the URLFetch Service to do a DELETE on the URL.' + + method name: 'head', + type: 'java.lang.Object', + useNamedArgs: true, + params: [allowTruncate: boolean, followRedirects: boolean, deadline: double, headers: Map, payload: byte[], params: Map, async: boolean ], + doc: 'Use the URLFetch Service to do a HEAD on the URL.' + + method name: 'head', + type: 'java.lang.Object', + doc: 'Use the URLFetch Service to do a HEAD on the URL.' + + method name: 'asType', + type: 'com.google.appengine.api.datastore.Link', + params: [arg1: 'java.lang.Class'], + doc: 'Converter method for converting a URL into a Link instance.' + + method name: 'post', + type: 'java.lang.Object', + useNamedArgs: true, + params: [allowTruncate: boolean, followRedirects: boolean, deadline: double, headers: Map, payload: byte[], params: Map, async: boolean ], + doc: 'Use the URLFetch Service to do a POST on the URL.' + + method name: 'post', + type: 'java.lang.Object', + doc: 'Use the URLFetch Service to do a POST on the URL.' + +} + +shortcutFor('com.google.appengine.api.datastore.DatastoreService').accept { + provider = 'Gaelyk' + method name: 'getProperty', + type: 'com.google.appengine.api.datastore.Entity', + params: [kind: 'java.lang.String', property: 'java.lang.String'], + doc: 'Gets datastore kind property.' + + method name: 'getProperties', + type: 'java.util.List', + params: [options: 'com.google.appengine.api.datastore.FetchOptions'], + doc: 'Gets all datastore kinds and their properties.' + + method name: 'getProperties', + type: 'java.util.List', + params: [options: 'com.google.appengine.api.datastore.FetchOptions', closure: 'groovy.lang.Closure'], + doc: 'Gets all datastore kinds and their properties. The closure lets you apply additional filters to your query.' + + method name: 'getProperties', + type: 'java.util.List', + params: [kind: 'java.lang.String', options: 'com.google.appengine.api.datastore.FetchOptions'], + doc: 'Gets datastore kind properties.' + + method name: 'getProperties', + type: 'java.util.List', + params: [kind: 'java.lang.String', options: 'com.google.appengine.api.datastore.FetchOptions', closure: 'groovy.lang.Closure'], + doc: 'Gets datastore kind properties. The closure lets you apply additional filters to your query.' + + method name: 'getProperties', + type: 'java.util.List', + doc: 'Gets all datastore kinds and their properties.' + + property name: 'properties', + type: 'java.util.List', + doc: 'Gets all datastore kinds and their properties.' + + method name: 'getProperties', + type: 'java.util.List', + params: [closure: 'groovy.lang.Closure'], + doc: 'Gets all datastore kinds and their properties. The closure lets you apply additional filters to your query.' + + method name: 'getProperties', + type: 'java.util.List', + params: [kind: 'java.lang.String'], + doc: 'Gets datastore kind properties.' + + method name: 'getProperties', + type: 'java.util.List', + params: [kind: 'java.lang.String', closure: 'groovy.lang.Closure'], + doc: 'Gets datastore kind properties. The closure lets you apply additional filters to your query.' + + method name: 'withTransaction', + type: 'com.google.appengine.api.datastore.Transaction', + params: [closure: 'groovy.lang.Closure'], + doc: '''With this method, transaction handling is done transparently. +The transaction is committed if the closure executed properly. +The transaction is rollbacked if anything went wrong. +You can use this method as follows: + +datastore.withTransaction { transaction -> + // do something in that transaction +} +''' + + method name: 'getAsync', + type: 'com.google.appengine.api.datastore.AsyncDatastoreService', + doc: 'The asynchronous datastore service.' + + property name: 'async', + type: 'com.google.appengine.api.datastore.AsyncDatastoreService', + doc: 'The asynchronous datastore service.' + + method name: 'getNamespaces', + type: 'java.util.List', + params: [options: 'com.google.appengine.api.datastore.FetchOptions'], + doc: 'Gets datastore namespaces.' + + method name: 'getNamespaces', + type: 'java.util.List', + params: [options: 'com.google.appengine.api.datastore.FetchOptions', clsoure: 'groovy.lang.Closure'], + doc: 'Gets datastore namespaces. The closure lets you apply additional filters to your query.' + + method name: 'getNamespaces', + type: 'java.util.List', + doc: 'Gets datastore namespaces.' + + property name: 'namespaces', + type: 'java.util.List', + doc: 'Gets datastore namespaces.' + + method name: 'getNamespaces', + type: 'java.util.List', + params: [arg1: 'groovy.lang.Closure'], + doc: 'Gets datastore namespaces. The closure lets you apply additional filters to your query.' + + method name: 'getKinds', + type: 'java.util.List', + params: [options: 'com.google.appengine.api.datastore.FetchOptions'], + doc: 'Gets datastore kinds.' + + method name: 'Gets datastore kinds. The closure lets you apply additional filters to your query.', + type: 'java.util.List', + params: [options: 'com.google.appengine.api.datastore.FetchOptions', closure: 'groovy.lang.Closure'], + doc: 'Gets datastore kinds. The closure lets you apply additional filters to your query.' + + method name: 'getKinds', + type: 'java.util.List', + doc: 'Gets datastore kinds.' + + property name: 'kinds', + type: 'java.util.List', + doc: 'Gets datastore kinds.' + + method name: 'getKinds', + type: 'java.util.List', + params: [arg1: 'groovy.lang.Closure'], + doc: 'Gets datastore kinds. The closure lets you apply additional filters to your query.' + +} + + + + +(enclosingCallName("transform") & inClosure() & enclosingCallDeclaringType('com.google.appengine.api.images.Image')).accept{ + provider = 'Gaelyk' + method name: 'resize', + type: 'com.google.appengine.api.images.Image', + params: [width: 'int', height: 'int'], + doc: 'Resizes the image.' + method name: 'crop', + type: 'com.google.appengine.api.images.Image', + params: [leftX: 'double', topY: 'double', rightY: 'double', bottomY: 'double'], + doc: 'Croppes the image.' + + method name: 'horizontal', + type: 'com.google.appengine.api.images.Image', + params: [flip: boolean], + doc: 'Applies the horizontal flip.' + + method name: 'vertical', + type: 'com.google.appengine.api.images.Image', + params: [flip: boolean], + doc: 'Applies the vertical flip.' + + method name: 'feeling', + type: 'com.google.appengine.api.images.Image', + params: [lucky: boolean], + doc: 'Applies the "I\'m feeling lucky" transformation.' + + property name: 'lucky', + type: boolean, + doc: 'Use after the "feeling" keyword' + + property name: 'flip', + type: boolean, + doc: 'Use after the "horizontal" or the "vertical" keyword' + +} + +shortcutFor('com.google.appengine.api.images.Image').accept { + provider = 'Gaelyk' + + method name: 'transform', + type: 'com.google.appengine.api.images.Image', + params: [closure: 'groovy.lang.Closure'], + doc: '''Image transform DSL. +

+bytes.image.transform {
+    resize 100, 100
+    crop 0.1, 0.1, 0.9, 0.9
+    flip horizontal
+    flip vertical
+    rotate 90
+    feeling lucky
+}
+
''' + + method name: 'resize', + type: 'com.google.appengine.api.images.Image', + params: [width: 'int', height: 'int'], + doc: '''Create a new resized image. +

+ def thumbnail = image.resize(100, 100)
+
''' + + method name: 'rotate', + type: 'com.google.appengine.api.images.Image', + params: [degrees: 'int'], + doc: '''Create a new rotated image. + +

+ def rotated = image.rotate(90)
+
''' + + method name: 'crop', + type: 'com.google.appengine.api.images.Image', + params: [leftX: 'double', topY: 'double', rightY: 'double', bottomY: 'double'], + doc: '''Create a new cropped image. + +

+ def cropped = image.crop(0.1, 0.1, 0.9, 0.9)
+
''' + + method name: 'horizontalFlip', + type: 'com.google.appengine.api.images.Image', + doc: '''Create a new image flipped horizontally. + +

+ def himage = image.horizontalFlip()
+
''' + + method name: 'verticalFlip', + type: 'com.google.appengine.api.images.Image', + doc: '''Create a new image flipped vertically. + +

+ def vimage = image.verticalFlip()
+
''' + + method name: 'imFeelingLucky', + type: 'com.google.appengine.api.images.Image', + doc: '''Create a new image applying the "I'm feeling lucky" transformation. + +

+ def adjusted = image.iAmFeelingLucky()
+
''' + +} + +shortcutFor('com.google.appengine.api.blobstore.BlobKey').accept { + provider = 'Gaelyk' + method name: 'getSize', + type: 'long', + doc: 'The size of the blob.' + + property name: 'size', + type: 'long', + doc: 'The size of the blob.' + + method name: 'delete', + type: 'void', + doc: 'Delete the blob associated with this blob key.' + + method name: 'getContentType', + type: 'java.lang.String', + doc: 'The content-type of the blob.' + + property name: 'contentType', + type: 'java.lang.String', + doc: 'The content-type of the blob.' + + method name: 'withStream', + type: 'java.lang.Object', + params: [closure: 'groovy.lang.Closure'], + doc: '''Creates an InputStream over the blob. +The stream is passed as parameter of the closure. +This methods takes care of properly opening and closing the stream. +You can use this method as follows: +

+blobKey.withStream { inputstream -> ... }
+
''' + + method name: 'withReader', + type: 'java.lang.Object', + params: [encoding: 'java.lang.String', c: 'groovy.lang.Closure'], + doc: '''Creates a (buffered) Reader over the blob with a specified encoding. +The reader is passed as parameter of the closure. +This methods takes care of properly opening and closing the reader and underlying stream. +You can use this method as follows: +

+blobKey.withReader("UTF-8") { reader -> ... }
+
''' + + method name: 'withReader', + type: 'java.lang.Object', + params: [closure: 'groovy.lang.Closure'], + doc: '''Creates a (buffered) Reader over the blob using UTF-8 as default encoding. +The reader is passed as parameter of the closure. +This methods takes care of properly opening and closing the reader and underlying stream. +You can use this method as follows: +

+ blobKey.withReader { reader -> ... }
+
''' + + method name: 'getInfo', + type: 'com.google.appengine.api.blobstore.BlobInfo', + doc: '''Get the BlobInfo associated with a blob key with: +

+ blobKey.info
+
''' + + property name: 'info', + type: 'com.google.appengine.api.blobstore.BlobInfo', + doc: '''Get the BlobInfo associated with a blob key with: +

+ blobKey.info
+
''' + + method name: 'getFilename', + type: 'java.lang.String', + doc: 'The name of the file stored in the blob.' + + property name: 'filename', + type: 'java.lang.String', + doc: 'The name of the file stored in the blob.' + + method name: 'getCreation', + type: 'java.util.Date', + doc: 'The creation date of the file stored in the blob.' + + property name: 'creation', + type: 'java.util.Date', + doc: 'The creation date of the file stored in the blob.' + + method name: 'serve', + type: 'void', + params: [response: 'javax.servlet.http.HttpServletResponse', range: 'com.google.appengine.api.blobstore.ByteRange'], + doc: 'Serve a range of the blob to the response.' + + method name: 'Serve a range of the blob to the response.', + type: 'void', + params: [response: 'javax.servlet.http.HttpServletResponse', range: 'groovy.lang.IntRange'], + doc: 'TODO' + + method name: 'serve', + type: 'void', + params: [response: 'javax.servlet.http.HttpServletResponse'], + doc: 'Serve a range of the blob to the response.' + + method name: 'fetchData', + type: 'byte[]', + params: [start: 'long', end: 'long'], + doc: 'Fetch a segment of a blob.' + + method name: 'fetchData', + type: 'byte[]', + params: [range: 'groovy.lang.IntRange'], + doc: '''Fetch a segment of a blob +

+ blobKey.fetchData 1000..2000
+
''' + + method name: 'fetchData', + type: 'byte[]', + params: [range: 'com.google.appengine.api.blobstore.ByteRange'], + doc: '''Fetch a segment of a blob''' + + method name: 'getImage', + type: 'com.google.appengine.api.images.Image', + doc: '''Fetch an image stored in the blobstore. +

+def image = blobKey.image
+// equivalent of ImagesServiceFactory.makeImageFromBlob(selfKey)
+
''' + + property name: 'image', + type: 'com.google.appengine.api.images.Image', + doc: '''Fetch an image stored in the blobstore. +

+def image = blobKey.image
+// equivalent of ImagesServiceFactory.makeImageFromBlob(selfKey)
+
''' + +} + + +// scaffolded + +shortcutFor('com.google.appengine.api.datastore.Key').accept { + provider = 'Gaelyk' + method name: 'delete', + type: 'void', + doc: '''Delete the entity represented by that key, from the data store. +Usage: key.delete() ''' + + method name: 'asyncDelete', + type: 'java.util.concurrent.Future', + doc: '''Delete the entity represented by that key, from the data store. +Usage: key.asyncDelete() ''' + +} + +shortcutFor('com.google.appengine.api.files.AppEngineFile').accept { + provider = 'Gaelyk' + method name: 'delete', + type: 'void', + doc: 'Delete an AppEngineFile file from the blobstore.' + + method name: 'withReader', + type: 'com.google.appengine.api.files.AppEngineFile', + useNamedArgs: true, + params: [encoding: String, locked: boolean, finalize: true, c: 'groovy.lang.Closure'], + doc: '''Method creating a reader for the AppEngineFile, read textual content from it, and closes it when done. + +

+ def file = files.fromPath(someStringPath)
+
+ // with default options
+ file.withReader { reader ->
+     log.info reader.text
+ }
+
+ // with specific options:
+ file.withReader(encoding: "US-ASCII", locked: true) { reader ->
+     log.info reader.text
+ }
+
''' + + method name: 'withReader', + type: 'com.google.appengine.api.files.AppEngineFile', + params: [c: 'groovy.lang.Closure'], + doc: '''Method creating a reader for the AppEngineFile, read textual content from it, and closes it when done. + +

+ def file = files.fromPath(someStringPath)
+
+ // with default options
+ file.withReader { reader ->
+     log.info reader.text
+ }
+
+ // with specific options:
+ file.withReader(encoding: "US-ASCII", locked: true) { reader ->
+     log.info reader.text
+ }
+
''' + + method name: 'withOutputStream', + type: 'com.google.appengine.api.files.AppEngineFile', + useNamedArgs: true, + params: [encoding: String, locked: boolean, finalize: true, c: 'groovy.lang.Closure'], + doc: '''Method creating an output stream for the AppEngineFile, writing bynary content to it, and closes it when done. + +

+ def file = files.createNewBlobFile("text/plain", "hello.txt")
+
+ // with default options
+ file.withOutputStream { stream ->
+     stream << "some content".bytes
+ }
+
+ // with specific options:
+ file.withOutputStream(locked: true, finalize: false) { writer ->
+     stream << "some content".bytes
+ }
+
''' + + method name: 'withOutputStream', + type: 'com.google.appengine.api.files.AppEngineFile', + params: [c: 'groovy.lang.Closure'], + doc: '''Method creating an output stream for the AppEngineFile, writing bynary content to it, and closes it when done. + +

+ def file = files.createNewBlobFile("text/plain", "hello.txt")
+
+ // with default options
+ file.withOutputStream { stream ->
+     stream << "some content".bytes
+ }
+
+ // with specific options:
+ file.withOutputStream(locked: true, finalize: false) { writer ->
+     stream << "some content".bytes
+ }
+
''' + + method name: 'withInputStream', + type: 'com.google.appengine.api.files.AppEngineFile', + useNamedArgs: true, + params: [encoding: String, locked: boolean, finalize: true, c: 'groovy.lang.Closure'], + doc: '''Method creating a buffered input stream for the AppEngineFile, read binary content from it, and closes it when done. + +

+ def file = files.fromPath(someStringPath)
+
+ // with default options
+ file.withInputStream { stream ->
+     // read from the buffered input stream
+ }
+
+ // with specific options:
+ file.withInputStream(locked: true) { stream ->
+     // read from the buffered input stream
+ }
+
''' + + method name: 'withInputStream', + type: 'com.google.appengine.api.files.AppEngineFile', + params: [c: 'groovy.lang.Closure'], + doc: '''Method creating a buffered input stream for the AppEngineFile, read binary content from it, and closes it when done. + +

+ def file = files.fromPath(someStringPath)
+
+ // with default options
+ file.withInputStream { stream ->
+     // read from the buffered input stream
+ }
+
+ // with specific options:
+ file.withInputStream(locked: true) { stream ->
+     // read from the buffered input stream
+ }
+
''' + + method name: 'withWriter', + type: 'com.google.appengine.api.files.AppEngineFile', + useNamedArgs: true, + params: [encoding: String, locked: boolean, finalize: true, c: 'groovy.lang.Closure'], + doc: '''Method creating a writer for the AppEngineFile, writing textual content to it, and closes it when done. + +

+ def file = files.createNewBlobFile("text/plain", "hello.txt")
+
+ // with default options
+ file.withWriter { writer ->
+     writer << "some content"
+ }
+
+ // with specific options:
+ file.withWriter(encoding: "US-ASCII", locked: true, finalize: false) { writer ->
+     writer << "some content
+ }
+
''' + + method name: 'withWriter', + type: 'com.google.appengine.api.files.AppEngineFile', + params: [c: 'groovy.lang.Closure'], + doc: '''Method creating a writer for the AppEngineFile, writing textual content to it, and closes it when done. + +

+ def file = files.createNewBlobFile("text/plain", "hello.txt")
+
+ // with default options
+ file.withWriter { writer ->
+     writer << "some content"
+ }
+
+ // with specific options:
+ file.withWriter(encoding: "US-ASCII", locked: true, finalize: false) { writer ->
+     writer << "some content
+ }
+
''' + + method name: 'getBlobKey', + type: 'com.google.appengine.api.blobstore.BlobKey', + doc: '''Retrieves the blob key associated with an App Engine file. +

+ def file = files.createNewBlobFile("text/plain")
+ def key = file.blobKey
+ // equivalent of FileServiceFactory.fileService.getBlobKey(file)
+
''' + + property name: 'blobKey', + type: 'com.google.appengine.api.blobstore.BlobKey', + doc: '''Retrieves the blob key associated with an App Engine file. +

+ def file = files.createNewBlobFile("text/plain")
+ def key = file.blobKey
+ // equivalent of FileServiceFactory.fileService.getBlobKey(file)
+
''' + +} + +shortcutFor('com.google.appengine.api.mail.MailService').accept { + provider = 'Gaelyk' + method name: 'send', + type: 'void', + useNamedArgs: true, + params: [attachments: Collection, bcc: Collections, cc: Collection, htmlBody: String, replyTo: String, sender: String, textBody: String, to: Collection], + doc: '''Additional send() method taking a map as parameter. +The map can contain the normal properties of the +MailService.Message class.''' + + method name: 'sendToAdmins', + type: 'void', + useNamedArgs: true, + params: [attachments: Collection, bcc: Collections, cc: Collection, htmlBody: String, replyTo: String, sender: String, textBody: String, to: Collection], + doc: '''Additional sendToAdmins() method for sending emails to the application admins. +This method is taking a map as parameter. +The map can contain the normal properties of the +MailService.Message class.''' + + method name: 'parseMessage', + type: 'javax.mail.internet.MimeMessage', + params: [request: 'javax.servlet.http.HttpServletRequest'], + doc: 'Parses an incoming email message coming from the request into a MimeMessage' + +} + +shortcutFor('com.google.appengine.api.xmpp.XMPPService').accept { + provider = 'Gaelyk' + method name: 'send', + type: 'com.google.appengine.api.xmpp.SendResponse', + useNamedArgs: true, + params: [from: String, to: List, type: 'com.google.appengine.api.xmpp.MessageType', body: String, xml: Closure], + doc: '''Send an XMPP/Jabber message with the XMPP service using a map of attributes to build the message. +

+Possible attributes are: +

''' + + method name: 'sendInvitation', + type: 'void', + params: [jabberId: 'java.lang.String'], + doc: 'Send a chat invitation to a Jabber ID.' + + method name: 'sendInvitation', + type: 'void', + params: [jabberId: 'java.lang.String', jabberIdFrom: 'java.lang.String'], + doc: 'Send a chat invitation to a Jabber ID from another Jabber ID.' + + method name: 'getPresence', + type: 'com.google.appengine.api.xmpp.Presence', + params: [jabberId: 'java.lang.String'], + doc: 'Get the presence of a Jabber ID.' + + method name: 'getPresence', + type: 'com.google.appengine.api.xmpp.Presence', + params:[jabberId: 'java.lang.String', jabberIdFrom: 'java.lang.String'], + doc: 'Get the presence of a Jabber ID.' + + method name: 'parsePresence', + type: 'com.google.appengine.api.xmpp.Presence', + params: [request: 'javax.servlet.http.HttpServletRequest'], + doc: ''' Override the GAE SDK XMPPService#parsePresence as it hard-codes the path for the presence handler, +thus preventing from using Gaelyk's routing to point at our own handler.''' + + method name: 'parseSubscription', + type: 'com.google.appengine.api.xmpp.Subscription', + params: [request: 'javax.servlet.http.HttpServletRequest'], + doc: '''Override the GAE SDK XMPPService#parseSubscription as it hard-codes the path for the subscription handler, +thus preventing from using Gaelyk's routing to point at our own handler.''' + +} + +shortcutFor('com.google.appengine.api.channel.ChannelService').accept { + provider = 'Gaelyk' + method name: 'send', + type: 'void', + params: [clientId: 'java.lang.String', message: 'java.lang.String'], + doc: 'Send a message through the Channel service.' + +} + +shortcutFor('javax.servlet.http.HttpServletResponse').accept { + provider = 'Gaelyk' + method name: 'getHeaders', + type: 'java.util.Map', + doc: '''Adds a fake getHeaders() method to HttpServletResponse. +It allows the similar subscript notation syntax of request, +but for setting or overriding a header on the response +(ie. calling response.setHeader()). +It also allows the leftShift notation for adding a header to the response +(ie. calling response.addHeader(). + +

+ // sets or overrides the header 'a'
+ response.headers['a'] == 'b'
+
+ // adds an additional value to an existing header
+ // or sets a first value for a non-existant header
+ response.headers['a'] << 'b' 
+
''' + + property name: 'headers', + type: 'java.util.Map', + doc: '''Adds a fake getHeaders() method to HttpServletResponse. +It allows the similar subscript notation syntax of request, +but for setting or overriding a header on the response +(ie. calling response.setHeader()). +It also allows the leftShift notation for adding a header to the response +(ie. calling response.addHeader(). + +

+ // sets or overrides the header 'a'
+ response.headers['a'] == 'b'
+ 
+ // adds an additional value to an existing header
+ // or sets a first value for a non-existant header
+ response.headers['a'] << 'b' 
+
''' + +} + +shortcutFor('com.google.appengine.api.urlfetch.HTTPResponse').accept { + provider = 'Gaelyk' + method name: 'getText', + type: 'java.lang.String', + params: [encoding: 'java.lang.String'], + doc: 'Gets the text of the response.' + + method name: 'getText', + type: 'java.lang.String', + doc: 'Gets the text of the response.' + + property name: 'text', + type: 'java.lang.String', + doc: 'Gets the text of the response.' + + method name: 'getStatusCode', + type: 'int', + doc: 'The HTTP status code (synonym of getResponseCode()).' + + property name: 'statusCode', + type: 'int', + doc: 'The HTTP status code (synonym of getResponseCode()).' + + method name: 'getHeadersMap', + type: 'java.util.Map', + doc: 'A convenient Map of HTTP Headers from the response.' + + property name: 'headersMap', + type: 'java.util.Map', + doc: 'A convenient Map of HTTP Headers from the response.' + +} + +shortcutFor('com.google.appengine.api.images.CompositeTransform').accept { + provider = 'Gaelyk' + method name: 'rightShift', + type: 'com.google.appengine.api.images.CompositeTransform', + params: [transform: 'com.google.appengine.api.images.Transform'], + doc: '''Use the rightShift operator, >>, to "pre-concatenate" a transform to the composite transform. +

+def cropTransform = ...
+def rotateTransform = ...
+
+croptTransform >> rotateTransform
+
''' + + method name: 'leftShift', + type: 'com.google.appengine.api.images.CompositeTransform', + params: [transform: 'com.google.appengine.api.images.Transform'], + doc: '''Use the leftShift operator, <<, to concatenate a transform to the composite transform. +

+def cropTransform = ...
+def rotateTransform = ...
+
+croptTransform << rotateTransform
+
''' + +} + +shortcutFor('com.google.appengine.api.xmpp.Message').accept { + provider = 'Gaelyk' + method name: 'getFrom', + type: 'java.lang.String', + doc: 'Get the sender Jabber ID of the message in the form of a String.' + + property name: 'from', + type: 'java.lang.String', + doc: 'Get the sender Jabber ID of the message in the form of a String.' + + method name: 'getXml', + type: 'groovy.util.slurpersupport.GPathResult', + doc: 'Get the XML content of this message (if it\'s an XML message) in the form of a DOM parsed with XmlSlurper.' + + property name: 'xml', + type: 'groovy.util.slurpersupport.GPathResult', + doc: 'Get the XML content of this message (if it\'s an XML message) in the form of a DOM parsed with XmlSlurper..' + + method name: 'getRecipients', + type: 'java.util.List', + doc: 'Gets the list of recipients of this message in the form of a list of Jabber ID strings.' + + property name: 'recipients', + type: 'java.util.List', + doc: 'Gets the list of recipients of this message in the form of a list of Jabber ID strings.' + +} + +shortcutFor('com.google.appengine.api.capabilities.CapabilitiesService').accept { + provider = 'Gaelyk' + method name: 'getAt', + type: 'com.google.appengine.api.capabilities.CapabilityStatus', + params: [capability: 'com.google.appengine.api.capabilities.Capability'], + doc: '''Query the status of the various App Engine services. + +

+import static com.google.appengine.api.capabilities.Capability.*
+import static com.google.appengine.api.capabilities.CapabilityStatus.*
+
+capabilities[DATASTORE] == ENABLED
+
''' + +} + +shortcutFor('java.lang.String').accept { + provider = 'Gaelyk' + method name: 'asType', + type: 'java.lang.Object', + params: [cls: 'java.lang.Class'], + doc: '''Converter method for converting strings into various GAE specific types +

+ "foo@bar.com" as Email
+ "http://www.google.com" as Link
+ "+3361234543" as PhoneNumber
+ "50 avenue de la Madeleine, Paris" as PostalAddress
+ "groovy" as DatastoreCategory
+ "32" as Rating
+ "long text" as Text
+ "foobar" as BlobKey
+ "foo@gmail.com" as JID
+
''' + +} + +shortcutFor('java.lang.Object').accept { + provider = 'Gaelyk' + method name: 'asType', + type: 'java.lang.Object', + params: [arg1: 'java.lang.Class'], + doc: '''Gaelyk supports a simplistic object/entity mapping, thanks to type coercion. +You can use this type coercion mechanism to coerce POJOs/POGOs and datastore Entities. +The Entity kind will be the simple name of the POJO/POGO (same approach as Objectify). +So with this mechanism, you can do: + +

+ class Person { String name, int age }
+
+ def p = new Person(name: "Guillaume", age: 33)
+ def e = p as Entity
+
+ assert p.name == e.name
+ assert p.age == e.age
+
''' + +} + +shortcutFor('java.lang.Integer').accept { + provider = 'Gaelyk' + method name: 'asType', + type: 'java.lang.Object', + params: [cls: 'java.lang.Class'], + doc: '''Converter method for converting an integer into a Rating instance +

+ 32 as Rating
+
''' + +} + +shortcutFor('byte[]').accept { + provider = 'Gaelyk' + method name: 'asType', + type: 'java.lang.Object', + params: [cls: 'java.lang.Class'], + doc: '''Converter method for converting a byte array into a Blob or ShortBlob instance +

+ "some byte".getBytes() as Blob
+ "some byte".getBytes() as ShortBlob
+
''' + + method name: 'getImage', + type: 'com.google.appengine.api.images.Image', + doc: '''Transform a byte array into an Image. + +

+def byteArray = ...
+def image = byteArray.image
+
''' + + property name: 'image', + type: 'com.google.appengine.api.images.Image', + doc: '''Transform a byte array into an Image. + +

+def byteArray = ...
+def image = byteArray.image
+
''' + +} + +shortcutFor('java.util.List').accept { + provider = 'Gaelyk' + method name: 'asType', + type: 'java.lang.Object', + params: [geoPtClass: 'java.lang.Class'], + doc: '''Converter method for converting a pair of numbers (in a list) into a GeoPt instance +

+ [45.32, 54.54f] as GeoPt
+
''' + +} + +shortcutFor('groovy.lang.IntRange').accept { + provider = 'Gaelyk' + method name: 'asType', + type: 'java.lang.Object', + params: [byteRangeClass: 'java.lang.Class'], + doc: '''Converter method for converting an int range to a blobstore ByteRange: +

+    300..400 as ByteRange
+
+Note that Groovy already allowed: [300, 400] as ByteRange.''' + +} + +shortcutFor('com.google.appengine.api.capabilities.CapabilityStatus').accept { + provider = 'Gaelyk' + method name: 'asBoolean', + type: 'boolean', + doc: '''Coerces a capability status into a boolean. +This mechanism is used by the "Groovy Truth".''' + +} + + +(shortcutFor('java.lang.Class')| shortcutFor('com.google.appengine.api.NamespaceManager')).accept { + provider = 'Gaelyk' + + method name: 'of', + type: 'void', + isStatic: true, + params: [namespace: 'java.lang.String', c: 'groovy.lang.Closure'], + doc: '''Use a namespace in the context of the excution of the closure. +This method will save the original namespace and restore it afterwards. + +

+namespace.of('test') { ... }
+
''' + +} + +shortcutFor('java.util.Map').accept { + provider = 'Gaelyk' + method name: 'toQueryString', + type: 'java.lang.String', + doc: 'Transforms a map of key / value pairs into a properly URL encoded query string.' + +} + +shortcutFor('com.google.appengine.api.xmpp.SendResponse').accept { + provider = 'Gaelyk' + method name: 'isSuccessful', + type: 'boolean', + doc: 'Checks the status of the sending of the message was successful for all its recipients.' + + property name: 'successful', + type: 'boolean', + doc: 'Checks the status of the sending of the message was successful for all its recipients.' + +} + +shortcutFor('javax.servlet.http.HttpServletRequest').accept { + provider = 'Gaelyk' + method name: 'parseXmppFormData', + type: 'java.util.Map', + doc: '''Parse the form-data from the Jabber requests, +as it contains useful information like presence and subscription details, etc.''' + +} + +shortcutFor('java.io.File').accept { + provider = 'Gaelyk' + method name: 'getImage', + type: 'com.google.appengine.api.images.Image', + doc: 'Create an image from a file.' + + property name: 'image', + type: 'com.google.appengine.api.images.Image', + doc: 'Create an image from a file.' + +} + +shortcutFor('com.google.appengine.api.files.FileService').accept { + provider = 'Gaelyk' + method name: 'fromPath', + type: 'com.google.appengine.api.files.AppEngineFile', + params: [path: 'java.lang.String'], + doc: '''Get a reference to an App Engine file from its path. +

+ def path = "...some path..."
+ def file = files.fromPath(path)
+// equivalent of new AppEngineFile(path)
+
''' + +} + +shortcutFor('com.google.appengine.api.LifecycleManager').accept { + provider = 'Gaelyk' + method name: 'setShutdownHook', + type: 'void', + params: [hook: 'groovy.lang.Closure'], + doc: '''Shortcut to use closures as shutdown hooks. +

+ lifecycle.shutdownHook = { ...shutdown logic... }
+
''' + + property name: 'shutdownHook', + type: 'groovy.lang.Closure', + doc: '''Shortcut to use closures as shutdown hooks. +

+ lifecycle.shutdownHook = { ...shutdown logic... }
+
''' + +} + diff --git a/src/gaelyk.gdsl b/src/gaelyk.gdsl new file mode 100644 index 0000000..0013315 --- /dev/null +++ b/src/gaelyk.gdsl @@ -0,0 +1,58 @@ +def all = context(scope: scriptScope(), filetypes: ['groovy', 'gtpl']) + +def jabber = context(scope: scriptScope(name: 'jabber.groovy')) +def mail = context(scope: scriptScope(name: 'email.groovy')) + +def routes = context(scope: scriptScope(name: 'routes.groovy')) + +contributor([all, jabber, mail]) { + property name: "request", type: "javax.servlet.http.HttpServletRequest" + property name: "response", type: "javax.servlet.http.HttpServletResponse" + property name: "context", type: "javax.servlet.ServletContext" + property name: "application", type: "javax.servlet.ServletContext" + property name: "session", type: "javax.servlet.http.HttpSession" + property name: "params", type: "java.util.Map" + property name: "headers", type: "java.util.Map" + property name: "out", type: "java.io.PrintWriter" + property name: "sout", type: "javax.servlet.ServletOutputStream" + property name: "html", type: "groovy.xml.MarkupBuilder" +} + +contributor([all, jabber, mail, routes]) { + property name: "app", type: "java.util.Map" + property name: "queues", type: "com.google.appengine.api.labs.taskqueue.Queue" + property name: "defaultQueue", type: "com.google.appengine.api.labs.taskqueue.Queue" + property name: "mail", type: "com.google.appengine.api.mail.MailService" + property name: "namespace", type: "com.google.appengine.api.NamespaceManager" + property name: "logger", type: "groovyx.gaelyk.logging.LoggerAccessor" + property name: "log", type: "groovyx.gaelyk.logging.GroovyLogger" + + property name: "datastore", type: "com.google.appengine.api.datastore.DatastoreService" + property name: "memcache", type: "com.google.appengine.api.memcache.MemcacheService" + property name: "urlFetch", type: "com.google.appengine.api.urlfetch.URLFetchService" + property name: "images", type: "groovyx.gaelyk.ImagesServiceWrapper" + property name: "users", type: "com.google.appengine.api.users.UserService" + property name: "user", type: "com.google.appengine.api.users.User" + property name: "xmpp", type: "com.google.appengine.api.xmpp.XMPPService" + property name: "blobstore", type: "com.google.appengine.api.blobstore.BlobstoreService" + property name: "files", type: "com.google.appengine.api.files.FileService" + property name: "oauth", type: "com.google.appengine.api.oauth.OAuthService" + + property name: "localMode", type: "java.lang.Boolean" + + method name: 'forward', type: 'void', params: [path: 'java.lang.String'] + method name: 'include', type: 'void', params: [path: 'java.lang.String'] + method name: 'redirect', type: 'void', params: [path: 'java.lang.String'] +} + +contributor([jabber]) { + property name: "message", type: "com.google.appengine.api.xmpp.Message" +} + +contributor([mail]) { + property name: "message", type: "javax.mail.MimeMessage" +} + +contributor([routes]) { + +} \ No newline at end of file diff --git a/src/main/bloogaey.iml b/src/main/bloogaey.iml new file mode 100644 index 0000000..447f02f --- /dev/null +++ b/src/main/bloogaey.iml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + dffedfc3dfcddfd8dfc5dfdfdf9bdf93df9ddf9d + /Library/GoogleAppEngine + glaforge@gmail.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/groovy/bloogy/Utilities.groovy b/src/main/groovy/bloogy/Utilities.groovy new file mode 100644 index 0000000..9d6ca09 --- /dev/null +++ b/src/main/groovy/bloogy/Utilities.groovy @@ -0,0 +1,19 @@ +package bloogy + +import java.text.Normalizer + +class Utilities { + + /** + * Transform a post article into a simplified url-friendly string. + * "Cool! A groovy, very groovy, title :-)" is transformed into "cool-a-groovy-very-groovy-title + */ + static String streamline(String title) { + Normalizer.normalize(title, Normalizer.Form.NFD) + .replaceAll("\\p{InCombiningDiacriticalMarks}+", "") + .replaceAll(/\W+/, '-') + .replaceAll(/(-+$|^-+)/, '') + .toLowerCase() + } +} + diff --git a/war/.gradle/1.0-milestone-3/taskArtifacts/cache.bin b/war/.gradle/1.0-milestone-3/taskArtifacts/cache.bin new file mode 100644 index 0000000..5eed77c Binary files /dev/null and b/war/.gradle/1.0-milestone-3/taskArtifacts/cache.bin differ diff --git a/war/.gradle/1.0-milestone-3/taskArtifacts/cache.properties b/war/.gradle/1.0-milestone-3/taskArtifacts/cache.properties new file mode 100644 index 0000000..29fc9ea --- /dev/null +++ b/war/.gradle/1.0-milestone-3/taskArtifacts/cache.properties @@ -0,0 +1 @@ +#Thu Jul 28 16:44:02 CEST 2011 diff --git a/war/WEB-INF/appengine-generated/4HnOt8EnYBQKeGPB3ltJLA b/war/WEB-INF/appengine-generated/4HnOt8EnYBQKeGPB3ltJLA new file mode 100644 index 0000000..faee63f Binary files /dev/null and b/war/WEB-INF/appengine-generated/4HnOt8EnYBQKeGPB3ltJLA differ diff --git a/war/WEB-INF/appengine-generated/6TOQGgmWyurVSC6auwgFeg b/war/WEB-INF/appengine-generated/6TOQGgmWyurVSC6auwgFeg new file mode 100644 index 0000000..7848a74 Binary files /dev/null and b/war/WEB-INF/appengine-generated/6TOQGgmWyurVSC6auwgFeg differ diff --git a/war/WEB-INF/appengine-generated/9T-Ycn5C0iscyQxIm_hUvg b/war/WEB-INF/appengine-generated/9T-Ycn5C0iscyQxIm_hUvg new file mode 100644 index 0000000..6050843 Binary files /dev/null and b/war/WEB-INF/appengine-generated/9T-Ycn5C0iscyQxIm_hUvg differ diff --git a/war/WEB-INF/appengine-generated/Cx-ZB1zCP9i7a3WWH3HxsQ b/war/WEB-INF/appengine-generated/Cx-ZB1zCP9i7a3WWH3HxsQ new file mode 100644 index 0000000..63da5f9 --- /dev/null +++ b/war/WEB-INF/appengine-generated/Cx-ZB1zCP9i7a3WWH3HxsQ @@ -0,0 +1,82 @@ + + + + + + + + + image/svg+xml + + + + + + + DOSPE + + diff --git a/war/WEB-INF/appengine-generated/EUBolXRDEyMInhdeMiu-Qg b/war/WEB-INF/appengine-generated/EUBolXRDEyMInhdeMiu-Qg new file mode 100644 index 0000000..819dace Binary files /dev/null and b/war/WEB-INF/appengine-generated/EUBolXRDEyMInhdeMiu-Qg differ diff --git a/war/WEB-INF/appengine-generated/Eu90pcmrEog-aSx5Gb_P_w b/war/WEB-INF/appengine-generated/Eu90pcmrEog-aSx5Gb_P_w new file mode 100644 index 0000000..8783613 Binary files /dev/null and b/war/WEB-INF/appengine-generated/Eu90pcmrEog-aSx5Gb_P_w differ diff --git a/war/WEB-INF/appengine-generated/Fy1qCGs5duw2iRRmug5VeA b/war/WEB-INF/appengine-generated/Fy1qCGs5duw2iRRmug5VeA new file mode 100644 index 0000000..819dace Binary files /dev/null and b/war/WEB-INF/appengine-generated/Fy1qCGs5duw2iRRmug5VeA differ diff --git a/war/WEB-INF/appengine-generated/KhYgYI9EIYcnCljoTt_5GQ b/war/WEB-INF/appengine-generated/KhYgYI9EIYcnCljoTt_5GQ new file mode 100644 index 0000000..819dace Binary files /dev/null and b/war/WEB-INF/appengine-generated/KhYgYI9EIYcnCljoTt_5GQ differ diff --git a/war/WEB-INF/appengine-generated/UPFJu4Y17iwgTTHmPS-BkQ b/war/WEB-INF/appengine-generated/UPFJu4Y17iwgTTHmPS-BkQ new file mode 100644 index 0000000..eb32985 Binary files /dev/null and b/war/WEB-INF/appengine-generated/UPFJu4Y17iwgTTHmPS-BkQ differ diff --git a/war/WEB-INF/appengine-generated/datastore-indexes-auto.xml b/war/WEB-INF/appengine-generated/datastore-indexes-auto.xml new file mode 100644 index 0000000..510f376 --- /dev/null +++ b/war/WEB-INF/appengine-generated/datastore-indexes-auto.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/war/WEB-INF/appengine-generated/local_db.bin b/war/WEB-INF/appengine-generated/local_db.bin new file mode 100644 index 0000000..44014be Binary files /dev/null and b/war/WEB-INF/appengine-generated/local_db.bin differ diff --git a/war/WEB-INF/appengine-generated/pRaJU4gfyQUKQ1QSnD78xA b/war/WEB-INF/appengine-generated/pRaJU4gfyQUKQ1QSnD78xA new file mode 100644 index 0000000..ec9039b Binary files /dev/null and b/war/WEB-INF/appengine-generated/pRaJU4gfyQUKQ1QSnD78xA differ diff --git a/war/WEB-INF/appengine-generated/xGOwZKjDjbsLKIAQoVe-OQ b/war/WEB-INF/appengine-generated/xGOwZKjDjbsLKIAQoVe-OQ new file mode 100644 index 0000000..0485cce Binary files /dev/null and b/war/WEB-INF/appengine-generated/xGOwZKjDjbsLKIAQoVe-OQ differ diff --git a/war/WEB-INF/appengine-generated/yNCR8fJUDnV9_LWawbQiJg b/war/WEB-INF/appengine-generated/yNCR8fJUDnV9_LWawbQiJg new file mode 100644 index 0000000..3ea1a88 Binary files /dev/null and b/war/WEB-INF/appengine-generated/yNCR8fJUDnV9_LWawbQiJg differ diff --git a/war/WEB-INF/appengine-web.xml b/war/WEB-INF/appengine-web.xml new file mode 100644 index 0000000..5e7036d --- /dev/null +++ b/war/WEB-INF/appengine-web.xml @@ -0,0 +1,42 @@ + + glaforge + + 1 + + + true + + + + + + + + + + + + + + + + mail + + + + + + + + + + + + + true + + + + + + diff --git a/war/WEB-INF/classes/bloogy/Utilities.class b/war/WEB-INF/classes/bloogy/Utilities.class new file mode 100644 index 0000000..6bd3239 Binary files /dev/null and b/war/WEB-INF/classes/bloogy/Utilities.class differ diff --git a/war/WEB-INF/groovy/__bootstrap_data__.groovy b/war/WEB-INF/groovy/__bootstrap_data__.groovy new file mode 100644 index 0000000..88b52e8 --- /dev/null +++ b/war/WEB-INF/groovy/__bootstrap_data__.groovy @@ -0,0 +1,91 @@ +import com.google.appengine.api.datastore.Entity +import com.google.appengine.api.datastore.Text + +['posts', 'categories', 'authors'].each { entityKind -> + datastore.execute { select keys from entityKind }*.delete() +} + +new Entity('categories').with { + name = 'Groovy' + description = 'Groovy dynamic language for the JVM' + save() +} + +new Entity('categories').with { + name = 'Java' + description = 'Articles about the Java ecosystem' + save() +} + +new Entity('categories').with { + name = 'Blogosphere' + description = 'About OSS, geek stuff, interesting reads, and more' + save() +} + +def posts = [ + [ + title: 'Groovy 1.8-final is out the door!', + urlTitle: 'groovy-18-final-is-out-the-door', + created: new Date() - 100, + categories: ['Groovy'], + content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent porttitor vulputate augue, ac vulputate purus lobortis non. Suspendisse suscipit elementum consectetur. Mauris adipiscing molestie sem sit amet ornare. Aenean non metus nec nulla sagittis blandit. In sollicitudin, massa quis ultrices ultrices, enim neque tristique purus, eu luctus mi mi eget lectus. Etiam at commodo sem. Maecenas quis rhoncus lacus. In id tempor arcu. Nulla rutrum, odio non ultrices cursus, sapien tortor interdum orci, eget rhoncus quam orci nec diam. Praesent ultrices, dui eu pellentesque tristique, massa sem consequat purus, nec posuere elit quam at purus. Donec volutpat leo quis purus.', + draft: false, + type: 'post' + ], + [ + title: 'GR8Conf Europe 2011 - a conference dedicated to the Groovy Ecosystem!', + urlTitle: 'gr8conf-europe-2011-a-conference-dedicated-to-the-groovy-ecosystem', + created: new Date() - 150, + categories: ['Groovy', 'Java'], + content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent porttitor vulputate augue, ac vulputate purus lobortis non. Suspendisse suscipit elementum consectetur. Mauris adipiscing molestie sem sit amet ornare. Aenean non metus nec nulla sagittis blandit. In sollicitudin, massa quis ultrices ultrices, enim neque tristique purus, eu luctus mi mi eget lectus. Etiam at commodo sem. Maecenas quis rhoncus lacus. In id tempor arcu. Nulla rutrum, odio non ultrices cursus, sapien tortor interdum orci, eget rhoncus quam orci nec diam. Praesent ultrices, dui eu pellentesque tristique, massa sem consequat purus, nec posuere elit quam at purus. Donec volutpat leo quis purus.', + draft: false, + type: 'post' + ], + [ + title: 'Gaelyk 0.7 is out!', + urlTitle: 'gaelyk-07-is-out', + created: new Date() - 1, + categories: ['Groovy'], + content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent porttitor vulputate augue, ac vulputate purus lobortis non. Suspendisse suscipit elementum consectetur. Mauris adipiscing molestie sem sit amet ornare. Aenean non metus nec nulla sagittis blandit. In sollicitudin, massa quis ultrices ultrices, enim neque tristique purus, eu luctus mi mi eget lectus. Etiam at commodo sem. Maecenas quis rhoncus lacus. In id tempor arcu. Nulla rutrum, odio non ultrices cursus, sapien tortor interdum orci, eget rhoncus quam orci nec diam. Praesent ultrices, dui eu pellentesque tristique, massa sem consequat purus, nec posuere elit quam at purus. Donec volutpat leo quis purus.', + draft: false, + type: 'post' + ], + [ + title: 'Gaelyk 1.0 released!', + urlTitle: 'gaelyk-10-released', + created: new Date() + 10, + categories: ['Groovy'], + content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent porttitor vulputate augue, ac vulputate purus lobortis non. Suspendisse suscipit elementum consectetur. Mauris adipiscing molestie sem sit amet ornare. Aenean non metus nec nulla sagittis blandit. In sollicitudin, massa quis ultrices ultrices, enim neque tristique purus, eu luctus mi mi eget lectus. Etiam at commodo sem. Maecenas quis rhoncus lacus. In id tempor arcu. Nulla rutrum, odio non ultrices cursus, sapien tortor interdum orci, eget rhoncus quam orci nec diam. Praesent ultrices, dui eu pellentesque tristique, massa sem consequat purus, nec posuere elit quam at purus. Donec volutpat leo quis purus.', + draft: true, + type: 'post' + ], + [ + title: 'About this site', + urlTitle: 'about-this-site', + created: new Date(), + categories: [], + content: new Text('About this site'), + draft: false, + type: 'page' + ], + [ + title: 'Contact me', + urlTitle: 'contact-me', + created: new Date(), + categories: [], + content: new Text('Contact me'), + draft: false, + type: 'page' + ] +] + +posts.each { item -> + def e = new Entity('posts') + item.each { prop, val -> + e."$prop" = val + } + e.save() +} + +redirect '/' \ No newline at end of file diff --git a/war/WEB-INF/groovy/__testMailParsing2__.groovy b/war/WEB-INF/groovy/__testMailParsing2__.groovy new file mode 100644 index 0000000..2453e83 --- /dev/null +++ b/war/WEB-INF/groovy/__testMailParsing2__.groovy @@ -0,0 +1,46 @@ +import javax.mail.internet.MimeMessage +import javax.mail.Session +import javax.mail.Authenticator +import javax.mail.internet.MimeMultipart + +def msg = new MimeMessage(new Session(new Properties(), new Authenticator() {}), new FileInputStream('msg.txt')) + +def sb = new StringBuilder() + +def handleMultipart +handleMultipart = { MimeMultipart mmp -> + for (int i = 0; i < mmp.count; i++) { + def part = mmp.getBodyPart(i) + if (part.content instanceof MimeMultipart) { + handleMultipart(part.content) + } else { + if (part.contentType.contains('text/plain')) { + + } else if (part.contentType.contains('text/html')) { + + } else if (part.contentType.contains('image/')) { + + } else { + + } + } + } +} + +handleMultipart(msg.content) + +out << sb.toString() + + +/* + +mixed + related + alternative + text/plain + text/html + image-png (inline) + image-png (attachment) + + +*/ diff --git a/war/WEB-INF/groovy/__testMailParsing__.groovy b/war/WEB-INF/groovy/__testMailParsing__.groovy new file mode 100644 index 0000000..2d3675b --- /dev/null +++ b/war/WEB-INF/groovy/__testMailParsing__.groovy @@ -0,0 +1,45 @@ +import javax.mail.internet.MimeMessage +import javax.mail.Session +import javax.mail.Authenticator +import javax.mail.internet.MimeMultipart + +def msg = new MimeMessage(new Session(new Properties(), new Authenticator() {}), new FileInputStream('msg.txt')) + +html.html { + head { + title "Parsed email from GMail" + } + body { + handleMultipart(msg.content) + } +} + +def handleMultipart(MimeMultipart mmp) { + html.div "Parts: ${mmp.count}" + html.div "Content-type: ${mmp.contentType}" + + for (int i = 0; i < mmp.count; i++) { + def part = mmp.getBodyPart(i) + html.h1 "Part #$i: ${part}" + html.h2 "Content ID: ${part.getHeader('Content-ID')}" + html.h2 "X-Attachment ID: ${part.getHeader('X-Attachment-Id')}" + html.h2 "Content-type: $part.contentType" + html.h2 "Content-disposition: $part.disposition" + html.h2 "File name: ${part.fileName}" + if (part.content instanceof MimeMultipart) { + html.blockquote { + handleMultipart(part.content) + } + } else { + if (part.contentType.contains('text/plain')) { + html.mkp.yieldUnescaped part.content + } else if (part.contentType.contains('text/html')) { + html.mkp.yieldUnescaped part.content + } else if (part.contentType.contains('image/')) { + html.img src:"data:${part.contentType.find('image/(.*);')}base64,${part.content.bytes.encodeBase64()}" + } else { + html.mkp.yieldUnescaped part.content.bytes.encodeBase64() + } + } + } +} \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/adminCategories.groovy b/war/WEB-INF/groovy/admin/adminCategories.groovy new file mode 100644 index 0000000..3ab248d --- /dev/null +++ b/war/WEB-INF/groovy/admin/adminCategories.groovy @@ -0,0 +1,15 @@ + +request.categories = datastore.execute { + from categories + sort asc by name +} + +request.categoriesCount = request.categories.collectEntries { category -> + [(category): datastore.execute { + select count + from posts + where categories == category.name + }] +} + +forward '/WEB-INF/pages/admin/adminCategories.gtpl' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/adminMedia.groovy b/war/WEB-INF/groovy/admin/adminMedia.groovy new file mode 100644 index 0000000..76e57ab --- /dev/null +++ b/war/WEB-INF/groovy/admin/adminMedia.groovy @@ -0,0 +1,2 @@ + +forward '/WEB-INF/pages/admin/adminMedia.gtpl' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/adminPosts.groovy b/war/WEB-INF/groovy/admin/adminPosts.groovy new file mode 100644 index 0000000..38f4eb2 --- /dev/null +++ b/war/WEB-INF/groovy/admin/adminPosts.groovy @@ -0,0 +1,22 @@ + +request.posts = datastore.execute { + from posts + sort desc by created + where draft == false + and type == 'post' +} + +request.pages = datastore.execute { + from posts + sort desc by created + where draft == false + and type == 'page' +} + +request.drafts = datastore.execute { + from posts + sort desc by created + where draft == true +} + +forward '/WEB-INF/pages/admin/adminPosts.gtpl' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/categoryAdd.groovy b/war/WEB-INF/groovy/admin/categoryAdd.groovy new file mode 100644 index 0000000..601b29d --- /dev/null +++ b/war/WEB-INF/groovy/admin/categoryAdd.groovy @@ -0,0 +1,12 @@ +import com.google.appengine.api.datastore.Entity + +def categoryName = params.categoryName +def categoryDescription = params.categoryDescription + +new Entity('categories').with { + name = categoryName + description = categoryDescription + save() +} + +redirect '/admin/categories' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/categoryDelete.groovy b/war/WEB-INF/groovy/admin/categoryDelete.groovy new file mode 100644 index 0000000..e43314d --- /dev/null +++ b/war/WEB-INF/groovy/admin/categoryDelete.groovy @@ -0,0 +1,4 @@ + +datastore.execute { select single from categories where name == params.categoryName }.delete() + +redirect '/admin/categories' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/clearCache.groovy b/war/WEB-INF/groovy/admin/clearCache.groovy new file mode 100644 index 0000000..2af179c --- /dev/null +++ b/war/WEB-INF/groovy/admin/clearCache.groovy @@ -0,0 +1,31 @@ + +memcache.clearCacheForUri '/' +memcache.clearCacheForUri '/archives' + +100.times { + memcache.clearCacheForUri "/p${it}" + memcache.clearCacheForUri "/archives/p${it}" +} + +memcache.clearCacheForUri '/search' +memcache.clearCacheForUri '/social' + +memcache.clearCacheForUri '/feed/atom' + +datastore.execute { + from posts + sort desc by created + where draft == false +}.each { + memcache.clearCacheForUri "/${it.type == 'post' ? 'article' : 'page'}/${it.urlTitle}" +} + +datastore.execute { + from categories + sort asc by name +}.each { + memcache.clearCacheForUri "/category/${it.name}" + memcache.clearCacheForUri "/feed/atom/${it.name}" +} + +redirect '/admin/posts' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/email.groovy b/war/WEB-INF/groovy/admin/email.groovy new file mode 100644 index 0000000..4f705ae --- /dev/null +++ b/war/WEB-INF/groovy/admin/email.groovy @@ -0,0 +1,54 @@ +import com.google.appengine.api.datastore.Entity +import javax.mail.internet.MimeMultipart +import javax.mail.BodyPart +import javax.mail.internet.MimeMessage + +import static bloogy.Utilities.* + +def content = request.inputStream.text +new Entity('email').with { + rawContent = content + save() +} + +MimeMessage msg = mail.parseMessage(request) + +log.info "Subject ${msg.subject}, to ${msg.allRecipients.join(', ')}, from ${msg.from[0]}" + +String fullContent = "" + +msg.contentStream.withReader { Reader reader -> + fullContent = reader.text +} + +def sb = new StringBuilder() + +if (msg.content instanceof String) { + log.info "Received a string" + sb << msg.content +} else if (msg.content instanceof MimeMultipart) { + log.info "Received a mime multipart" + for (int i = 0; i < msg.content.count; i++) { + BodyPart part = msg.content.getBodyPart(i) + log.info("Part $i: $part") + log.info("Content: " + part.content) + sb << part.content + } +} + +log.info "ALL: ${sb.toString()}" + +new Entity('posts').with { + title = msg.subject + urlTitle = streamline(msg.subject) + created = new Date() + categories = [] + draft = false + type = 'post' + + content = "
$fullContent
" + + save() +} + + diff --git a/war/WEB-INF/groovy/admin/mediaAdd.groovy b/war/WEB-INF/groovy/admin/mediaAdd.groovy new file mode 100644 index 0000000..93571cb --- /dev/null +++ b/war/WEB-INF/groovy/admin/mediaAdd.groovy @@ -0,0 +1,5 @@ + +def blobs = blobstore.getUploadedBlobs(request) +def blob = blobs["fileName"] + +redirect '/admin/media' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/mediaDelete.groovy b/war/WEB-INF/groovy/admin/mediaDelete.groovy new file mode 100644 index 0000000..ef35ecd --- /dev/null +++ b/war/WEB-INF/groovy/admin/mediaDelete.groovy @@ -0,0 +1,10 @@ +import com.google.appengine.api.blobstore.BlobKey + +new BlobKey(params.blobKey).delete() + +def page = params.page.toInteger() + +def singleOnPage = params.singleOnPage == 'true' +if (singleOnPage && page > 0) page -= 1 + +redirect "/admin/media${page > 0 ? "/p${params.page}" : ''}#media-browser" \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/mediaSelector.groovy b/war/WEB-INF/groovy/admin/mediaSelector.groovy new file mode 100644 index 0000000..2453647 --- /dev/null +++ b/war/WEB-INF/groovy/admin/mediaSelector.groovy @@ -0,0 +1,21 @@ +import com.google.appengine.api.blobstore.BlobInfoFactory + +def blobstoreKind = com.google.appengine.api.blobstore.BlobInfoFactory.KIND + +def numberPerPage = 5 + +def page = params.page ? params.page.toInteger() : 0 +def offsetParam = page * numberPerPage + +datastore.execute { + from blobstoreKind + offset offsetParam limit numberPerPage + sort desc by creation +}.each { media -> + def info = new BlobInfoFactory().createBlobInfo(media) + def mediaUrl = "/media/${java.net.URLEncoder.encode(info.filename)}" + def croppedUrl = images.getServingUrl(info.blobKey) + '=s100-c' + + html.img src: croppedUrl, fullsrc: mediaUrl +} + diff --git a/war/WEB-INF/groovy/admin/postDelete.groovy b/war/WEB-INF/groovy/admin/postDelete.groovy new file mode 100644 index 0000000..546b65e --- /dev/null +++ b/war/WEB-INF/groovy/admin/postDelete.groovy @@ -0,0 +1,6 @@ +import com.google.appengine.api.datastore.Key + +def key = ['posts', params.id.toLong()] as Key +key.delete() + +redirect '/admin/posts' \ No newline at end of file diff --git a/war/WEB-INF/groovy/admin/postSave.groovy b/war/WEB-INF/groovy/admin/postSave.groovy new file mode 100644 index 0000000..61a0e3e --- /dev/null +++ b/war/WEB-INF/groovy/admin/postSave.groovy @@ -0,0 +1,38 @@ +import com.google.appengine.api.datastore.Entity + +import static bloogy.Utilities.* + +def id = params.id?.toLong() + +Entity postOrPage + +if (id) { + postOrPage = datastore.get('posts', id) +} else { + postOrPage = new Entity('posts') + postOrPage.urlTitle = streamline(params.title) +} + +postOrPage.title = params.title +postOrPage.content = params.content +postOrPage.created = Date.parse('yyyy/MM/dd HH:mm', params.created) +postOrPage.draft = params.draft == 'draft' ?: false +postOrPage.type = params.type + +if (params.categories == null) { + postOrPage.categories = null +} else if (params.categories instanceof String) { + postOrPage.categories = [params.categories] +} else if (params.categories) { + postOrPage.categories = params.categories.toList() +} + +postOrPage.save() + +memcache.clearCacheForUri "/${postOrPage.type == 'page' ? 'page' : 'article'}/${postOrPage.urlTitle}" +memcache.clearCacheForUri '/archives' +memcache.clearCacheForUri '/' + +redirect "/live/${postOrPage.urlTitle}" + + diff --git a/war/WEB-INF/groovy/archive.groovy b/war/WEB-INF/groovy/archive.groovy new file mode 100644 index 0000000..3a49d76 --- /dev/null +++ b/war/WEB-INF/groovy/archive.groovy @@ -0,0 +1,21 @@ +// Max number of articles per page +int pageSize = 10 + +// Page number +int page = params.page ? params.page.toInteger() : 0 + +// Retrieve the latest 10 posts +def posts = datastore.execute { + from posts + limit pageSize offset pageSize * page + where created < new Date() + and draft == false + and type == 'post' + sort desc by created +}.groupBy { it.created.year + 1900 } + +request.page = page +request.posts = posts + +forward '/WEB-INF/pages/archive.gtpl' + diff --git a/war/WEB-INF/groovy/article.groovy b/war/WEB-INF/groovy/article.groovy new file mode 100644 index 0000000..686e920 --- /dev/null +++ b/war/WEB-INF/groovy/article.groovy @@ -0,0 +1,11 @@ +def title = params.title + +def post = datastore.execute { from posts where urlTitle == title }[0] + +if (post) { + request.post = post + forward '/WEB-INF/pages/article.gtpl' +} else { + request.title = params.title + forward '/WEB-INF/pages/notFound.gtpl' +} \ No newline at end of file diff --git a/war/WEB-INF/groovy/category.groovy b/war/WEB-INF/groovy/category.groovy new file mode 100644 index 0000000..965e474 --- /dev/null +++ b/war/WEB-INF/groovy/category.groovy @@ -0,0 +1,27 @@ + +if (params.category) { + + // Max number of articles per page + int pageSize = 10 + + // Page number + int page = params.page ? params.page.toInteger() : 0 + + def posts = datastore.execute { + from posts + limit pageSize offset pageSize * page + where created < new Date() + 1 + and draft == false + and type == 'post' + and categories == params.category + sort desc by created + }.groupBy { it.created.year + 1900 } + + request.page = page + request.posts = posts + request.category = params.category + + forward '/WEB-INF/pages/archive.gtpl' +} else { + forward '/WEB-INF/pages/notfound.gtpl' +} \ No newline at end of file diff --git a/war/WEB-INF/groovy/error.groovy b/war/WEB-INF/groovy/error.groovy new file mode 100644 index 0000000..58df39c --- /dev/null +++ b/war/WEB-INF/groovy/error.groovy @@ -0,0 +1,6 @@ + +request.code = request.getAttribute("javax.servlet.error.status_code"); +request.ex = request.getAttribute("javax.servlet.error.exception"); +request.msg = request.getAttribute("javax.servlet.error.message"); + +forward '/WEB-INF/pages/error.gtpl' \ No newline at end of file diff --git a/war/WEB-INF/groovy/feed.groovy b/war/WEB-INF/groovy/feed.groovy new file mode 100644 index 0000000..b28196b --- /dev/null +++ b/war/WEB-INF/groovy/feed.groovy @@ -0,0 +1,45 @@ +import java.text.SimpleDateFormat + +response.contentType = "text/xml;charset=utf-8" + +def isoTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US) + +def posts = datastore.execute { + from posts limit 10 + where created < new Date() + and draft == false + and type == 'post' + if (params.category) { + and categories == params.category + } + sort desc by created +} + +def serverRoot = "http://${request.serverName}${request.serverPort != 80 ? ":$request.serverPort" : ''}" + +html.feed(xmlns: "http://www.w3.org/2005/Atom") { + title "Guillaume Laforge's blog feed" + subtitle "On all things Groovy!" + link href: serverRoot, rel: "self" + updated isoTime.format(new Date()) + generator(uri: "http://gaelyk.appspot.com", version: "1.0", "Gaelyk lightweight Groovy toolkit for Google App Engine") + + posts.each { post -> + entry { + // create the summary to show in the Atom feed + int min = Math.min(post.content.size(), 1000) + def content = post.content[0.. + sout << stream + } + } else { + blobInfo.blobKey.serve response + } +} else { + response.contentType = 'image/png' + sout << new File('images/image-not-found.png').bytes +} diff --git a/war/WEB-INF/groovy/search.groovy b/war/WEB-INF/groovy/search.groovy new file mode 100644 index 0000000..b0b8248 --- /dev/null +++ b/war/WEB-INF/groovy/search.groovy @@ -0,0 +1 @@ +forward '/WEB-INF/pages/search.gtpl' \ No newline at end of file diff --git a/war/WEB-INF/groovy/social.groovy b/war/WEB-INF/groovy/social.groovy new file mode 100644 index 0000000..4e84121 --- /dev/null +++ b/war/WEB-INF/groovy/social.groovy @@ -0,0 +1,50 @@ +import java.text.SimpleDateFormat + +def delicious = "http://feeds.delicious.com/v2/rss/glaforge?count=15".toURL().get(async: true) +def greader = "http://www.google.com/reader/public/atom/user%2F16866715143536937448%2Fstate%2Fcom.google%2Fbroadcast".toURL().get(async: true) +def twitter = "http://search.twitter.com/search.atom?q=from%3Aglaforge&rpp=200".toURL().get(async: true) + +def items = [] + +def slurper = new XmlSlurper() + +// date format: 2011-07-29T09:00:10Z +def sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + +def twitterDoc = slurper.parseText(twitter.get().text) +twitterDoc.entry.each { entry -> + items << [ + origin: 'twitter', + title: entry.title.text(), + published: sdf.parse(entry.published.text()), + link: entry.link.find { it.@type == 'text/html' }.@href.text() + ] +} + +def greaderDoc = slurper.parseText(greader.get().text) +greaderDoc.entry.each { entry -> + items << [ + origin: 'greader', + title: entry.title.text(), + published: sdf.parse(entry.published.text()), + link: entry.link.find { it.@type == 'text/html' }.@href.text() + ] +} + +// date format: Thu, 28 Jul 2011 07:32:22 +0000 +sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US) + +def deliciousDoc = slurper.parseText(delicious.get().text) +deliciousDoc.channel.item.each { entry -> + items << [ + origin: 'delicious', + title: entry.title.text(), + published: sdf.parse(entry.pubDate.text()), + link: entry.link.text() + ] +} + + +request.items = items.sort { it.published }.reverse().each { it.published.clearTime() }.groupBy { it.published } + +forward '/WEB-INF/pages/social.gtpl' \ No newline at end of file diff --git a/war/WEB-INF/groovy/viewRawEmail.groovy b/war/WEB-INF/groovy/viewRawEmail.groovy new file mode 100644 index 0000000..36de721 --- /dev/null +++ b/war/WEB-INF/groovy/viewRawEmail.groovy @@ -0,0 +1,5 @@ +def e = datastore.execute { select single from email } + +response.contentType = "text/plain" + +out << e.rawContent \ No newline at end of file diff --git a/war/WEB-INF/includes/bottom.gtpl b/war/WEB-INF/includes/bottom.gtpl new file mode 100644 index 0000000..baf6c10 --- /dev/null +++ b/war/WEB-INF/includes/bottom.gtpl @@ -0,0 +1,18 @@ +
+ +
+ +
+ © 2011 Guillaume Laforge | + The views and opinions expressed here are mine and don't reflect the ones from my employer. +
+ + + +
 
+ +
+ +
\ No newline at end of file diff --git a/war/WEB-INF/includes/footer.gtpl b/war/WEB-INF/includes/footer.gtpl new file mode 100644 index 0000000..aec3810 --- /dev/null +++ b/war/WEB-INF/includes/footer.gtpl @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/war/WEB-INF/includes/header.gtpl b/war/WEB-INF/includes/header.gtpl new file mode 100644 index 0000000..32bf677 --- /dev/null +++ b/war/WEB-INF/includes/header.gtpl @@ -0,0 +1,28 @@ +
+
+
+ + + +
+
+
\ No newline at end of file diff --git a/war/WEB-INF/includes/left.gtpl b/war/WEB-INF/includes/left.gtpl new file mode 100644 index 0000000..4615fbd --- /dev/null +++ b/war/WEB-INF/includes/left.gtpl @@ -0,0 +1,80 @@ + + +
 
diff --git a/war/WEB-INF/includes/meta.gtpl b/war/WEB-INF/includes/meta.gtpl new file mode 100644 index 0000000..c6fadf5 --- /dev/null +++ b/war/WEB-INF/includes/meta.gtpl @@ -0,0 +1,20 @@ + + + + + + + + <% if (!request.getAttribute('originalURI').contains('/admin')) { %> + + <% } %> diff --git a/war/WEB-INF/includes/navigation.gtpl b/war/WEB-INF/includes/navigation.gtpl new file mode 100644 index 0000000..9f08ddd --- /dev/null +++ b/war/WEB-INF/includes/navigation.gtpl @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/war/WEB-INF/includes/syntaxHighlighting.gtpl b/war/WEB-INF/includes/syntaxHighlighting.gtpl new file mode 100644 index 0000000..65e039c --- /dev/null +++ b/war/WEB-INF/includes/syntaxHighlighting.gtpl @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.2.jar b/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.2.jar new file mode 100644 index 0000000..93cc8dc Binary files /dev/null and b/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.2.jar differ diff --git a/war/WEB-INF/lib/appengine-api-labs-1.5.2.jar b/war/WEB-INF/lib/appengine-api-labs-1.5.2.jar new file mode 100644 index 0000000..35aa061 Binary files /dev/null and b/war/WEB-INF/lib/appengine-api-labs-1.5.2.jar differ diff --git a/war/WEB-INF/lib/gaelyk-1.0.jar b/war/WEB-INF/lib/gaelyk-1.0.jar new file mode 100644 index 0000000..b08e57f Binary files /dev/null and b/war/WEB-INF/lib/gaelyk-1.0.jar differ diff --git a/war/WEB-INF/lib/groovy-all-1.8.1.jar b/war/WEB-INF/lib/groovy-all-1.8.1.jar new file mode 100644 index 0000000..096db7a Binary files /dev/null and b/war/WEB-INF/lib/groovy-all-1.8.1.jar differ diff --git a/war/WEB-INF/lib/ocpsoft-pretty-time-1.0.7.jar b/war/WEB-INF/lib/ocpsoft-pretty-time-1.0.7.jar new file mode 100644 index 0000000..327f38f Binary files /dev/null and b/war/WEB-INF/lib/ocpsoft-pretty-time-1.0.7.jar differ diff --git a/war/WEB-INF/logging.properties b/war/WEB-INF/logging.properties new file mode 100644 index 0000000..4c9dd0c --- /dev/null +++ b/war/WEB-INF/logging.properties @@ -0,0 +1,2 @@ +# Set the default logging level for all loggers to INFO +.level = INFO diff --git a/war/WEB-INF/pages/admin/adminCategories.gtpl b/war/WEB-INF/pages/admin/adminCategories.gtpl new file mode 100644 index 0000000..fbdca2b --- /dev/null +++ b/war/WEB-INF/pages/admin/adminCategories.gtpl @@ -0,0 +1,98 @@ + + + + + <% include '/WEB-INF/includes/meta.gtpl' %> + Administration -- Guillaume Laforge -- Groovy Blog + + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Categories

+ +
+ +
    + <% request.categories.each { category -> %> +
  • + <% if (request.categoriesCount[category] == 0) { %> +
    + +
    + <%}%> + ${category.name} — + ${category.description} — + (${request.categoriesCount[category]} posts) +
  • + <% } %> +
+
+

Create a new category

+
+
+
+
Category name
+
+ + +
+
 
+
+
+
Description
+
+
 
+
+
+
+
+
 
+
+
+
+ +
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/admin/adminMedia.gtpl b/war/WEB-INF/pages/admin/adminMedia.gtpl new file mode 100644 index 0000000..1bcb448 --- /dev/null +++ b/war/WEB-INF/pages/admin/adminMedia.gtpl @@ -0,0 +1,162 @@ + + +<% import com.google.appengine.api.blobstore.BlobInfoFactory %> + + + Media browser -- Guillaume Laforge -- Groovy Blog + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + + + + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Media browser

+ +
+ +
+

Store new media

+
+
+
+
+ +   + + +
+
 
+
+
+
+
+
 
+
+
+
+ + +
+
+ <% + def blobstoreKind = com.google.appengine.api.blobstore.BlobInfoFactory.KIND + def numberPerPage = 8 + + def page = params.page ? params.page.toInteger() : 0 + def offsetParam = page * numberPerPage + + def medias = datastore.execute { + from blobstoreKind + offset offsetParam limit numberPerPage + sort desc by creation + } + medias.each { media -> + def mediaUrl = "/media/${java.net.URLEncoder.encode(media.filename)}" + %> +
+ +
+ + + +
+ ${blobInfo.filename}
+ ${blobInfo.creation.format('yyyy/MM/dd')} — ${blobInfo.size.intdiv(1024)} KB +
+
+
+ <% } %> +

 

+
+
+ <% + int entityCount = datastore.execute { select count from blobstoreKind } + int pageCount = (entityCount - 1).intdiv(numberPerPage) + 1 + + log.info "entity count = ${entityCount}" + log.info "page count = ${pageCount}" + + boolean hasPrev = offsetParam > 0 + boolean hasNext = page + 1 < pageCount + + %> + +   + +   + +
+
+ +
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/admin/adminPosts.gtpl b/war/WEB-INF/pages/admin/adminPosts.gtpl new file mode 100644 index 0000000..a2eaf50 --- /dev/null +++ b/war/WEB-INF/pages/admin/adminPosts.gtpl @@ -0,0 +1,95 @@ + + + + + Administration -- Guillaume Laforge -- Groovy Blog + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Drafts, posts, and pages

+ +
+ +
+ + + <% + ['Drafts': request.drafts, 'Posts': request.posts, 'Pages': request.pages].each { type, posts -> + %> +
+
    + <% posts.each { post -> %> +
  • +
    + +
    +
    + +
    + <% if (post.type == 'page') { %> + Page  + <% } else if (post.type == 'post') { %> + Post  + <% } %> + ${post.title} +
    + + ${post.created.format('yyyy / MM / dd')} + <% if (post.categories) { %> — ${post.categories?.join(', ') ?: 'none'} <% } %> +
  • + <% } %> +
+
+ <% } %> + +
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/admin/postEdit.gtpl b/war/WEB-INF/pages/admin/postEdit.gtpl new file mode 100644 index 0000000..dcc9fa6 --- /dev/null +++ b/war/WEB-INF/pages/admin/postEdit.gtpl @@ -0,0 +1,143 @@ + + +<% import com.google.appengine.api.datastore.KeyFactory %> + + + Administration -- Guillaume Laforge -- Groovy Blog + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + + + + + + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +<% + def id = params.id?.toLong() + def post = id ? KeyFactory.createKey('posts', id).get() : null +%> + +
+
+ +
+ +
+
+ +
+ +

Edit post

+ +
+
+
+ <% if (post) { %> + + <% } %> +
+
Title
+
+ + +
+ +
 
+
+ + + + + + + + + +
+
+
Created (GMT time)
+
+ + +
+
+
+
+
Type
+
+ +
+
+
+
+
Status
+
+ +
+
+
+
+
Categories
+
+ +
+
 
+
+
+
+
Content
+
+ +
+
 
+
+
+
+
+ +
+
 
+
+
+
+
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/archive.gtpl b/war/WEB-INF/pages/archive.gtpl new file mode 100644 index 0000000..1fc5a69 --- /dev/null +++ b/war/WEB-INF/pages/archive.gtpl @@ -0,0 +1,117 @@ + + + +<% + int page = params.page ? params.page.toInteger() : 0 + + def originalURI = request.originalURI + + def titlePrefix = '' + def origin = "archives" + if (originalURI.contains('category')) { + origin = "category/${params.category}" + titlePrefix = "Category ${params.category} -- " + } else { + titlePrefix = "Archives -- " + } +%> + + + ${titlePrefix}Guillaume Laforge -- Groovy Blog + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ + <% + if (origin.startsWith("archives")) { + def date = [request.year, request.month, request.day].grep{ it }*.toString()*.padLeft(2, '0') %> +

Archives ${date?'for':''} ${date.join('-')}

+ <% } else if (origin.startsWith("category")) { %> +

Category ${params.category}

+ <% } %> +
+ <% + request.posts.each { year, posts -> + %> +

${year}

+
+ <% + posts.each { post -> + String day = post.created.date.toString().padLeft(2, '0') + String monthLetters = post.created.format('MMM').toUpperCase() + %> + +
+ + + +
+

${post.title}

+ +
+ +
 
+ +
+ +
+ <% + } + } + %> + + + <% if (request.posts || page) { %> + + <% } %> +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/article.gtpl b/war/WEB-INF/pages/article.gtpl new file mode 100644 index 0000000..1653adb --- /dev/null +++ b/war/WEB-INF/pages/article.gtpl @@ -0,0 +1,123 @@ + + + + + ${request.post.title} -- Guillaume Laforge -- Groovy Blog + <% include '/WEB-INF/includes/syntaxHighlighting.gtpl' %> + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ + <% def post = request.post %> +

${post.title}

+ + + + <% if (request.getAttribute('originalURI').contains('article')) { %> +
+
+ + +
+ <% } %> + +
+ ${post.content} +
+ + <% if (post.categories) { %> + + <% } %> + +
+ + <% if (request.getAttribute('originalURI').contains('article')) { %> +
+ + + + + + + + + + + + + + +

 

+
+ +
+ +
+ + + +
+ <% } %> + +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/error.gtpl b/war/WEB-INF/pages/error.gtpl new file mode 100644 index 0000000..d799416 --- /dev/null +++ b/war/WEB-INF/pages/error.gtpl @@ -0,0 +1,53 @@ + + + + + <% include '/WEB-INF/includes/meta.gtpl' %> + An error occured -- Guillaume Laforge -- Groovy Blog + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

An error occured

+ +
+ <% if (request.getAttribute('code')) { %> +
Error code:
+
${request.getAttribute('code')}
+ <% } else if (request.getAttribute('ex')) { %> +
Exception:
+
${request.getAttribute('ex')}
+ <% } %> +
Message:
+
${request.getAttribute('msg')}
+
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/home.gtpl b/war/WEB-INF/pages/home.gtpl new file mode 100644 index 0000000..43f3fe5 --- /dev/null +++ b/war/WEB-INF/pages/home.gtpl @@ -0,0 +1,101 @@ + + + + + Guillaume Laforge -- Groovy Blog + <% include '/WEB-INF/includes/syntaxHighlighting.gtpl' %> + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ + <% + // no articles to display + if (!request.posts) { + %> +

No more posts

+ <% + } + %> + <% + request.posts.each { post -> + %> + +
+ +

${post.title}

+ + + +
+ ${post.content} +
+ + <% if (post.categories) { %> + + <% } %> + +
+ + <% + } + %> + + + +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/notAllowed.gtpl b/war/WEB-INF/pages/notAllowed.gtpl new file mode 100644 index 0000000..3997f6a --- /dev/null +++ b/war/WEB-INF/pages/notAllowed.gtpl @@ -0,0 +1,47 @@ + + + + + <% include '/WEB-INF/includes/meta.gtpl' %> + Not allowed -- Guillaume Laforge -- Groovy Blog + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Access not allowed

+ +
+

You must be administrator to be able to administer this weblog.

+ +

Please sign-in back with an administrator account

+
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/notFound.gtpl b/war/WEB-INF/pages/notFound.gtpl new file mode 100644 index 0000000..003417b --- /dev/null +++ b/war/WEB-INF/pages/notFound.gtpl @@ -0,0 +1,48 @@ + + + + + <% include '/WEB-INF/includes/meta.gtpl' %> + Page not found -- Guillaume Laforge -- Groovy Blog + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Page not found

+ +
+

The page you were looking for couldn't be found.

+ +

Otherwise, please one of the links in the navigation bars + to find your way in this website.

+
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/search.gtpl b/war/WEB-INF/pages/search.gtpl new file mode 100644 index 0000000..a248e19 --- /dev/null +++ b/war/WEB-INF/pages/search.gtpl @@ -0,0 +1,56 @@ + + + + + Search this site -- Guillaume Laforge -- Groovy Blog + + + + + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Search this site

+ +
+
Loading
+
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/pages/social.gtpl b/war/WEB-INF/pages/social.gtpl new file mode 100644 index 0000000..ccd264a --- /dev/null +++ b/war/WEB-INF/pages/social.gtpl @@ -0,0 +1,66 @@ + + + + + Social (twitter, delicious, google reader) -- Guillaume Laforge -- Groovy Blog + + <% include '/WEB-INF/includes/meta.gtpl' %> + + + + +<% include '/WEB-INF/includes/header.gtpl' %> +<% include '/WEB-INF/includes/navigation.gtpl' %> + +
+
+ +
+ +
+
+ +
+ +

Social

+ +
+ +

+ This page gathers: +

+ + + <% request.items.each { date, entries -> %> +

${date.format('yyyy / MM / dd')}

+ + <% } %> +
+ +
+ +
+
+ + <% include '/WEB-INF/includes/left.gtpl' %> +
+ +
+
+ +<% include '/WEB-INF/includes/footer.gtpl' %> +<% include '/WEB-INF/includes/bottom.gtpl' %> + + + \ No newline at end of file diff --git a/war/WEB-INF/plugins.groovy b/war/WEB-INF/plugins.groovy new file mode 100644 index 0000000..8942d3b --- /dev/null +++ b/war/WEB-INF/plugins.groovy @@ -0,0 +1 @@ +install prettyTime \ No newline at end of file diff --git a/war/WEB-INF/plugins/prettyTime.groovy b/war/WEB-INF/plugins/prettyTime.groovy new file mode 100644 index 0000000..ddeca2e --- /dev/null +++ b/war/WEB-INF/plugins/prettyTime.groovy @@ -0,0 +1,9 @@ +import com.ocpsoft.pretty.time.PrettyTime + +categories PrettyTimeCategory + +class PrettyTimeCategory { + static String pretty(Date date) { + new PrettyTime().format(date) + } +} \ No newline at end of file diff --git a/war/WEB-INF/routes.groovy b/war/WEB-INF/routes.groovy new file mode 100644 index 0000000..1cdd4b5 --- /dev/null +++ b/war/WEB-INF/routes.groovy @@ -0,0 +1,50 @@ +def cache = localMode ? 0 : 1.hour + +get "/", forward: '/home.groovy', cache: cache +get "/p@p", forward: '/home.groovy?page=@p', validate: { p ==~ /\d+/ }, cache: cache + +get "/article/@title", forward: '/article.groovy?title=@title', cache: cache +get "/page/@title", forward: '/article.groovy?title=@title', cache: cache +get "/live/@title", forward: '/article.groovy?title=@title' + +get "/archives/p@p", forward: '/archive.groovy?page=@p', validate: { p ==~ /\d+/ }, cache: cache +get "/archives", forward: '/archive.groovy', cache: cache + +get "/category/@cat/p@p", forward: '/category.groovy?category=@cat&page=@p', validate: { p ==~ /\d+/ }, cache: cache +get "/category/@cat", forward: '/category.groovy?category=@cat', cache: cache + +get "/media/@file.@ext", forward: '/media.groovy?fileName=@file.@ext', cache: cache + +get "/feed/atom/@cat", forward: '/feed.groovy?category=@cat', cache: cache +get "/feed/atom", forward: '/feed.groovy', cache: cache + +get "/social", forward: '/social.groovy', cache: cache + +get "/search", forward: '/search.groovy', cache: 24.hours + +get "/admin/categories", forward: '/admin/adminCategories.groovy' +get "/admin/posts", forward: '/admin/adminPosts.groovy' +get "/admin/posts/create", forward: '/WEB-INF/pages/admin/postEdit.gtpl' +get "/admin/media", forward: '/admin/adminMedia.groovy' +get "/admin/media/p@p", forward: '/admin/adminMedia.groovy?page=@p' +get "/admin/mediaSelector", forward: '/admin/mediaSelector.groovy' +get "/admin/clearCache", forward: '/admin/clearCache.groovy' + +post "/admin/media/add", forward: '/admin/mediaAdd.groovy' +post "/admin/media/delete/@bk", forward: '/admin/mediaDelete.groovy?blobKey=@bk' +post "/admin/posts/delete/@id", forward: '/admin/postDelete.groovy?id=@id' +post "/admin/posts/edit/@id", forward: '/WEB-INF/pages/admin/postEdit.gtpl?id=@id' +post "/admin/posts/save", forward: '/admin/postSave.groovy' +post "/admin/categories/add", forward: '/admin/categoryAdd.groovy' +post "/admin/categories/delete/@cat", forward: '/admin/categoryDelete.groovy?categoryName=@cat' + +// route for 404 errors defined in web.xml +get "/not-found", forward: '/WEB-INF/pages/notFound.gtpl', cache: 24.hours +// route for 403 errors defined in web.xml +get "/not-allowed", forward: '/WEB-INF/pages/notAllowed.gtpl', cache: 24.hours +// when some error happens +get "/error", forward: '/WEB-INF/pages/error.gtpl' + +get "/favicon.ico", redirect: "/images/gaelyk-favicon.png" + +email to: "/admin/email.groovy" diff --git a/war/WEB-INF/web.xml b/war/WEB-INF/web.xml new file mode 100644 index 0000000..f852aa4 --- /dev/null +++ b/war/WEB-INF/web.xml @@ -0,0 +1,106 @@ + + + groovyx.gaelyk.GaelykServletContextListener + + + + GroovletServlet + groovyx.gaelyk.GaelykServlet + + verbose + + false + + + 1 + + + TemplateServlet + groovyx.gaelyk.GaelykTemplateServlet + + + generated.by + false + + + verbose + + false + + + 1 + + + + RoutesFilter + groovyx.gaelyk.routes.RoutesFilter + + + + GroovletServlet + *.groovy + + + TemplateServlet + *.gtpl + + + + RoutesFilter + /* + FORWARD + REQUEST + + ERROR + + + + + /admin/* + + + admin + + + + + /_ah/mail/* + + + admin + + + + + + + 404 + + /not-found + + + 403 + /not-allowed + + + 500 + /error + + + java.lang.Throwable + /error + + + + + \ No newline at end of file diff --git a/war/css/chosen.css b/war/css/chosen.css new file mode 100644 index 0000000..59fe7cf --- /dev/null +++ b/war/css/chosen.css @@ -0,0 +1,310 @@ +div.chzn-container { + font-size: 13px; + position: relative; +} + +div.chzn-container input { + background: #fff; + background: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + border: 1px solid #aaa; + font-family: sans-serif; + font-size: 1em; + margin: 0px; + padding: 4px 5px; + outline: none; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -o-border-radius: 3px; + -ms-border-radius: 3px; + -khtml-border-radius: 3px; + border-radius: 3px; +} +div.chzn-container textarea:focus { + border-color: #058cf5; + -moz-box-shadow: 0px 0px 3px #aaa; + -webkit-box-shadow: 0px 0px 3px #aaa; + box-shadow: 0px 0px 3px #aaa; +} + + +div.chzn-container div.chzn-drop { + background: #FFF; + border: 1px solid #aaa; + border-width: 0 1px 1px; + left: 0; + position: absolute; + top: 29px; + -webkit-box-shadow: 0px 4px 5px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0px 4px 5px rgba(0, 0, 0, 0.15); + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.15); + z-index: 20; +} +div.chzn-container-single div.chzn-drop { + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + -o-border-radius: 0 0 4px 4px; + -ms-border-radius: 0 0 4px 4px; + -khtml-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + + +/* SINGLE */ +div.chzn-container a.chzn-single { + background: #FFF; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); + background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); + border: 1px solid #aaa; + display: block; + overflow: hidden; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -o-border-radius: 4px; + -ms-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + height: 25px; + color: #444; + line-height: 26px; + padding: 0px 0px 0px 8px; + position: relative; + text-decoration: none; + z-index: 19; + white-space: nowrap; +} +div.chzn-container a.chzn-single span { + display: block; + margin-right: 26px; + overflow: hidden; + text-overflow: ellipsis; +} +div.chzn-container a.chzn-single div { + -moz-border-radius-topright: 4px; + -webkit-border-top-right-radius: 4px; + -o-border-top-right-radius: 4px; + -ms-border-top-right-radius: 4px; + -khtml-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + -webkit-border-bottom-right-radius: 42px; + -o-border-bottom-right-radius: 4px; + -ms-border-bottom-right-radius: 4px; + -khtml-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + background: #ccc; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); + background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); + border-left: 1px solid #aaa; + display: block; + height: 100%; + position: absolute; + right: 0; + top: 0; + width: 18px; +} +div.chzn-container a.chzn-single div b { + background: url('/images/chosen-sprite.png') no-repeat 0 1px; + display: block; + width: 100%; + height: 100%; +} +div.chzn-container div.chzn-search { + padding: 3px 4px; + margin: 0px; + white-space: nowrap; +} +div.chzn-container div.chzn-search input { + background: url('/images/chosen-sprite.png') no-repeat 97% -35px, #ffffff; + background: url('/images/chosen-sprite.png') no-repeat 97% -35px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: url('/images/chosen-sprite.png') no-repeat 97% -35px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + -moz-border-radius: 0px; + -webkit-border-radius: 0px; + -o-border-radius: 0px; + -ms-border-radius: 0px; + -khtml-border-radius: 0px; + border-radius: 0px; + margin: 1px 0; + outline: 0; +} + + +/* Multi */ +div.chzn-container ul.chzn-choices { + background: #fff; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background-image: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + margin: 0; + cursor: text; + border: 1px solid #aaa; + overflow: hidden; + height: auto !important; + height: 1%; + padding: 0; + position: relative; +} +div.chzn-container ul.chzn-choices:focus { + border-color: #058cf5; + -moz-box-shadow: 0px 0px 5px #999; + -webkit-box-shadow: 0px 0px 5px #999; + box-shadow: 0px 0px 5px #999; +} +div.chzn-container ul.chzn-choices li { + float: left; + list-style-type: none; + margin: 0px; +} +div.chzn-container ul.chzn-choices li.search-field { + margin: 0px; + white-space: nowrap; + padding: 0px; +} +div.chzn-container ul.chzn-choices li.search-field input { + color: #666; + background: transparent !important; + border: 0px !important; + padding: 5px; + margin: 1px 0; + outline: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +div.chzn-container ul.chzn-choices li.search-field input.default { + color: #999; +} +div.chzn-container ul.chzn-choices li.search-choice { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background: #e4e4e4; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e4e4e4), color-stop(0.7, #eeeeee)); + background-image: -moz-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); + color: #333; + border: 1px solid #b4b4b4; + line-height: 13px; + padding: 3px 19px 3px 6px; + position: relative; + margin: 3px 0px 3px 5px; +} +div.chzn-container ul.chzn-choices li.search-choice span { + cursor: default; +} +div.chzn-container ul.chzn-choices li.search-choice.search-choice-focus { + background: #d4d4d4; +} +div.chzn-container ul.chzn-choices li.search-choice a.search-choice-close { + position: absolute; + right: 5px; + top: 6px; + display: block; + width: 8px; + height: 9px; + font-size: 1px; + background: url(/images/chosen-sprite.png) right top no-repeat; +} +div.chzn-container ul.chzn-choices li.search-choice a.search-choice-close:hover { + background-position: right -9px; +} +div.chzn-container ul.chzn-choices li.search-choice.search-choice-focus a.search-choice-close { + background-position: right -9px; +} + + +/* Results */ +div.chzn-container ul.chzn-results { + margin: 0 4px 4px 0; + max-height: 190px; + padding: 0 0 0 4px; + position: relative; + overflow-x: hidden; + overflow-y: auto; + z-index: 20; +} +div.chzn-container-multi ul.chzn-results { + margin: -1px 0 0; + padding: 0; +} +div.chzn-container-multi ul.chzn-results li { + border-left: 0px !important; + border-right: 0px !important; +} +div.chzn-container ul.chzn-results li { + line-height: 80%; + padding: 7px 7px 8px; + z-index: 22; + margin: 0; + list-style-type: none; +} +div.chzn-container ul.chzn-results li.active-result { + cursor: pointer; +} +div.chzn-container ul.chzn-results li em { + font-style: normal; + background: #FEFFDC; +} +div.chzn-container ul.chzn-results li.highlighted { + background: #3875d7; + color: #fff; +} +div.chzn-container ul.chzn-results li.highlighted em { + background: transparent; +} +div.chzn-container ul.chzn-results li.no-results { + background: #F4F4F4; +} +div.chzn-container ul.chzn-results li.group-result { + cursor: default; + color: #999; + font-weight: bold; +} +div.chzn-container ul.chzn-results li.group-option { + padding-left: 20px; +} + +div.chzn-container-multi div.chzn-drop li.result-selected { + display: none; +} + + + +/* Active */ +div.chzn-container-active a.chzn-single { + -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + border: 1px solid #5897fb; +} +div.chzn-container-active a.chzn-single-with-drop { + border: 1px solid #aaa; + border-width: 1px 1px 1px; + -moz-box-shadow: 0px 1px 0px #FFF inset; + -webkit-box-shadow: 0px 1px 0px #FFF inset; + box-shadow: 0px 1px 0px #FFF inset; + background: #EEE; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); + background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); + -webkit-border-bottom-left-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + -moz-border-radius-bottomleft: 0px; + -moz-border-radius-bottomright: 0px; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; +} +div.chzn-container-active a.chzn-single-with-drop div { + background: transparent; + border-left: none; +} +div.chzn-container-active a.chzn-single-with-drop div b { + background-position: -18px 1px; +} +div.chzn-container-active ul.chzn-choices { + z-index: 21; + -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); + border: 1px solid #5897fb; +} +div.chzn-container-active ul.chzn-choices input { + color: #111 !important; +} diff --git a/war/css/google-search.css b/war/css/google-search.css new file mode 100644 index 0000000..37853e3 --- /dev/null +++ b/war/css/google-search.css @@ -0,0 +1,183 @@ +.gsc-control-cse { + font-family: Arial, sans-serif; + border-color: #FFFFFF; + background-color: #FFFFFF; +} + +input.gsc-input { + border-color: #DFDFDA; + + height: 28px; + + -moz-box-shadow: 2px 1px 3px #AAA; + -webkit-box-shadow: 2px 1px 3px #AAA; + box-shadow: 2px 1px 3px #AAA; + + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input.gsc-search-button { + border-color: #666666; + background-color: #CECECE; +} + +.gsc-tabHeader.gsc-tabhInactive { + border-color: #E9E9E9; + background-color: #E9E9E9; +} + +.gsc-tabHeader.gsc-tabhActive { + border-top-color: #905010; + border-left-color: #E9E9E9; + border-right-color: #E9E9E9; + background-color: #FFFFFF; +} + +.gsc-tabsArea { + border-color: #E9E9E9; +} + +.gsc-webResult.gsc-result, +.gsc-results .gsc-imageResult { + border-color: #FFFFFF; + background-color: #FFFFFF; +} + +.gsc-webResult.gsc-result:hover, +.gsc-imageResult:hover { + border-color: #FFFFFF; + background-color: #FFFFFF; +} + +.gs-webResult.gs-result a.gs-title:link, +.gs-webResult.gs-result a.gs-title:link b, +.gs-imageResult a.gs-title:link, +.gs-imageResult a.gs-title:link b { + color: #204060; +} + +.gs-webResult.gs-result a.gs-title:visited, +.gs-webResult.gs-result a.gs-title:visited b, +.gs-imageResult a.gs-title:visited, +.gs-imageResult a.gs-title:visited b { + color: #204060; +} + +.gs-webResult.gs-result a.gs-title:hover, +.gs-webResult.gs-result a.gs-title:hover b, +.gs-imageResult a.gs-title:hover, +.gs-imageResult a.gs-title:hover b { + color: #204060; +} + +.gs-webResult.gs-result a.gs-title:active, +.gs-webResult.gs-result a.gs-title:active b, +.gs-imageResult a.gs-title:active, +.gs-imageResult a.gs-title:active b { + color: #204060; +} + +.gsc-cursor-page { + color: #204060; +} + +a.gsc-trailing-more-results:link { + color: #204060; +} + +.gs-webResult .gs-snippet, +.gs-imageResult .gs-snippet { + color: #000000; +} + +.gs-webResult div.gs-visibleUrl, +.gs-imageResult div.gs-visibleUrl { + color: #905010; +} + +.gs-webResult div.gs-visibleUrl-short { + color: #905010; +} + +.gs-webResult div.gs-visibleUrl-short { + display: none; +} + +.gs-webResult div.gs-visibleUrl-long { + display: block; +} + +.gsc-cursor-box { + border-color: #FFFFFF; + text-align: center; +} + +.gsc-results .gsc-cursor-box .gsc-cursor-page, +.gsc-results .gsc-cursor-box .gsc-cursor-current-page { + margin: 5px; + padding: 5px; + border: 1px solid #E9E9E9; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.gsc-results .gsc-cursor-box .gsc-cursor-page { + border-color: #E9E9E9; + background-color: #FFFFFF; + color: #204060; +} + +.gsc-results .gsc-cursor-box .gsc-cursor-current-page { + border-color: #905010; + background-color: #F7F7F2; + color: #204060; +} + +.gs-promotion { + border-color: #204060; + background-color: #FFFFFF; +} + +.gs-promotion a.gs-title:link, +.gs-promotion a.gs-title:link *, +.gs-promotion .gs-snippet a:link { + color: #204060; +} + +.gs-promotion a.gs-title:visited, +.gs-promotion a.gs-title:visited *, +.gs-promotion .gs-snippet a:visited { + color: #204060; +} + +.gs-promotion a.gs-title:hover, +.gs-promotion a.gs-title:hover *, +.gs-promotion .gs-snippet a:hover { + color: #204060; +} + +.gs-promotion a.gs-title:active, +.gs-promotion a.gs-title:active *, +.gs-promotion .gs-snippet a:active { + color: #204060; +} + +.gs-promotion .gs-snippet, +.gs-promotion .gs-title .gs-promotion-title-right, +.gs-promotion .gs-title .gs-promotion-title-right * { + color: #000000; +} + +.gs-promotion .gs-visibleUrl, +.gs-promotion .gs-visibleUrl-short { + color: #905010; +} + +.gs-no-results-result .gs-snippet, .gs-error-result .gs-snippet { + background-color: #F7F7F2; + border-color: #E6E6E6; +} diff --git a/war/css/idea.css b/war/css/idea.css new file mode 100644 index 0000000..3d8baab --- /dev/null +++ b/war/css/idea.css @@ -0,0 +1,118 @@ +/* + +Intellij Idea-like styling (c) Vasily Polovnyov + +*/ + +pre code { + display: block; padding: 0.5em; + color: #000; + background: #fff; +} + +pre .subst, +pre .title { + font-weight: normal; + color: #000; +} + +pre .comment, +pre .template_comment, +pre .javadoc, +pre .diff .header { + color: #808080; + font-style: italic; +} + +pre .annotation, +pre .decorator, +pre .preprocessor, +pre .doctype, +pre .pi, +pre .chunk, +pre .shebang, +pre .apache .cbracket, +pre .input_number { + color: #808000; +} + +pre .tag, +pre .pi { + background: #efefef; +} + +pre .tag .title, +pre .id, +pre .attr_selector, +pre .pseudo, +pre .literal, +pre .keyword, +pre .hexcolor, +pre .css .function, +pre .ini .title, +pre .css .class, +pre .list .title, +pre .tex .command { + font-weight: bold; + color: #000080; +} + +pre .attribute, +pre .rules .keyword, +pre .number, +pre .date, +pre .regexp, +pre .tex .special { + font-weight: bold; + color: #0000ff; +} + +pre .number, +pre .regexp { + font-weight: normal; +} + +pre .string, +pre .value, +pre .filter .argument, +pre .css .function .params, +pre .apache .tag { + color: #008000; + font-weight: bold; +} + +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .char, +pre .tex .formula { + color: #000; + background: #d0eded; + font-style: italic; +} + +pre .phpdoc, +pre .yardoctag, +pre .javadoctag { + text-decoration: underline; +} + +pre .variable, +pre .envvar, +pre .apache .sqbracket, +pre .nginx .built_in { + color: #660e7a; +} + +pre .addition { + background: #baeeba; +} + +pre .deletion { + background: #ffc8bd; +} + +pre .diff .change { + background: #bccff9; +} diff --git a/war/css/jquery.cleditor.css b/war/css/jquery.cleditor.css new file mode 100755 index 0000000..0302a72 --- /dev/null +++ b/war/css/jquery.cleditor.css @@ -0,0 +1,112 @@ +.cleditorMain { + border: 1px solid #999; + padding: 0 1px 1px; + background-color: white +} + +.cleditorMain iframe { + border: none; + margin: 0; + padding: 0 +} + +.cleditorMain textarea { + border: none; + margin: 0; + padding: 0; + overflow-y: scroll; + font: 10pt Arial, Verdana; + resize: none; + outline: none /* webkit grip focus */ +} + +.cleditorToolbar { + background: url('/images/toolbar.gif') repeat +} + +.cleditorGroup { + float: left; + height: 26px +} + +.cleditorButton { + float: left; + width: 24px; + height: 24px; + margin: 1px 0 1px 0; + background: url('/images/buttons.gif') +} + +.cleditorDisabled { + opacity: 0.3; + filter: alpha(opacity = 30) +} + +.cleditorDivider { + float: left; + width: 1px; + height: 23px; + margin: 1px 0 1px 0; + background: #CCC +} + +.cleditorPopup { + border: solid 1px #999; + background-color: white; + position: absolute; + font: 10pt Arial, Verdana; + cursor: default; + z-index: 10000 +} + +.cleditorList div { + padding: 2px 4px 2px 4px +} + +.cleditorList p, +.cleditorList h1, +.cleditorList h2, +.cleditorList h3, +.cleditorList h4, +.cleditorList h5, +.cleditorList h6, +.cleditorList font { + padding: 0; + margin: 0; + background-color: Transparent +} + +.cleditorColor { + width: 150px; + padding: 1px 0 0 1px +} + +.cleditorColor div { + float: left; + width: 14px; + height: 14px; + margin: 0 1px 1px 0 +} + +.cleditorPrompt { + background-color: #F6F7F9; + padding: 4px; + font-size: 8.5pt +} + +.cleditorPrompt input, +.cleditorPrompt textarea { + font: 8.5pt Arial, Verdana; + margin: 4px; +} + +.cleditorPrompt input { + padding: 2px; +} + +.cleditorMsg { + background-color: #FDFCEE; + width: 150px; + padding: 4px; + font-size: 8.5pt +} diff --git a/war/css/stabs.css b/war/css/stabs.css new file mode 100644 index 0000000..004040c --- /dev/null +++ b/war/css/stabs.css @@ -0,0 +1,105 @@ +/* +.tabs, .tabs li { + margin: 0; + padding: 0; + list-style: none; + float: left; +} + +.tabs { + width: 100%; + border-bottom: 0; +} + +.tabs li { + margin-left: 4px; +} + +.tabs a { + + border: 1px solid #ddd; + background: #f5f5f5; + padding: 0 50px; + line-height: 30px; + display: block; + text-decoration: none; + margin-bottom: -1px +} + +.tabs a.active { + background: #fff; + font-weight: bold; + border-bottom: 1px solid white; +} + +.tabs a:hover { + background: #fff +} + +.tab { + border-top: 1px solid #ddd; + clear: both; + position: relative; + padding: 10px +} + +.tab h2 { + margin-top: 0 +} +*/ + + +.tabs, .tabs li { + margin: 0; + padding: 0; + list-style: none; + float: left +} + +.tabs { + width: 100%; + border-bottom: 1px solid #ddd; +} + +.tabs li { + margin-left: 4px; +} + +.tabs a { + -webkit-border-top-left-radius: 10px; + -webkit-border-top-right-radius: 10px; + -moz-border-radius-topleft: 10px; + -moz-border-radius-topright: 10px; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + + border: 1px solid #ddd; + background: #f5f5f5; + padding: 0 50px; + line-height: 25px; + display: block; + height: 24px; + text-decoration: none; + margin-bottom: -1px; +} + +.tabs a.active { + background: #fff; + border-bottom: 1px solid white; + font-weight: bold; +} + +.tabs a:hover { + background: #f6e5d6; + text-decoration: none; + color: black; +} + +.tab { + border-top: 0; + clear: both; + position: relative; + padding: 10px; + margin-bottom: 10px; +} + diff --git a/war/css/style.css b/war/css/style.css new file mode 100755 index 0000000..213a80b --- /dev/null +++ b/war/css/style.css @@ -0,0 +1,1165 @@ +/* + Template name: Freshmade Software + Template URI: http://templates.arcsin.se/freshmade-software-website-template/ + Release date: 2009-06-21 + Last updated: 2009-08-10 + Description: A software company styled template in light colors of white, orange and brown. + Author: Viktor Persson + Author URI: http://arcsin.se/ + + This template is licensed under a Creative Commons Attribution 2.5 License: + http://templates.arcsin.se/license/ +*/ + +/* + Reset +------------------------------------------------------------------- */ + +html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, +blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, +img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, +caption, tbody, tfoot, thead, tr, th, td, textarea, input, select { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +caption, th, td { + text-align: left; + font-weight: normal; +} + +table, td, th { + vertical-align: middle; +} + +pre, blockquote, fieldset { + background: #F7F7F2 url('/images/box.gif') no-repeat left top; +} + +pre, blockquote, fieldset, .framed { + border: 10px solid white; + + -moz-box-shadow: 3px 2px 8px #AAA; + -webkit-box-shadow: 3px 2px 8px #AAA; + box-shadow: 3px 2px 8px #AAA; + + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; +} + +blockquote { + display: block; + padding: 10px 60px; +} + +blockquote:after { + color: #ffe0bf; + display: block; + font-size: 700%; + width: 50px; + content: '\201C'; + height: 0; + margin-left: -0.6em; +} + +div.cleditorPopup.cleditorList blockquote { + width: 100px; +} + +a img { + border: none; +} + +:focus { + outline: 0; +} + +/* + General +------------------------------------------------------------------- */ + +html { + height: 100%; + padding-bottom: 1px; /* force scrollbars */ +} + +body { + background: #A9A9A9; + color: #444; + font: normal 75% sans-serif; + line-height: 1.5; +} + +/* + Typography +------------------------------------------------------------------- */ + +/* Headings */ + +h1, h2, h3, h4, h5, h6 { + color: #444; + font-weight: normal; + line-height: 1; + margin-bottom: 0.3em; +} + +h4, h5, h6 { + font-weight: bold; +} + +h1 { + font-size: 2.6em; +} + +h2 { + font-size: 2em; +} + +h3 { + font-size: 1.5em; +} + +h4 { + font-size: 1.25em; +} + +h5 { + font-size: 1.1em; +} + +h6 { + font-size: 1em; +} + +h1 img, h2 img, h3 img, h4 img, h5 img, h6 img { + margin: 0; +} + +/* Text elements */ + +p { + margin-bottom: 1em; +} + +a:focus, a:hover { + color: #002; +} + +a { + color: #246; + text-decoration: underline; +} + +abbr, acronym { + border-bottom: 1px dotted #666; +} + +address { + margin-bottom: 1.5em; +} + +blockquote { + margin: 1.2em; + line-height: 1.4em; +} + +blockquote span { + font-size: 1.4em; + color: #000; +} + +del { + color: #666; +} + +em, dfn, blockquote, address { + font-style: italic; +} + +strong, dfn { + font-weight: bold; +} + +sup, sub { + line-height: 0; +} + +cite { + color: #666; +} + +pre { + margin: 1.2em; + white-space: pre; +} + +pre, code, tt { + font: 1.1em monospace; + line-height: 1.5; + + overflow-x: auto; + overflow-y: hidden; +} + +pre code { + background: #F7F7F2 url('/images/box.gif') no-repeat left top; +} + +/* Lists */ + +li ul, li ol { + margin-left: 1.5em; +} + +ul, ol { + margin: 0 1.5em 1.5em 1.5em; +} + +ul { + list-style-type: disc; +} + +ol { + list-style-type: decimal; +} + +dl { + margin: 0 0 1.5em 0; +} + +dl dt { + font-weight: bold; +} + +dd { + margin-left: 1.5em; +} + +/* Tables */ + +table { + margin-bottom: 1.4em; + width: 100%; +} + +th { + font-weight: bold; +} + +thead th { + background: #C3D9FF; +} + +th, td, caption { + padding: 4px 10px 4px 5px; +} + +tr.even td { + background: #F2F6FA; +} + +tfoot { + font-style: italic; +} + +caption { + background: #EEE; +} + +table.data-table { + border: 1px solid #EEE; + margin-bottom: 2em; + width: 100%; +} + +table.data-table th { + background: #EEE; + border: 1px solid #DDD; + color: #555; + text-align: left; +} + +table.data-table tr { + border-bottom: 1px solid #EEE; +} + +table.data-table td, table th { + padding: 8px 10px; +} + +table.data-table td { + background: #F6F6F6; + border: 1px solid #E6E6E6; +} + +table.data-table tr.even td { + background: #FCFCFC; +} + +/* Misc classes */ + +.small { + font-size: 0.9em; +} + +.smaller { + font-size: 0.8em; +} + +.smallest { + font-size: 0.7em; +} + +.large { + font-size: 1.1em; +} + +.larger { + font-size: 1.2em; +} + +.largest { + font-size: 1.3em; +} + +.hidden { + display: none; +} + +.quiet { + color: #666; +} + +.loud { + color: #000; +} + +.highlight { + background: #FF0; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +.error, .notice, .success { + border: 1px solid #DDD; + padding: 5px; + margin: 5px; +} + +.error { + background: #FBE3E4; + color: #8A1F11; + border-color: #FBC2C4; +} + +.error a { + color: #8A1F11; +} + +.notice { + background: #FFF6BF; + color: #514721; + border-color: #FFD324; +} + +.notice a { + color: #514721; +} + +.success { + background: #E6EFC2; + color: #264409; + border-color: #C6D880; +} + +.success a { + color: #264409; +} + +div.more { + padding-top: 6px; +} + +.more a, a.more { + color: #666; +} + +.more a:hover, a.more:hover { + color: #002; +} + +/* + Forms +------------------------------------------------------------------- */ + +label { + font-weight: bold; + cursor: pointer; +} + +fieldset { + padding: 1.4em; + margin: 0 0 1.5em 0; + border: 5px solid white; +} + +legend { + font-weight: bold; + font-size: 1.2em; +} + +textarea { + overflow: auto; +} + +input.text, textarea, select { + background: #FCFCFC; + border: 1px inset #AAA; + margin: 0.5em 0; + padding: 4px 5px; +} + +input.text:focus, textarea:focus, select:focus { + background: #FFFFF5; +} + +input.button, input.gsc-search-button { + border: 1px outset #AAA; + padding: 4px 5px; + + height: 30px; + width: 150px; + + -moz-box-shadow: 2px 1px 3px #AAA; + -webkit-box-shadow: 2px 1px 3px #AAA; + box-shadow: 2px 1px 3px #AAA; + + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0.26, rgb(199,199,199)), + color-stop(0.68, rgb(240,240,240)) + ); + background-image: -moz-linear-gradient( + center bottom, + rgb(199,199,199) 26%, + rgb(240,240,240) 68% + ); +} + +input.button:active, input.gsc-search-button:active { + border-style: inset; + padding: 7px 8px; + + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0.16, rgb(199,199,199)), + color-stop(0.58, rgb(240,240,240)) + ); + background-image: -moz-linear-gradient( + center bottom, + rgb(199,199,199) 16%, + rgb(240,240,240) 58% + ); +} + +.form-error { + border-color: #F00; +} + +/* + Alignment +------------------------------------------------------------------- */ + +/* General */ + +.center, .aligncenter { + display: block; + margin-left: auto; + margin-right: auto; +} + +/* Images */ + +img.bordered, img.alignleft, img.alignright, img.aligncenter { + background-color: #FFF; + border: 1px solid #DDD; + padding: 3px; +} + +img.alignleft, img.left { + margin: 0 1.5em 1em 0; +} + +img.alignright, img.right { + margin: 0 0 1em 1.5em; +} + +/* Floats */ + +.left, .alignleft { + float: left; +} + +.right, .alignright { + float: right; +} + +.clear, .clearer { + clear: both; +} + +.clearer { + display: block; + font-size: 0; + line-height: 0; +} + +/* Columns */ + +.col2 { + width: 47%; +} + +/* + Separators +------------------------------------------------------------------- */ + +.content-separator, .archive-separator { + background: #EEE; + clear: both; + color: #FFE; + display: block; + font-size: 0; + height: 1px; + line-height: 0; + margin: 12px 0 24px; +} + +.archive-separator { + margin: 0 0 14px; +} + +.separator-vertical { + background: url('/images/separator-vertical.gif') repeat-y center top; +} + +.archive-year { + background: #F7F7F2 url('/images/box.gif') no-repeat left top; + padding: 5px; + text-align: center; + margin-top: 20px; + margin-bottom: 20px; +} + +/* + Posts +------------------------------------------------------------------- */ + +.post { + margin-bottom: 24px; +} + +.post a { + text-decoration: none; +} + +.post a:hover, .post-body a { + text-decoration: underline; +} + +.post-title { + border-bottom: 1px solid #E5E5E5; +} + +.post-date { + color: #777; + font-size: 0.9em; + padding: 8px 0 0; +} + +.post-date a { + color: #444; +} + +.post-body { + padding-top: 12px; +} + +.post-meta { + background: #FCFCFC; + border: 1px solid #ECECEC; + color: #777; + font-size: 0.9em; + margin-top: 16px; + padding: 6px 10px; +} + +.post-meta a { + color: #345; +} + +.post-meta a:hover { + color: #001; +} + +ul.nice-list { + border-top: 1px solid #F0F0F0; + margin-left: 0; + margin-right: 0; +} + +ul.nice-list li { + border-bottom: 1px solid #F0F0F0; + list-style: none; + padding: 6px 5px; +} + +ul.nice-list li a { + text-decoration: none; +} + +ul.nice-list li a:hover { + text-decoration: underline; +} + +ul.nice-list span { + color: #666; +} + +ul.nice-list img { + margin-left: 3px; + margin-right: 3px; +} + +ul.nice-list input[type=image] { + margin-left: 3px; + margin-right: 3px; +} + +#sidebar ul.nice-list li, #sidebar ul.nice-list { + border-color: #E0E0E0; +} + +/* Archives */ +.archive-pagination { + margin-bottom: 1.6em; +} + +.archive-pagination a { + text-decoration: none; +} + +.archive-pagination a:hover { + text-decoration: underline; +} + +.archive-post { + margin-bottom: 14px; +} + +.archive-post-date { + background: #F5F5F5; + + border: 4px solid white; + + -moz-box-shadow: 3px 2px 8px #AAA; + -webkit-box-shadow: 3px 2px 8px #AAA; + box-shadow: 3px 2px 8px #AAA; + + float: left; + margin-right: 16px; + padding: 2px 0 5px; + text-align: center; + width: 46px; +} + +.archive-post .post-date { + border: none; + padding: 0; +} + +.archive-post-day { + font: normal 1.6em Georgia, serif; +} + +.archive-post .post-date, .archive-post-title { + padding-top: 3px; +} + +/* + Thumbnails +------------------------------------------------------------------- */ + +.thumbnails { + margin: 0 0 1em -8px; +} + +.thumbnails a.thumb { + background: #DAD6D0; + display: block; + float: left; + margin: 0 0 8px 8px; + padding: 1px; +} + +.thumbnails a.thumb:hover { + background: #AAA; +} + +.thumbnails .thumb img { + display: block; +} + +/* + Box +------------------------------------------------------------------- */ + +.box { + background: url('/images/box.gif') no-repeat left top; + border-bottom: 1px solid #DFDFDA; + border-top: 1px solid #FFF; + padding: 16px 20px 0; +} + +.box a { + color: #951; +} + +.box a:hover { + color: #310; +} + +.box-title { + color: #665; + font: normal 1.6em sans-serif; +} + +.box-content { + padding: 8px 0; +} + +/* + Layout +------------------------------------------------------------------- */ + +/* Common */ +.center-wrapper { + width: 960px; + margin: 0 auto; +} + +/* Header */ + +#header-wrapper { + background: #2F2F2F url('/images/header.gif') repeat-x left top; +} + +#header-wrapper-2 { + background: url('/images/header-wrapper-2.gif') repeat-y center top; +} + +#header { + background: #333 url('/images/header.gif') repeat-x left top; + padding: 32px 32px 0 46px; +} + +#help-wrapper { + background: url('/images/help.gif') no-repeat left top; + height: 39px; + margin: -8px 0 0 auto; + width: 290px; +} + +#help { + color: #666; + font-size: 1.2em; + padding: 10px 28px 0 32px; +} + +#help a { + color: #999; + text-decoration: none; +} + +#help a:hover { + color: #DDD; +} + +#help span.text-separator { + color: #444; + padding: 0 7px; +} + +#logo { + color: #FFF; +} + +#site-title a { + text-decoration: none; +} + +#site-title, #site-title a { + color: #FFF; +} + +#site-title span, #site-title a span { + color: #DDD; +} + +#site-slogan { + color: #B58361; + font-size: 1.3em; +} + +/* Navigation */ + +ul.tabbed { + display: inline; + margin: 0; + padding: 0; +} + +ul.tabbed li { + float: left; + list-style: none; +} + +ul.tabbed a { + text-decoration: none; +} + +#navigation-wrapper { + background: url('/images/navigation.gif') repeat-x left top; +} + +#navigation-wrapper-2 { + background: url('/images/navigation-wrapper-2.gif') no-repeat center top; +} + +#navigation { + background: url('/images/navigation.gif') repeat-x left top; + min-height: 46px; + padding: 0 8px; +} + +#navigation a { + color: #EAE6DD; + display: block; + font-weight: bold; + font-size: 1.3em; + padding: 12px 12px 11px; +} + +#navigation a:hover { + color: #FFF; +} + +#navigation li.current_page_item a, #navigation li.current_page_parent a { + color: #FFE; +} + +#navigation li.current_page_item a { + background: url('/images/navigation-arrow-2.gif') no-repeat center bottom; +} + +#navigation li.current_page_parent a { + background: url('/images/navigation-arrow.gif') no-repeat center bottom; +} + +/* Subnav */ + +#subnav-wrapper { + background: #E9E9E9 url('/images/subnav-wrapper.gif') repeat-x left bottom; +} + +#subnav-wrapper-2 { + background: url('/images/subnav-wrapper-2.gif') no-repeat center bottom; +} + +#subnav { + padding: 0 8px; +} + +#subnav a { + color: #666; + display: block; + font: bold 1.1em sans-serif; + padding: 12px 12px; +} + +#subnav a:hover { + color: #111; +} + +#subnav li.current_page_item a { + color: #333; +} + +/* Content */ + +.content { + font-size: 1.1em; +} + +#content-wrapper { + background: #F6F6F6 url('/images/content-wrapper.gif') repeat-y center top; +} + +.content#content-two-columns { + background: url('/images/content-two-columns.gif') repeat-y left top; +} + +/* Main */ + +#main-wrapper { + float: right; + width: 698px; +} + +#main { + padding: 24px; +} + +#main .text-separator, #featured .text-separator { + color: #AAA; + padding: 0 5px; +} + +/* Sidebar */ + +#sidebar-wrapper { + float: left; + width: 260px; +} + +/* Footer */ + +#footer-wrapper { + background: url('/images/footer-wrapper.gif') no-repeat center bottom; + border-top: 1px solid #999; + padding-bottom: 20px; +} + +#footer { + background: #808080; + font-size: 1.1em; + padding: 12px 16px; +} + +#footer a { + color: #DDD; + text-decoration: none; +} + +#footer a:hover { + color: #FFF; +} + +#footer span.text-separator { + color: #999; + padding: 0 3px; +} + +/* Bottom */ + +#bottom { + color: #666; + padding: 0 6px 12px; + margin-top: -6px; +} + +#bottom a { + color: #555; + text-decoration: none; +} + +#bottom a:hover, #bottom .right a:hover { + color: #002; +} + +#bottom span.text-separator { + color: #888; + padding: 0 3px; +} + +#bottom .right, #bottom .right a { + color: #777; +} + +/* Featured Box */ +#featured-wrapper { + background: url('/images/gradient-light.gif') repeat-x left bottom; + border-bottom: 1px solid #E0E0E0; + padding-bottom: 22px; +} + +#featured { + padding: 42px 124px 12px 48px; +} + +#featured h2 { + font: normal 3em sans-serif; + margin: 0; +} + +#featured h2 span { + color: #43B16C; +} + +/* + Media Browser +*/ + +#media-browser .centered { + display: inline-block; + text-align: center +} + +#media-browser .caption { + padding: 4px; + font-size: 0.8em; + border-bottom: 1px dotted black; +} + +#media-browser .thumbnail-container { + margin: 10px 20px 10px 17px; + text-align: center +} + +#media-browser #prevNext { + text-align: center; +} + +/* + Misc overriding classes +------------------------------------------------------------------- */ + +/* Border */ + +.noborder { + border: 0; +} + +.notborder { + border-top: 0; +} + +.norborder { + border-right: 0; +} + +.nobborder { + border-bottom: 0; +} + +.nolborder { + border-left: 0; +} + +/* Margin */ + +.nomargin { + margin: 0; +} + +.notmargin { + margin-top: 0; +} + +.normargin { + margin-right: 0; +} + +.nobmargin { + margin-bottom: 0; +} + +.nolmargin { + margin-left: 0; +} + +/* Padding */ + +.nopadding { + padding: 0; +} + +.notpadding { + padding-top: 0; +} + +.norpadding { + padding-right: 0; +} + +.nobpadding { + padding-bottom: 0; +} + +.nolpadding { + padding-left: 0; +} + +/* Single Line IE Fixes */ +* html .separator-vertical, * html .content { + height: 0.01%; + min-height: 0.01%; +} + +/* misc */ +#placeHolder, #imgs { + border: 2px inset white; + height: 120px; +} + +#placeHolder img { + margin: 4px; + border: 4px solid white; + + -moz-box-shadow: 3px 2px 8px #AAA; + -webkit-box-shadow: 3px 2px 8px #AAA; + box-shadow: 3px 2px 8px #AAA; +} + +#imgs { + border: 2px inset white; + height: 100px; +} + +.post #Drafts, .post #Posts, .post #Pages { + margin-top: 40px; + max-height: 700px; + overflow-y: auto; +} + + diff --git a/war/css/wysiwyg.css b/war/css/wysiwyg.css new file mode 100644 index 0000000..8b04558 --- /dev/null +++ b/war/css/wysiwyg.css @@ -0,0 +1,9 @@ +@import '/css/style.css'; + +body { + background-color: white; +} + +blockquote { + width: 70%; +} \ No newline at end of file diff --git a/war/images/add.png b/war/images/add.png new file mode 100755 index 0000000..6332fef Binary files /dev/null and b/war/images/add.png differ diff --git a/war/images/atom.gif b/war/images/atom.gif new file mode 100644 index 0000000..e6bc11f Binary files /dev/null and b/war/images/atom.gif differ diff --git a/war/images/box.gif b/war/images/box.gif new file mode 100755 index 0000000..1a361c0 Binary files /dev/null and b/war/images/box.gif differ diff --git a/war/images/buttons.gif b/war/images/buttons.gif new file mode 100755 index 0000000..2e464d0 Binary files /dev/null and b/war/images/buttons.gif differ diff --git a/war/images/chosen-sprite.png b/war/images/chosen-sprite.png new file mode 100644 index 0000000..6ec9bbf Binary files /dev/null and b/war/images/chosen-sprite.png differ diff --git a/war/images/clipboard.png b/war/images/clipboard.png new file mode 100755 index 0000000..08647f1 Binary files /dev/null and b/war/images/clipboard.png differ diff --git a/war/images/content-two-columns.gif b/war/images/content-two-columns.gif new file mode 100755 index 0000000..3ca2f15 Binary files /dev/null and b/war/images/content-two-columns.gif differ diff --git a/war/images/content-wrapper.gif b/war/images/content-wrapper.gif new file mode 100755 index 0000000..298bbf8 Binary files /dev/null and b/war/images/content-wrapper.gif differ diff --git a/war/images/cross.png b/war/images/cross.png new file mode 100755 index 0000000..1514d51 Binary files /dev/null and b/war/images/cross.png differ diff --git a/war/images/feed.png b/war/images/feed.png new file mode 100755 index 0000000..315c4f4 Binary files /dev/null and b/war/images/feed.png differ diff --git a/war/images/footer-wrapper.gif b/war/images/footer-wrapper.gif new file mode 100755 index 0000000..1a35caf Binary files /dev/null and b/war/images/footer-wrapper.gif differ diff --git a/war/images/gaelyk-favicon.png b/war/images/gaelyk-favicon.png new file mode 100644 index 0000000..dd3f4bc Binary files /dev/null and b/war/images/gaelyk-favicon.png differ diff --git a/war/images/gradient-light.gif b/war/images/gradient-light.gif new file mode 100755 index 0000000..2675f60 Binary files /dev/null and b/war/images/gradient-light.gif differ diff --git a/war/images/header-wrapper-2.gif b/war/images/header-wrapper-2.gif new file mode 100755 index 0000000..a8c593b Binary files /dev/null and b/war/images/header-wrapper-2.gif differ diff --git a/war/images/header.gif b/war/images/header.gif new file mode 100755 index 0000000..73ad174 Binary files /dev/null and b/war/images/header.gif differ diff --git a/war/images/help.gif b/war/images/help.gif new file mode 100755 index 0000000..61434a4 Binary files /dev/null and b/war/images/help.gif differ diff --git a/war/images/icon-delicious.png b/war/images/icon-delicious.png new file mode 100644 index 0000000..eba3519 Binary files /dev/null and b/war/images/icon-delicious.png differ diff --git a/war/images/icon-greader.png b/war/images/icon-greader.png new file mode 100644 index 0000000..31b53ca Binary files /dev/null and b/war/images/icon-greader.png differ diff --git a/war/images/icon-twitter.png b/war/images/icon-twitter.png new file mode 100644 index 0000000..9d82663 Binary files /dev/null and b/war/images/icon-twitter.png differ diff --git a/war/images/image-not-found.png b/war/images/image-not-found.png new file mode 100644 index 0000000..cd1172f Binary files /dev/null and b/war/images/image-not-found.png differ diff --git a/war/images/images.png b/war/images/images.png new file mode 100755 index 0000000..184860d Binary files /dev/null and b/war/images/images.png differ diff --git a/war/images/images2.png b/war/images/images2.png new file mode 100755 index 0000000..cdb3e00 Binary files /dev/null and b/war/images/images2.png differ diff --git a/war/images/navigation-arrow-2.gif b/war/images/navigation-arrow-2.gif new file mode 100755 index 0000000..b94beeb Binary files /dev/null and b/war/images/navigation-arrow-2.gif differ diff --git a/war/images/navigation-arrow.gif b/war/images/navigation-arrow.gif new file mode 100755 index 0000000..06dd8c5 Binary files /dev/null and b/war/images/navigation-arrow.gif differ diff --git a/war/images/navigation-wrapper-2.gif b/war/images/navigation-wrapper-2.gif new file mode 100755 index 0000000..894950a Binary files /dev/null and b/war/images/navigation-wrapper-2.gif differ diff --git a/war/images/navigation.gif b/war/images/navigation.gif new file mode 100755 index 0000000..fc4fdcb Binary files /dev/null and b/war/images/navigation.gif differ diff --git a/war/images/newspaper.png b/war/images/newspaper.png new file mode 100755 index 0000000..6a2ecce Binary files /dev/null and b/war/images/newspaper.png differ diff --git a/war/images/page_white_text.png b/war/images/page_white_text.png new file mode 100755 index 0000000..813f712 Binary files /dev/null and b/war/images/page_white_text.png differ diff --git a/war/images/pencil.png b/war/images/pencil.png new file mode 100755 index 0000000..0bfecd5 Binary files /dev/null and b/war/images/pencil.png differ diff --git a/war/images/sample-gravatar.jpg b/war/images/sample-gravatar.jpg new file mode 100755 index 0000000..2e76b12 Binary files /dev/null and b/war/images/sample-gravatar.jpg differ diff --git a/war/images/separator-vertical.gif b/war/images/separator-vertical.gif new file mode 100755 index 0000000..dc482c3 Binary files /dev/null and b/war/images/separator-vertical.gif differ diff --git a/war/images/subnav-wrapper-2.gif b/war/images/subnav-wrapper-2.gif new file mode 100755 index 0000000..d28e555 Binary files /dev/null and b/war/images/subnav-wrapper-2.gif differ diff --git a/war/images/subnav-wrapper.gif b/war/images/subnav-wrapper.gif new file mode 100755 index 0000000..439ec43 Binary files /dev/null and b/war/images/subnav-wrapper.gif differ diff --git a/war/images/toolbar.gif b/war/images/toolbar.gif new file mode 100755 index 0000000..e6eb2da Binary files /dev/null and b/war/images/toolbar.gif differ diff --git a/war/images/transparent.png b/war/images/transparent.png new file mode 100644 index 0000000..7c0bd7e Binary files /dev/null and b/war/images/transparent.png differ diff --git a/war/js/chosen.jquery.min.js b/war/js/chosen.jquery.min.js new file mode 100644 index 0000000..da2e632 --- /dev/null +++ b/war/js/chosen.jquery.min.js @@ -0,0 +1,9 @@ +/* +Chosen, a Select Box Enhancer for jQuery and Protoype +by Patrick Filler for Harvest, http://getharvest.com + +Available for use under the MIT License, http://en.wikipedia.org/wiki/MIT_License + +Copyright (c) 2011 by Harvest +*/ +(function(){var $,Chosen,SelectParser,get_side_border_padding,root;var __bind=function(fn,me){return function(){return fn.apply(me,arguments);};};root=typeof exports!=="undefined"&&exports!==null?exports:this;$=jQuery;$.fn.extend({chosen:function(data,options){return $(this).each(function(input_field){if(!($(this)).hasClass("chzn-done")){return new Chosen(this,data,options);}});}});Chosen=(function(){function Chosen(elmn){this.set_default_values();this.form_field=elmn;this.form_field_jq=$(this.form_field);this.is_multiple=this.form_field.multiple;this.default_text_default=this.form_field.multiple?"Select one or more options":"Select an option";this.set_up_html();this.register_observers();this.form_field_jq.addClass("chzn-done");}Chosen.prototype.set_default_values=function(){this.click_test_action=__bind(function(evt){return this.test_active_click(evt);},this);this.active_field=false;this.mouse_on_container=false;this.results_showing=false;this.result_highlighted=null;this.result_single_selected=null;return this.choices=0;};Chosen.prototype.set_up_html=function(){var container_div,dd_top,dd_width,sf_width;this.container_id=this.form_field.id+"_chzn";this.f_width=this.form_field_jq.width();this.default_text=this.form_field_jq.attr("title")?this.form_field_jq.attr("title"):this.default_text_default;container_div=$("
",{id:this.container_id,"class":"chzn-container",style:"width: "+this.f_width+"px;"});if(this.is_multiple){container_div.html('
    ');}else{container_div.html(''+this.default_text+'
      ');}this.form_field_jq.hide().after(container_div);this.container=$("#"+this.container_id);this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single"));this.dropdown=this.container.find("div.chzn-drop").first();dd_top=this.container.height();dd_width=this.f_width-get_side_border_padding(this.dropdown);this.dropdown.css({width:dd_width+"px",top:dd_top+"px"});this.search_field=this.container.find("input").first();this.search_results=this.container.find("ul.chzn-results").first();this.search_field_scale();this.search_no_results=this.container.find("li.no-results").first();if(this.is_multiple){this.search_choices=this.container.find("ul.chzn-choices").first();this.search_container=this.container.find("li.search-field").first();}else{this.search_container=this.container.find("div.chzn-search").first();this.selected_item=this.container.find(".chzn-single").first();sf_width=dd_width-get_side_border_padding(this.search_container)-get_side_border_padding(this.search_field);this.search_field.css({width:sf_width+"px"});}this.results_build();return this.set_tab_index();};Chosen.prototype.register_observers=function(){this.container.click(__bind(function(evt){return this.container_click(evt);},this));this.container.mouseenter(__bind(function(evt){return this.mouse_enter(evt);},this));this.container.mouseleave(__bind(function(evt){return this.mouse_leave(evt);},this));this.search_results.click(__bind(function(evt){return this.search_results_click(evt);},this));this.search_results.mouseover(__bind(function(evt){return this.search_results_mouseover(evt);},this));this.search_results.mouseout(__bind(function(evt){return this.search_results_mouseout(evt);},this));this.form_field_jq.bind("liszt:updated",__bind(function(evt){return this.results_update_field(evt);},this));this.search_field.blur(__bind(function(evt){return this.input_blur(evt);},this));this.search_field.keyup(__bind(function(evt){return this.keyup_checker(evt);},this));this.search_field.keydown(__bind(function(evt){return this.keydown_checker(evt);},this));if(this.is_multiple){this.search_choices.click(__bind(function(evt){return this.choices_click(evt);},this));return this.search_field.focus(__bind(function(evt){return this.input_focus(evt);},this));}else{return this.selected_item.focus(__bind(function(evt){return this.activate_field(evt);},this));}};Chosen.prototype.container_click=function(evt){if(evt&&evt.type==="click"){evt.stopPropagation();}if(!this.pending_destroy_click){if(!this.active_field){if(this.is_multiple){this.search_field.val("");}$(document).click(this.click_test_action);this.results_show();}else{if(!this.is_multiple&&evt&&($(evt.target)===this.selected_item||$(evt.target).parents("a.chzn-single").length)){evt.preventDefault();this.results_toggle();}}return this.activate_field();}else{return this.pending_destroy_click=false;}};Chosen.prototype.mouse_enter=function(){return this.mouse_on_container=true;};Chosen.prototype.mouse_leave=function(){return this.mouse_on_container=false;};Chosen.prototype.input_focus=function(evt){if(!this.active_field){return setTimeout((__bind(function(){return this.container_click();},this)),50);}};Chosen.prototype.input_blur=function(evt){if(!this.mouse_on_container){this.active_field=false;return setTimeout((__bind(function(){return this.blur_test();},this)),100);}};Chosen.prototype.blur_test=function(evt){if(!this.active_field&&this.container.hasClass("chzn-container-active")){return this.close_field();}};Chosen.prototype.close_field=function(){$(document).unbind("click",this.click_test_action);if(!this.is_multiple){this.selected_item.attr("tabindex",this.search_field.attr("tabindex"));this.search_field.attr("tabindex",-1);}this.active_field=false;this.results_hide();this.container.removeClass("chzn-container-active");this.winnow_results_clear();this.clear_backstroke();this.show_search_field_default();return this.search_field_scale();};Chosen.prototype.activate_field=function(){if(!this.is_multiple&&!this.active_field){this.search_field.attr("tabindex",this.selected_item.attr("tabindex"));this.selected_item.attr("tabindex",-1);}this.container.addClass("chzn-container-active");this.active_field=true;this.search_field.val(this.search_field.val());return this.search_field.focus();};Chosen.prototype.test_active_click=function(evt){if($(evt.target).parents("#"+this.container.id).length){return this.active_field=true;}else{return this.close_field();}};Chosen.prototype.results_build=function(){var content,data,startTime,_i,_len,_ref;startTime=new Date();this.parsing=true;this.results_data=SelectParser.select_to_array(this.form_field);if(this.is_multiple&&this.choices>0){this.search_choices.find("li.search-choice").remove();this.choices=0;}else{if(!this.is_multiple){this.selected_item.find("span").text(this.default_text);}}content="";_ref=this.results_data;for(_i=0,_len=_ref.length;_i<_len;_i++){data=_ref[_i];if(data.group){content+=this.result_add_group(data);}else{if(!data.empty){content+=this.result_add_option(data);if(data.selected&&this.is_multiple){this.choice_build(data);}else{if(data.selected&&!this.is_multiple){this.selected_item.find("span").text(data.text);}}}}}this.show_search_field_default();this.search_field_scale();this.search_results.html(content);return this.parsing=false;};Chosen.prototype.result_add_group=function(group){if(!group.disabled){group.dom_id=this.form_field.id+"chzn_g_"+group.array_index;return'
    • '+$("
      ").text(group.label).html()+"
    • ";}else{return"";}};Chosen.prototype.result_add_option=function(option){var classes;if(!option.disabled){option.dom_id=this.form_field.id+"chzn_o_"+option.array_index;classes=option.selected&&this.is_multiple?[]:["active-result"];if(option.selected){classes.push("result-selected");}if(option.group_array_index!=null){classes.push("group-option");}return'
    • '+$("
      ").text(option.text).html()+"
    • ";}else{return"";}};Chosen.prototype.results_update_field=function(){this.result_clear_highlight();this.result_single_selected=null;return this.results_build();};Chosen.prototype.result_do_highlight=function(el){var high_bottom,high_top,maxHeight,visible_bottom,visible_top;if(el.length){this.result_clear_highlight();this.result_highlight=el;this.result_highlight.addClass("highlighted");maxHeight=parseInt(this.search_results.css("maxHeight"),10);visible_top=this.search_results.scrollTop();visible_bottom=maxHeight+visible_top;high_top=this.result_highlight.position().top+this.search_results.scrollTop();high_bottom=high_top+this.result_highlight.outerHeight();if(high_bottom>=visible_bottom){return this.search_results.scrollTop((high_bottom-maxHeight)>0?high_bottom-maxHeight:0);}else{if(high_top'+item.text+'');link=$("#"+choice_id).find("a").first();return link.click(__bind(function(evt){return this.choice_destroy_link_click(evt);},this));};Chosen.prototype.choice_destroy_link_click=function(evt){evt.preventDefault();this.pending_destroy_click=true;return this.choice_destroy($(evt.target));};Chosen.prototype.choice_destroy=function(link){this.choices-=1;this.show_search_field_default();if(this.is_multiple&&this.choices>0&&this.search_field.val().length<1){this.results_hide();}this.result_deselect(link.attr("rel"));return link.parents("li").first().remove();};Chosen.prototype.result_select=function(){var high,high_id,item,position;if(this.result_highlight){high=this.result_highlight;high_id=high.attr("id");this.result_clear_highlight();high.addClass("result-selected");if(this.is_multiple){this.result_deactivate(high);}else{this.result_single_selected=high;}position=high_id.substr(high_id.lastIndexOf("_")+1);item=this.results_data[position];item.selected=true;this.form_field.options[item.options_index].selected=true;if(this.is_multiple){this.choice_build(item);}else{this.selected_item.find("span").first().text(item.text);}this.results_hide();this.search_field.val("");this.form_field_jq.trigger("change");return this.search_field_scale();}};Chosen.prototype.result_activate=function(el){return el.addClass("active-result").show();};Chosen.prototype.result_deactivate=function(el){return el.removeClass("active-result").hide();};Chosen.prototype.result_deselect=function(pos){var result,result_data;result_data=this.results_data[pos];result_data.selected=false;this.form_field.options[result_data.options_index].selected=false;result=$("#"+this.form_field.id+"chzn_o_"+pos);result.removeClass("result-selected").addClass("active-result").show();this.result_clear_highlight();this.winnow_results();this.form_field_jq.trigger("change");return this.search_field_scale();};Chosen.prototype.results_search=function(evt){if(this.results_showing){return this.winnow_results();}else{return this.results_show();}};Chosen.prototype.winnow_results=function(){var found,option,part,parts,regex,result_id,results,searchText,startTime,startpos,text,zregex,_i,_j,_len,_len2,_ref;startTime=new Date();this.no_results_clear();results=0;searchText=this.search_field.val()===this.default_text?"":$.trim(this.search_field.val());regex=new RegExp("^"+searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i");zregex=new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i");_ref=this.results_data;for(_i=0,_len=_ref.length;_i<_len;_i++){option=_ref[_i];if(!option.disabled&&!option.empty){if(option.group){$("#"+option.dom_id).hide();}else{if(!(this.is_multiple&&option.selected)){found=false;result_id=option.dom_id;if(regex.test(option.text)){found=true;results+=1;}else{if(option.text.indexOf(" ")>=0||option.text.indexOf("[")===0){parts=option.text.replace(/\[|\]/g,"").split(" ");if(parts.length){for(_j=0,_len2=parts.length;_j<_len2;_j++){part=parts[_j];if(regex.test(part)){found=true;results+=1;}}}}}if(found){if(searchText.length){startpos=option.text.search(zregex);text=option.text.substr(0,startpos+searchText.length)+""+option.text.substr(startpos+searchText.length);text=text.substr(0,startpos)+""+text.substr(startpos);}else{text=option.text;}if($("#"+result_id).html!==text){$("#"+result_id).html(text);}this.result_activate($("#"+result_id));if(option.group_array_index!=null){$("#"+this.results_data[option.group_array_index].dom_id).show();}}else{if(this.result_highlight&&result_id===this.result_highlight.attr("id")){this.result_clear_highlight();}this.result_deactivate($("#"+result_id));}}}}}if(results<1&&searchText.length){return this.no_results(searchText);}else{return this.winnow_results_set_highlight();}};Chosen.prototype.winnow_results_clear=function(){var li,lis,_i,_len,_results;this.search_field.val("");lis=this.search_results.find("li");_results=[];for(_i=0,_len=lis.length;_i<_len;_i++){li=lis[_i];li=$(li);_results.push(li.hasClass("group-result")?li.show():!this.is_multiple||!li.hasClass("result-selected")?this.result_activate(li):void 0);}return _results;};Chosen.prototype.winnow_results_set_highlight=function(){var do_high;if(!this.result_highlight){do_high=this.search_results.find(".active-result").first();if(do_high){return this.result_do_highlight(do_high);}}};Chosen.prototype.no_results=function(terms){var no_results_html;no_results_html=$('
    • No results match ""
    • ');no_results_html.find("span").first().text(terms);return this.search_results.append(no_results_html);};Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove();};Chosen.prototype.keydown_arrow=function(){var first_active,next_sib;if(!this.result_highlight){first_active=this.search_results.find("li.active-result").first();if(first_active){this.result_do_highlight($(first_active));}}else{if(this.results_showing){next_sib=this.result_highlight.nextAll("li.active-result").first();if(next_sib){this.result_do_highlight(next_sib);}}}if(!this.results_showing){return this.results_show();}};Chosen.prototype.keyup_arrow=function(){var prev_sibs;if(!this.results_showing&&!this.is_multiple){return this.results_show();}else{if(this.result_highlight){prev_sibs=this.result_highlight.prevAll("li.active-result");if(prev_sibs.length){return this.result_do_highlight(prev_sibs.first());}else{if(this.choices>0){this.results_hide();}return this.result_clear_highlight();}}}};Chosen.prototype.keydown_backstroke=function(){if(this.pending_backstroke){this.choice_destroy(this.pending_backstroke.find("a").first());return this.clear_backstroke();}else{this.pending_backstroke=this.search_container.siblings("li.search-choice").last();return this.pending_backstroke.addClass("search-choice-focus");}};Chosen.prototype.clear_backstroke=function(){if(this.pending_backstroke){this.pending_backstroke.removeClass("search-choice-focus");}return this.pending_backstroke=null;};Chosen.prototype.keyup_checker=function(evt){var stroke,_ref;stroke=(_ref=evt.which)!=null?_ref:evt.keyCode;this.search_field_scale();switch(stroke){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0){return this.keydown_backstroke();}else{if(!this.pending_backstroke){this.result_clear_highlight();return this.results_search();}}break;case 13:evt.preventDefault();if(this.results_showing){return this.result_select();}break;case 27:if(this.results_showing){return this.results_hide();}break;case 9:case 38:case 40:case 16:break;default:return this.results_search();}};Chosen.prototype.keydown_checker=function(evt){var stroke,_ref;stroke=(_ref=evt.which)!=null?_ref:evt.keyCode;this.search_field_scale();if(stroke!==8&&this.pending_backstroke){this.clear_backstroke();}switch(stroke){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.mouse_on_container=false;break;case 13:evt.preventDefault();break;case 38:evt.preventDefault();this.keyup_arrow();break;case 40:this.keydown_arrow();break;}};Chosen.prototype.search_field_scale=function(){var dd_top,div,h,style,style_block,styles,w,_i,_len;if(this.is_multiple){h=0;w=0;style_block="position:absolute; left: -1000px; top: -1000px; display:none;";styles=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(_i=0,_len=styles.length;_i<_len;_i++){style=styles[_i];style_block+=style+":"+this.search_field.css(style)+";";}div=$("
      ",{style:style_block});div.text(this.search_field.val());$("body").append(div);w=div.width()+25;div.remove();if(w>this.f_width-10){w=this.f_width-10;}this.search_field.css({width:w+"px"});dd_top=this.container.height();return this.dropdown.css({top:dd_top+"px"});}};return Chosen;})();get_side_border_padding=function(elmt){var side_border_padding;return side_border_padding=elmt.outerWidth()-elmt.width();};root.get_side_border_padding=get_side_border_padding;SelectParser=(function(){function SelectParser(){this.options_index=0;this.parsed=[];}SelectParser.prototype.add_node=function(child){if(child.nodeName==="OPTGROUP"){return this.add_group(child);}else{return this.add_option(child);}};SelectParser.prototype.add_group=function(group){var group_position,option,_i,_len,_ref,_results;group_position=this.parsed.length;this.parsed.push({array_index:group_position,group:true,label:group.label,children:0,disabled:group.disabled});_ref=group.childNodes;_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++){option=_ref[_i];_results.push(this.add_option(option,group_position,group.disabled));}return _results;};SelectParser.prototype.add_option=function(option,group_position,group_disabled){if(option.nodeName==="OPTION"){if(option.text!==""){if(group_position!=null){this.parsed[group_position].children+=1;}this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:option.value,text:option.text,selected:option.selected,disabled:group_disabled===true?group_disabled:option.disabled,group_array_index:group_position});}else{this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:true});}return this.options_index+=1;}};return SelectParser;})();SelectParser.select_to_array=function(select){var child,parser,_i,_len,_ref;parser=new SelectParser();_ref=select.childNodes;for(_i=0,_len=_ref.length;_i<_len;_i++){child=_ref[_i];parser.add_node(child);}return parser.parsed;};root.SelectParser=SelectParser;}).call(this); \ No newline at end of file diff --git a/war/js/highlight.js b/war/js/highlight.js new file mode 100644 index 0000000..91b9b73 --- /dev/null +++ b/war/js/highlight.js @@ -0,0 +1,585 @@ +/* +Syntax highlighting with language autodetection. +http://softwaremaniacs.org/soft/highlight/ +*/ + +var hljs = new function() { + + /* Utility functions */ + + function escape(value) { + return value.replace(/&/gm, '&').replace(/'; + } + + while (stream1.length || stream2.length) { + var current = selectStream().splice(0, 1)[0]; + result += escape(value.substr(processed, current.offset - processed)); + processed = current.offset; + if ( current.event == 'start') { + result += open(current.node); + nodeStack.push(current.node); + } else if (current.event == 'stop') { + var i = nodeStack.length; + do { + i--; + var node = nodeStack[i]; + result += (''); + } while (node != current.node); + nodeStack.splice(i, 1); + while (i < nodeStack.length) { + result += open(nodeStack[i]); + i++; + } + } + } + result += value.substr(processed); + return result; + } + + /* Core highlighting function */ + + function highlight(language_name, value) { + + function subMode(lexem, mode) { + for (var i = 0; i < mode.contains.length; i++) { + if (mode.contains[i].beginRe.test(lexem)) { + return mode.contains[i]; + } + } + } + + function endOfMode(mode_index, lexem) { + if (modes[mode_index].end && modes[mode_index].endRe.test(lexem)) + return 1; + if (modes[mode_index].endsWithParent) { + var level = endOfMode(mode_index - 1, lexem); + return level ? level + 1 : 0; + } + return 0; + } + + function isIllegal(lexem, mode) { + return mode.illegalRe && mode.illegalRe.test(lexem); + } + + function compileTerminators(mode, language) { + var terminators = []; + + for (var i = 0; i < mode.contains.length; i++) { + terminators.push(mode.contains[i].begin); + } + + var index = modes.length - 1; + do { + if (modes[index].end) { + terminators.push(modes[index].end); + } + index--; + } while (modes[index + 1].endsWithParent); + + if (mode.illegal) { + terminators.push(mode.illegal); + } + + return langRe(language, '(' + terminators.join('|') + ')', true); + } + + function eatModeChunk(value, index) { + var mode = modes[modes.length - 1]; + if (!mode.terminators) { + mode.terminators = compileTerminators(mode, language); + } + mode.terminators.lastIndex = index; + var match = mode.terminators.exec(value); + if (match) + return [value.substr(index, match.index - index), match[0], false]; + else + return [value.substr(index), '', true]; + } + + function keywordMatch(mode, match) { + var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0] + for (var className in mode.keywordGroups) { + if (!mode.keywordGroups.hasOwnProperty(className)) + continue; + var value = mode.keywordGroups[className].hasOwnProperty(match_str); + if (value) + return [className, value]; + } + return false; + } + + function processKeywords(buffer, mode) { + if (!mode.keywords) + return escape(buffer); + var result = ''; + var last_index = 0; + mode.lexemsRe.lastIndex = 0; + var match = mode.lexemsRe.exec(buffer); + while (match) { + result += escape(buffer.substr(last_index, match.index - last_index)); + var keyword_match = keywordMatch(mode, match); + if (keyword_match) { + keyword_count += keyword_match[1]; + result += '' + escape(match[0]) + ''; + } else { + result += escape(match[0]); + } + last_index = mode.lexemsRe.lastIndex; + match = mode.lexemsRe.exec(buffer); + } + result += escape(buffer.substr(last_index, buffer.length - last_index)); + return result; + } + + function processBuffer(buffer, mode) { + if (mode.subLanguage && languages[mode.subLanguage]) { + var result = highlight(mode.subLanguage, buffer); + keyword_count += result.keyword_count; + return result.value; + } else { + return processKeywords(buffer, mode); + } + } + + function startNewMode(mode, lexem) { + var markup = mode.className?'':''; + if (mode.returnBegin) { + result += markup; + mode.buffer = ''; + } else if (mode.excludeBegin) { + result += escape(lexem) + markup; + mode.buffer = ''; + } else { + result += markup; + mode.buffer = lexem; + } + modes.push(mode); + relevance += mode.relevance; + } + + function processModeInfo(buffer, lexem, end) { + var current_mode = modes[modes.length - 1]; + if (end) { + result += processBuffer(current_mode.buffer + buffer, current_mode); + return false; + } + + var new_mode = subMode(lexem, current_mode); + if (new_mode) { + result += processBuffer(current_mode.buffer + buffer, current_mode); + startNewMode(new_mode, lexem); + return new_mode.returnBegin; + } + + var end_level = endOfMode(modes.length - 1, lexem); + if (end_level) { + var markup = current_mode.className?'':''; + if (current_mode.returnEnd) { + result += processBuffer(current_mode.buffer + buffer, current_mode) + markup; + } else if (current_mode.excludeEnd) { + result += processBuffer(current_mode.buffer + buffer, current_mode) + markup + escape(lexem); + } else { + result += processBuffer(current_mode.buffer + buffer + lexem, current_mode) + markup; + } + while (end_level > 1) { + markup = modes[modes.length - 2].className?'':''; + result += markup; + end_level--; + modes.length--; + } + var last_ended_mode = modes[modes.length - 1]; + modes.length--; + modes[modes.length - 1].buffer = ''; + if (last_ended_mode.starts) { + startNewMode(last_ended_mode.starts, ''); + } + return current_mode.returnEnd; + } + + if (isIllegal(lexem, current_mode)) + throw 'Illegal'; + } + + var language = languages[language_name]; + var modes = [language.defaultMode]; + var relevance = 0; + var keyword_count = 0; + var result = ''; + try { + var index = 0; + language.defaultMode.buffer = ''; + do { + var mode_info = eatModeChunk(value, index); + var return_lexem = processModeInfo(mode_info[0], mode_info[1], mode_info[2]); + index += mode_info[0].length; + if (!return_lexem) { + index += mode_info[1].length; + } + } while (!mode_info[2]); + if(modes.length > 1) + throw 'Illegal'; + return { + language: language_name, + relevance: relevance, + keyword_count: keyword_count, + value: result + } + } catch (e) { + if (e == 'Illegal') { + return { + language: null, + relevance: 0, + keyword_count: 0, + value: escape(value) + } + } else { + throw e; + } + } + } + + /* Initialization */ + + function compileModes() { + + function compileMode(mode, language, is_default) { + if (mode.compiled) + return; + + if (!is_default) { + mode.beginRe = langRe(language, mode.begin ? mode.begin : '\\B|\\b'); + if (!mode.end && !mode.endsWithParent) + mode.end = '\\B|\\b' + if (mode.end) + mode.endRe = langRe(language, mode.end); + } + if (mode.illegal) + mode.illegalRe = langRe(language, mode.illegal); + if (mode.relevance == undefined) + mode.relevance = 1; + if (mode.keywords) + mode.lexemsRe = langRe(language, mode.lexems || hljs.IDENT_RE, true); + for (var key in mode.keywords) { + if (!mode.keywords.hasOwnProperty(key)) + continue; + if (mode.keywords[key] instanceof Object) + mode.keywordGroups = mode.keywords; + else + mode.keywordGroups = {'keyword': mode.keywords}; + break; + } + if (!mode.contains) { + mode.contains = []; + } + // compiled flag is set before compiling submodes to avoid self-recursion + // (see lisp where quoted_list contains quoted_list) + mode.compiled = true; + for (var i = 0; i < mode.contains.length; i++) { + compileMode(mode.contains[i], language, false); + } + if (mode.starts) { + compileMode(mode.starts, language, false); + } + } + + for (var i in languages) { + if (!languages.hasOwnProperty(i)) + continue; + compileMode(languages[i].defaultMode, languages[i], true); + } + } + + function initialize() { + if (initialize.called) + return; + initialize.called = true; + compileModes(); + } + + /* Public library functions */ + + function highlightBlock(block, tabReplace, useBR) { + initialize(); + + var text = blockText(block, useBR); + var language = blockLanguage(block); + if (language == 'no-highlight') + return; + if (language) { + var result = highlight(language, text); + } else { + var result = {language: '', keyword_count: 0, relevance: 0, value: escape(text)}; + var second_best = result; + for (var key in languages) { + if (!languages.hasOwnProperty(key)) + continue; + var current = highlight(key, text); + if (current.keyword_count + current.relevance > second_best.keyword_count + second_best.relevance) { + second_best = current; + } + if (current.keyword_count + current.relevance > result.keyword_count + result.relevance) { + second_best = result; + result = current; + } + } + } + + var class_name = block.className; + if (!class_name.match(result.language)) { + class_name = class_name ? (class_name + ' ' + result.language) : result.language; + } + var original = nodeStream(block); + if (original.length) { + var pre = document.createElement('pre'); + pre.innerHTML = result.value; + result.value = mergeStreams(original, nodeStream(pre), text); + } + if (tabReplace) { + result.value = result.value.replace(/^((<[^>]+>|\t)+)/gm, function(match, p1, offset, s) { + return p1.replace(/\t/g, tabReplace); + }) + } + if (useBR) { + result.value = result.value.replace(/\n/g, '
      '); + } + if (/MSIE [678]/.test(navigator.userAgent) && block.tagName == 'CODE' && block.parentNode.tagName == 'PRE') { + // This is for backwards compatibility only. IE needs this strange + // hack becasue it cannot just cleanly replace block contents. + var pre = block.parentNode; + var container = document.createElement('div'); + container.innerHTML = '
      ' + result.value + '
      '; + block = container.firstChild.firstChild; + container.firstChild.className = pre.className; + pre.parentNode.replaceChild(container.firstChild, pre); + } else { + block.innerHTML = result.value; + } + block.className = class_name; + block.dataset = {}; + block.dataset.result = { + language: result.language, + kw: result.keyword_count, + re: result.relevance + }; + if (second_best && second_best.language) { + block.dataset.second_best = { + language: second_best.language, + kw: second_best.keyword_count, + re: second_best.relevance + }; + } + } + + function initHighlighting() { + if (initHighlighting.called) + return; + initHighlighting.called = true; + initialize(); + var pres = document.getElementsByTagName('pre'); + for (var i = 0; i < pres.length; i++) { + var code = findCode(pres[i]); + if (code) + highlightBlock(code, hljs.tabReplace); + } + } + + function initHighlightingOnLoad() { + var original_arguments = arguments; + var handler = function(){initHighlighting.apply(null, original_arguments)}; + if (window.addEventListener) { + window.addEventListener('DOMContentLoaded', handler, false); + window.addEventListener('load', handler, false); + } else if (window.attachEvent) + window.attachEvent('onload', handler); + else + window.onload = handler; + } + + var languages = {}; // a shortcut to avoid writing "this." everywhere + + /* Interface definition */ + + this.LANGUAGES = languages; + this.initHighlightingOnLoad = initHighlightingOnLoad; + this.highlightBlock = highlightBlock; + this.initHighlighting = initHighlighting; + + // Common regexps + this.IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*'; + this.UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*'; + this.NUMBER_RE = '\\b\\d+(\\.\\d+)?'; + this.C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)'; + this.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; + + // Common modes + this.BACKSLASH_ESCAPE = { + begin: '\\\\.', relevance: 0 + }; + this.APOS_STRING_MODE = { + className: 'string', + begin: '\'', end: '\'', + illegal: '\\n', + contains: [this.BACKSLASH_ESCAPE], + relevance: 0 + }; + this.QUOTE_STRING_MODE = { + className: 'string', + begin: '"', end: '"', + illegal: '\\n', + contains: [this.BACKSLASH_ESCAPE], + relevance: 0 + }; + this.C_LINE_COMMENT_MODE = { + className: 'comment', + begin: '//', end: '$' + }; + this.C_BLOCK_COMMENT_MODE = { + className: 'comment', + begin: '/\\*', end: '\\*/' + }; + this.HASH_COMMENT_MODE = { + className: 'comment', + begin: '#', end: '$' + }; + this.NUMBER_MODE = { + className: 'number', + begin: this.NUMBER_RE, + relevance: 0 + }; + this.C_NUMBER_MODE = { + className: 'number', + begin: this.C_NUMBER_RE, + relevance: 0 + }; + + // Utility functions + this.inherit = function(parent, obj) { + var result = {} + for (var key in parent) + result[key] = parent[key]; + if (obj) + for (var key in obj) + result[key] = obj[key]; + return result; + } +}(); diff --git a/war/js/highlight.pack.js b/war/js/highlight.pack.js new file mode 100644 index 0000000..7e510e4 --- /dev/null +++ b/war/js/highlight.pack.js @@ -0,0 +1 @@ +var hljs=new function(){function l(o){return o.replace(/&/gm,"&").replace(/"}while(x.length||y.length){var u=t().splice(0,1)[0];v+=l(w.substr(q,u.offset-q));q=u.offset;if(u.event=="start"){v+=r(u.node);s.push(u.node)}else{if(u.event=="stop"){var p=s.length;do{p--;var o=s[p];v+=("")}while(o!=u.node);s.splice(p,1);while(p'+l(K[0])+""}else{M+=l(K[0])}O=N.lR.lastIndex;K=N.lR.exec(L)}M+=l(L.substr(O,L.length-O));return M}function J(r,L){if(L.sL&&d[L.sL]){var K=f(L.sL,r);s+=K.keyword_count;return K.value}else{return E(r,L)}}function H(L,r){var K=L.cN?'':"";if(L.rB){p+=K;L.buffer=""}else{if(L.eB){p+=l(r)+K;L.buffer=""}else{p+=K;L.buffer=r}}B.push(L);A+=L.r}function D(N,K,P){var Q=B[B.length-1];if(P){p+=J(Q.buffer+N,Q);return false}var L=y(K,Q);if(L){p+=J(Q.buffer+N,Q);H(L,K);return L.rB}var r=v(B.length-1,K);if(r){var M=Q.cN?"":"";if(Q.rE){p+=J(Q.buffer+N,Q)+M}else{if(Q.eE){p+=J(Q.buffer+N,Q)+M+l(K)}else{p+=J(Q.buffer+N+K,Q)+M}}while(r>1){M=B[B.length-2].cN?"":"";p+=M;r--;B.length--}var O=B[B.length-1];B.length--;B[B.length-1].buffer="";if(O.starts){H(O.starts,"")}return Q.rE}if(w(K,Q)){throw"Illegal"}}var G=d[I];var B=[G.dM];var A=0;var s=0;var p="";try{var u=0;G.dM.buffer="";do{var x=q(C,u);var t=D(x[0],x[1],x[2]);u+=x[0].length;if(!t){u+=x[1].length}}while(!x[2]);if(B.length>1){throw"Illegal"}return{language:I,r:A,keyword_count:s,value:p}}catch(F){if(F=="Illegal"){return{language:null,r:0,keyword_count:0,value:l(C)}}else{throw F}}}function h(){function o(t,s,u){if(t.compiled){return}if(!u){t.bR=c(s,t.b?t.b:"\\B|\\b");if(!t.e&&!t.eW){t.e="\\B|\\b"}if(t.e){t.eR=c(s,t.e)}}if(t.i){t.iR=c(s,t.i)}if(t.r==undefined){t.r=1}if(t.k){t.lR=c(s,t.l||hljs.IR,true)}for(var r in t.k){if(!t.k.hasOwnProperty(r)){continue}if(t.k[r] instanceof Object){t.kG=t.k}else{t.kG={keyword:t.k}}break}if(!t.c){t.c=[]}t.compiled=true;for(var q=0;qx.keyword_count+x.r){x=u}if(u.keyword_count+u.r>w.keyword_count+w.r){x=w;w=u}}}var s=t.className;if(!s.match(w.language)){s=s?(s+" "+w.language):w.language}var o=b(t);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=k(o,b(q),A)}if(y){w.value=w.value.replace(/^((<[^>]+>|\t)+)/gm,function(B,E,D,C){return E.replace(/\t/g,y)})}if(p){w.value=w.value.replace(/\n/g,"
      ")}if(/MSIE [678]/.test(navigator.userAgent)&&t.tagName=="CODE"&&t.parentNode.tagName=="PRE"){var q=t.parentNode;var v=document.createElement("div");v.innerHTML="
      "+w.value+"
      ";t=v.firstChild.firstChild;v.firstChild.cN=q.cN;q.parentNode.replaceChild(v.firstChild,q)}else{t.innerHTML=w.value}t.className=s;t.dataset={};t.dataset.result={language:w.language,kw:w.keyword_count,re:w.r};if(x&&x.language){t.dataset.second_best={language:x.language,kw:x.keyword_count,re:x.r}}}function j(){if(j.called){return}j.called=true;e();var q=document.getElementsByTagName("pre");for(var o=0;o|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.inherit=function(o,r){var q={};for(var p in o){q[p]=o[p]}if(r){for(var p in r){q[p]=r[p]}}return q}}();hljs.LANGUAGES.bash=function(){var d={"true":1,"false":1};var b={cN:"variable",b:"\\$([a-zA-Z0-9_]+)\\b"};var a={cN:"variable",b:"\\$\\{(([^}])|(\\\\}))+\\}",c:[hljs.CNM]};var c={cN:"string",b:'"',e:'"',i:"\\n",c:[hljs.BE,b,a],r:0};var e={cN:"test_condition",b:"",e:"",c:[c,b,a,hljs.CNM],k:{literal:d},r:0};return{dM:{k:{keyword:{"if":1,then:1,"else":1,fi:1,"for":1,"break":1,"continue":1,"while":1,"in":1,"do":1,done:1,echo:1,exit:1,"return":1,set:1,declare:1},literal:d},c:[{cN:"shebang",b:"(#!\\/bin\\/bash)|(#!\\/bin\\/sh)",r:10},hljs.HCM,{cN:"comment",b:"\\/\\/",e:"$",i:"."},hljs.CNM,c,b,a,hljs.inherit(e,{b:"\\[ ",e:" \\]",r:0}),hljs.inherit(e,{b:"\\[\\[ ",e:" \\]\\]"})]}}}();hljs.LANGUAGES.erlang=function(){var g="[a-z'][a-zA-Z0-9_']*";var l="("+g+":"+g+"|"+g+")";var d={keyword:{after:1,and:1,andalso:10,band:1,begin:1,bnot:1,bor:1,bsl:1,bzr:1,bxor:1,"case":1,"catch":1,cond:1,div:1,end:1,fun:1,let:1,not:1,of:1,orelse:10,query:1,receive:1,rem:1,"try":1,when:1,xor:1},literal:{"false":1,"true":1}};var j={cN:"comment",b:"%",e:"$",r:0};var c={b:"fun\\s+"+g+"/\\d+"};var m={b:l+"\\(",e:"\\)",rB:true,r:0,c:[{cN:"function_name",b:l,r:0},{b:"\\(",e:"\\)",eW:true,rE:true,r:0}]};var f={cN:"tuple",b:"{",e:"}",r:0};var a={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0};var k={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0};var h={b:"#",e:"}",i:".",r:0,rB:true,c:[{cN:"record_name",b:"#"+hljs.UIR,r:0},{b:"{",eW:true,r:0}]};var i={k:d,b:"(fun|receive|if|try|case)",e:"end"};i.c=[j,c,hljs.inherit(hljs.ASM,{cN:""}),i,m,hljs.QSM,hljs.CNM,f,a,k,h];var b=[j,c,i,m,hljs.QSM,hljs.CNM,f,a,k,h];m.c[1].c=b;f.c=b;h.c[1].c=b;var e={cN:"params",b:"\\(",e:"\\)",eW:true,c:b};return{dM:{k:d,i:"(",eW:true,c:b}]},j,{cN:"pp",b:"^-",e:"\\.",r:0,eE:true,rB:true,l:"-"+hljs.IR,k:{"-module":1,"-record":1,"-undef":1,"-export":1,"-ifdef":1,"-ifndef":1,"-author":1,"-copyright":1,"-doc":1,"-vsn":1,"-import":1,"-include":1,"-include_lib":1,"-compile":1,"-define":1,"-else":1,"-endif":1,"-file":1,"-behaviour":1,"-behavior":1},c:[e]},hljs.CNM,hljs.QSM,h,a,k,f]}}}();hljs.LANGUAGES.cs={dM:{k:{"abstract":1,as:1,base:1,bool:1,"break":1,"byte":1,"case":1,"catch":1,"char":1,checked:1,"class":1,"const":1,"continue":1,decimal:1,"default":1,delegate:1,"do":1,"do":1,"double":1,"else":1,"enum":1,event:1,explicit:1,extern:1,"false":1,"finally":1,fixed:1,"float":1,"for":1,foreach:1,"goto":1,"if":1,implicit:1,"in":1,"int":1,"interface":1,internal:1,is:1,lock:1,"long":1,namespace:1,"new":1,"null":1,object:1,operator:1,out:1,override:1,params:1,"private":1,"protected":1,"public":1,readonly:1,ref:1,"return":1,sbyte:1,sealed:1,"short":1,sizeof:1,stackalloc:1,"static":1,string:1,struct:1,"switch":1,"this":1,"throw":1,"true":1,"try":1,"typeof":1,uint:1,ulong:1,unchecked:1,unsafe:1,ushort:1,using:1,virtual:1,"volatile":1,"void":1,"while":1,ascending:1,descending:1,from:1,get:1,group:1,into:1,join:1,let:1,orderby:1,partial:1,select:1,set:1,value:1,"var":1,where:1,yield:1},c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|"},{cN:"xmlDocTag",b:""}]},hljs.CLCM,hljs.CBLCLM,{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},hljs.ASM,hljs.QSM,hljs.CNM]}};hljs.LANGUAGES.ruby=function(){var g="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var a="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var n={keyword:{and:1,"false":1,then:1,defined:1,module:1,"in":1,"return":1,redo:1,"if":1,BEGIN:1,retry:1,end:1,"for":1,"true":1,self:1,when:1,next:1,until:1,"do":1,begin:1,unless:1,END:1,rescue:1,nil:1,"else":1,"break":1,undef:1,not:1,"super":1,"class":1,"case":1,require:1,yield:1,alias:1,"while":1,ensure:1,elsif:1,or:1,def:1},keymethods:{__id__:1,__send__:1,abort:1,abs:1,"all?":1,allocate:1,ancestors:1,"any?":1,arity:1,assoc:1,at:1,at_exit:1,autoload:1,"autoload?":1,"between?":1,binding:1,binmode:1,"block_given?":1,call:1,callcc:1,caller:1,capitalize:1,"capitalize!":1,casecmp:1,"catch":1,ceil:1,center:1,chomp:1,"chomp!":1,chop:1,"chop!":1,chr:1,"class":1,class_eval:1,"class_variable_defined?":1,class_variables:1,clear:1,clone:1,close:1,close_read:1,close_write:1,"closed?":1,coerce:1,collect:1,"collect!":1,compact:1,"compact!":1,concat:1,"const_defined?":1,const_get:1,const_missing:1,const_set:1,constants:1,count:1,crypt:1,"default":1,default_proc:1,"delete":1,"delete!":1,delete_at:1,delete_if:1,detect:1,display:1,div:1,divmod:1,downcase:1,"downcase!":1,downto:1,dump:1,dup:1,each:1,each_byte:1,each_index:1,each_key:1,each_line:1,each_pair:1,each_value:1,each_with_index:1,"empty?":1,entries:1,eof:1,"eof?":1,"eql?":1,"equal?":1,"eval":1,exec:1,exit:1,"exit!":1,extend:1,fail:1,fcntl:1,fetch:1,fileno:1,fill:1,find:1,find_all:1,first:1,flatten:1,"flatten!":1,floor:1,flush:1,for_fd:1,foreach:1,fork:1,format:1,freeze:1,"frozen?":1,fsync:1,getc:1,gets:1,global_variables:1,grep:1,gsub:1,"gsub!":1,"has_key?":1,"has_value?":1,hash:1,hex:1,id:1,include:1,"include?":1,included_modules:1,index:1,indexes:1,indices:1,induced_from:1,inject:1,insert:1,inspect:1,instance_eval:1,instance_method:1,instance_methods:1,"instance_of?":1,"instance_variable_defined?":1,instance_variable_get:1,instance_variable_set:1,instance_variables:1,"integer?":1,intern:1,invert:1,ioctl:1,"is_a?":1,isatty:1,"iterator?":1,join:1,"key?":1,keys:1,"kind_of?":1,lambda:1,last:1,length:1,lineno:1,ljust:1,load:1,local_variables:1,loop:1,lstrip:1,"lstrip!":1,map:1,"map!":1,match:1,max:1,"member?":1,merge:1,"merge!":1,method:1,"method_defined?":1,method_missing:1,methods:1,min:1,module_eval:1,modulo:1,name:1,nesting:1,"new":1,next:1,"next!":1,"nil?":1,nitems:1,"nonzero?":1,object_id:1,oct:1,open:1,pack:1,partition:1,pid:1,pipe:1,pop:1,popen:1,pos:1,prec:1,prec_f:1,prec_i:1,print:1,printf:1,private_class_method:1,private_instance_methods:1,"private_method_defined?":1,private_methods:1,proc:1,protected_instance_methods:1,"protected_method_defined?":1,protected_methods:1,public_class_method:1,public_instance_methods:1,"public_method_defined?":1,public_methods:1,push:1,putc:1,puts:1,quo:1,raise:1,rand:1,rassoc:1,read:1,read_nonblock:1,readchar:1,readline:1,readlines:1,readpartial:1,rehash:1,reject:1,"reject!":1,remainder:1,reopen:1,replace:1,require:1,"respond_to?":1,reverse:1,"reverse!":1,reverse_each:1,rewind:1,rindex:1,rjust:1,round:1,rstrip:1,"rstrip!":1,scan:1,seek:1,select:1,send:1,set_trace_func:1,shift:1,singleton_method_added:1,singleton_methods:1,size:1,sleep:1,slice:1,"slice!":1,sort:1,"sort!":1,sort_by:1,split:1,sprintf:1,squeeze:1,"squeeze!":1,srand:1,stat:1,step:1,store:1,strip:1,"strip!":1,sub:1,"sub!":1,succ:1,"succ!":1,sum:1,superclass:1,swapcase:1,"swapcase!":1,sync:1,syscall:1,sysopen:1,sysread:1,sysseek:1,system:1,syswrite:1,taint:1,"tainted?":1,tell:1,test:1,"throw":1,times:1,to_a:1,to_ary:1,to_f:1,to_hash:1,to_i:1,to_int:1,to_io:1,to_proc:1,to_s:1,to_str:1,to_sym:1,tr:1,"tr!":1,tr_s:1,"tr_s!":1,trace_var:1,transpose:1,trap:1,truncate:1,"tty?":1,type:1,ungetc:1,uniq:1,"uniq!":1,unpack:1,unshift:1,untaint:1,untrace_var:1,upcase:1,"upcase!":1,update:1,upto:1,"value?":1,values:1,values_at:1,warn:1,write:1,write_nonblock:1,"zero?":1,zip:1}};var h={cN:"yardoctag",b:"@[A-Za-z]+"};var d={cN:"comment",b:"#",e:"$",c:[h]};var c={cN:"comment",b:"^\\=begin",e:"^\\=end",c:[h],r:10};var b={cN:"comment",b:"^__END__",e:"\\n$"};var u={cN:"subst",b:"#\\{",e:"}",l:g,k:n};var p=[hljs.BE,u];var s={cN:"string",b:"'",e:"'",c:p,r:0};var r={cN:"string",b:'"',e:'"',c:p,r:0};var q={cN:"string",b:"%[qw]?\\(",e:"\\)",c:p,r:10};var o={cN:"string",b:"%[qw]?\\[",e:"\\]",c:p,r:10};var m={cN:"string",b:"%[qw]?{",e:"}",c:p,r:10};var l={cN:"string",b:"%[qw]?<",e:">",c:p,r:10};var k={cN:"string",b:"%[qw]?/",e:"/",c:p,r:10};var j={cN:"string",b:"%[qw]?%",e:"%",c:p,r:10};var i={cN:"string",b:"%[qw]?-",e:"-",c:p,r:10};var t={cN:"string",b:"%[qw]?\\|",e:"\\|",c:p,r:10};var e={cN:"function",b:"\\bdef\\s+",e:" |$|;",l:g,k:n,c:[{cN:"title",b:a,l:g,k:n},{cN:"params",b:"\\(",e:"\\)",l:g,k:n},d,c,b]};var f={cN:"identifier",b:g,l:g,k:n,r:0};var v=[d,c,b,s,r,q,o,m,l,k,j,i,t,{cN:"class",b:"\\b(class|module)\\b",e:"$|;",k:{"class":1,module:1},c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+hljs.IR+"::)?"+hljs.IR}]},d,c,b]},e,{cN:"constant",b:"(::)?([A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:[s,r,q,o,m,l,k,j,i,t,f],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},f,{b:"("+hljs.RSR+")\\s*",c:[d,c,b,{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[hljs.BE]}],r:0}];u.c=v;e.c[1].c=v;return{dM:{l:g,k:n,c:v}}}();hljs.LANGUAGES.diff={cI:true,dM:{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}};hljs.LANGUAGES.javascript={dM:{k:{keyword:{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},literal:{"true":1,"false":1,"null":1}},c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM,hljs.CNM,{b:"("+hljs.RSR+"|case|return|throw)\\s*",k:{"return":1,"throw":1,"case":1},c:[hljs.CLCM,hljs.CBLCLM,{cN:"regexp",b:"/.*?[^\\\\/]/[gim]*"}],r:0},{cN:"function",b:"\\bfunction\\b",e:"{",k:{"function":1},c:[{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*"},{cN:"params",b:"\\(",e:"\\)",c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM]}]}]}};hljs.LANGUAGES.lua=function(){var b="\\[=*\\[";var e="\\]=*\\]";var a={b:b,e:e};a.c=[a];var d={cN:"comment",b:"--(?!"+b+")",e:"$"};var c={cN:"comment",b:"--"+b,e:e,c:[a],r:10};return{dM:{l:hljs.UIR,k:{keyword:{and:1,"break":1,"do":1,"else":1,elseif:1,end:1,"false":1,"for":1,"if":1,"in":1,local:1,nil:1,not:1,or:1,repeat:1,"return":1,then:1,"true":1,until:1,"while":1},built_in:{_G:1,_VERSION:1,assert:1,collectgarbage:1,dofile:1,error:1,getfenv:1,getmetatable:1,ipairs:1,load:1,loadfile:1,loadstring:1,module:1,next:1,pairs:1,pcall:1,print:1,rawequal:1,rawget:1,rawset:1,require:1,select:1,setfenv:1,setmetatable:1,tonumber:1,tostring:1,type:1,unpack:1,xpcall:1,coroutine:1,debug:1,io:1,math:1,os:1,"package":1,string:1,table:1}},c:[d,c,{cN:"function",b:"\\bfunction\\b",e:"\\)",k:{"function":1},c:[{cN:"title",b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"},{cN:"params",b:"\\(",eW:true,c:[d,c]},d,c]},hljs.CNM,hljs.ASM,hljs.QSM,{cN:"string",b:b,e:e,c:[a],r:10}]}}}();hljs.LANGUAGES.css=function(){var a={cN:"function",b:hljs.IR+"\\(",e:"\\)",c:[{eW:true,eE:true,c:[hljs.NM,hljs.ASM,hljs.QSM]}]};return{cI:true,dM:{i:"[=/|']",c:[hljs.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@font-face",l:"[a-z-]+",k:{"font-face":1}},{cN:"at_rule",b:"@",e:"[{;]",eE:true,k:{"import":1,page:1,media:1,charset:1},c:[a,hljs.ASM,hljs.QSM,hljs.NM]},{cN:"tag",b:hljs.IR,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[hljs.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[a,hljs.NM,hljs.QSM,hljs.ASM,hljs.CBLCLM,{cN:"hexcolor",b:"\\#[0-9A-F]+"},{cN:"important",b:"!important"}]}}]}]}]}}}();hljs.LANGUAGES.xml=function(){var b="[A-Za-z0-9\\._:-]+";var a={eW:true,c:[{cN:"attribute",b:b,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,dM:{c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"",r:10},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"",k:{title:{style:1}},c:[a],starts:{cN:"css",e:"",rE:true,sL:"css"}},{cN:"tag",b:"",k:{title:{script:1}},c:[a],starts:{cN:"javascript",e:"<\/script>",rE:true,sL:"javascript"}},{cN:"vbscript",b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"",c:[{cN:"title",b:"[^ />]+"},a]}]}}}();hljs.LANGUAGES.lisp=function(){var m="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#]*";var n="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s)(\\+|\\-)?\\d+)?";var c={cN:"literal",b:"\\b(t{1}|nil)\\b"};var o={cN:"number",b:n};var p={cN:"number",b:"#b[0-1]+(/[0-1]+)?"};var q={cN:"number",b:"#o[0-7]+(/[0-7]+)?"};var a={cN:"number",b:"#x[0-9a-f]+(/[0-9a-f]+)?"};var b={cN:"number",b:"#c\\("+n+" +"+n,e:"\\)"};var e={cN:"string",b:'"',e:'"',c:[hljs.BE],r:0};var l={cN:"comment",b:";",e:"$"};var d={cN:"variable",b:"\\*",e:"\\*"};var k={cN:"keyword",b:"[:&]"+m};var i={b:"\\(",e:"\\)"};i.c=[i,c,o,p,q,a,b,e];var g={cN:"quoted",b:"['`]\\(",e:"\\)",c:[o,p,q,a,b,e,d,k,i]};var f={cN:"quoted",b:"\\(quote ",e:"\\)",k:{title:{quote:1}},c:[o,p,q,a,b,e,d,k,i]};var j={cN:"list",b:"\\(",e:"\\)"};var h={cN:"body",eW:true,eE:true};j.c=[{cN:"title",b:m},h];h.c=[g,f,j,c,o,p,q,a,b,e,l,d,k];return{cI:true,dM:{i:"[^\\s]",c:[c,o,p,q,a,b,e,l,g,f,j]}}}();hljs.LANGUAGES.java={dM:{k:{"false":1,"synchronized":1,"int":1,"abstract":1,"float":1,"private":1,"char":1,"interface":1,"boolean":1,"static":1,"null":1,"if":1,"const":1,"for":1,"true":1,"while":1,"long":1,"throw":1,strictfp:1,"finally":1,"protected":1,"extends":1,"import":1,"native":1,"final":1,"implements":1,"return":1,"void":1,"enum":1,"else":1,"break":1,"transient":1,"new":1,"catch":1,"instanceof":1,"byte":1,"super":1,"class":1,"volatile":1,"case":1,assert:1,"short":1,"package":1,"default":1,"double":1,"public":1,"try":1,"this":1,"switch":1,"continue":1,"throws":1},c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},hljs.CLCM,hljs.CBLCLM,hljs.ASM,hljs.QSM,{cN:"class",b:"(class |interface )",e:"{",k:{"class":1,"interface":1},i:":",c:[{b:"(implements|extends)",k:{"extends":1,"implements":1},r:10},{cN:"title",b:hljs.UIR}]},hljs.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}};hljs.LANGUAGES.php={cI:true,dM:{k:{and:1,include_once:1,list:1,"abstract":1,global:1,"private":1,echo:1,"interface":1,as:1,"static":1,endswitch:1,array:1,"null":1,"if":1,endwhile:1,or:1,"const":1,"for":1,endforeach:1,self:1,"var":1,"while":1,isset:1,"public":1,"protected":1,exit:1,foreach:1,"throw":1,elseif:1,"extends":1,include:1,__FILE__:1,empty:1,require_once:1,"function":1,"do":1,xor:1,"return":1,"implements":1,parent:1,clone:1,use:1,__CLASS__:1,__LINE__:1,"else":1,"break":1,print:1,"eval":1,"new":1,"catch":1,__METHOD__:1,"class":1,"case":1,exception:1,php_user_filter:1,"default":1,die:1,require:1,__FUNCTION__:1,enddeclare:1,"final":1,"try":1,"this":1,"switch":1,"continue":1,endfor:1,endif:1,declare:1,unset:1,"true":1,"false":1,namespace:1},c:[hljs.CLCM,hljs.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+",r:10}]},hljs.CNM,hljs.inherit(hljs.ASM,{i:null}),hljs.inherit(hljs.QSM,{i:null}),{cN:"variable",b:"\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"}]}};hljs.LANGUAGES.python=function(){var c={cN:"string",b:"u?r?'''",e:"'''",r:10};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};var a={cN:"string",b:"(u|r|ur)'",e:"'",c:[hljs.BE],r:10};var f={cN:"string",b:'(u|r|ur)"',e:'"',c:[hljs.BE],r:10};var d={cN:"title",b:hljs.UIR};var e={cN:"params",b:"\\(",e:"\\)",c:[c,b,a,f,hljs.ASM,hljs.QSM]};return{dM:{k:{keyword:{and:1,elif:1,is:1,global:1,as:1,"in":1,"if":1,from:1,raise:1,"for":1,except:1,"finally":1,print:1,"import":1,pass:1,"return":1,exec:1,"else":1,"break":1,not:1,"with":1,"class":1,assert:1,yield:1,"try":1,"while":1,"continue":1,del:1,or:1,def:1,lambda:1,nonlocal:10},built_in:{None:1,True:1,False:1,Ellipsis:1,NotImplemented:1}},i:"(|\\?)",c:[hljs.HCM,c,b,a,f,hljs.ASM,hljs.QSM,{cN:"function",b:"\\bdef ",e:":",i:"$",k:{def:1},c:[d,e],r:10},{cN:"class",b:"\\bclass ",e:":",i:"[${]",k:{"class":1},c:[d,e],r:10},hljs.CNM,{cN:"decorator",b:"@",e:"$"}]}}}();hljs.LANGUAGES.smalltalk=function(){var b="[a-z][a-zA-Z0-9_]*";var c={cN:"char",b:"\\$.{1}"};var a={cN:"symbol",b:"#"+hljs.UIR};return{dM:{k:{self:1,"super":1,nil:1,"true":1,"false":1,thisContext:1},c:[{cN:"comment",b:'"',e:'"',r:0},hljs.ASM,{cN:"class",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{cN:"method",b:b+":"},hljs.CNM,a,c,{cN:"localvars",b:"\\|\\s*(("+b+")\\s*)+\\|"},{cN:"array",b:"\\#\\(",e:"\\)",c:[hljs.ASM,c,hljs.CNM,a]}]}}}();hljs.LANGUAGES.sql={cI:true,dM:{i:"[^\\s]",c:[{cN:"operator",b:"(begin|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma)\\b",e:";|$",k:{keyword:{all:1,partial:1,global:1,month:1,current_timestamp:1,using:1,go:1,revoke:1,smallint:1,indicator:1,"end-exec":1,disconnect:1,zone:1,"with":1,character:1,assertion:1,to:1,add:1,current_user:1,usage:1,input:1,local:1,alter:1,match:1,collate:1,real:1,then:1,rollback:1,get:1,read:1,timestamp:1,session_user:1,not:1,integer:1,bit:1,unique:1,day:1,minute:1,desc:1,insert:1,execute:1,like:1,ilike:2,level:1,decimal:1,drop:1,"continue":1,isolation:1,found:1,where:1,constraints:1,domain:1,right:1,national:1,some:1,module:1,transaction:1,relative:1,second:1,connect:1,escape:1,close:1,system_user:1,"for":1,deferred:1,section:1,cast:1,current:1,sqlstate:1,allocate:1,intersect:1,deallocate:1,numeric:1,"public":1,preserve:1,full:1,"goto":1,initially:1,asc:1,no:1,key:1,output:1,collation:1,group:1,by:1,union:1,session:1,both:1,last:1,language:1,constraint:1,column:1,of:1,space:1,foreign:1,deferrable:1,prior:1,connection:1,unknown:1,action:1,commit:1,view:1,or:1,first:1,into:1,"float":1,year:1,primary:1,cascaded:1,except:1,restrict:1,set:1,references:1,names:1,table:1,outer:1,open:1,select:1,size:1,are:1,rows:1,from:1,prepare:1,distinct:1,leading:1,create:1,only:1,next:1,inner:1,authorization:1,schema:1,corresponding:1,option:1,declare:1,precision:1,immediate:1,"else":1,timezone_minute:1,external:1,varying:1,translation:1,"true":1,"case":1,exception:1,join:1,hour:1,"default":1,"double":1,scroll:1,value:1,cursor:1,descriptor:1,values:1,dec:1,fetch:1,procedure:1,"delete":1,and:1,"false":1,"int":1,is:1,describe:1,"char":1,as:1,at:1,"in":1,varchar:1,"null":1,trailing:1,any:1,absolute:1,current_time:1,end:1,grant:1,privileges:1,when:1,cross:1,check:1,write:1,current_date:1,pad:1,begin:1,temporary:1,exec:1,time:1,update:1,catalog:1,user:1,sql:1,date:1,on:1,identity:1,timezone_hour:1,natural:1,whenever:1,interval:1,work:1,order:1,cascade:1,diagnostics:1,nchar:1,having:1,left:1,call:1,"do":1,handler:1,load:1,replace:1,truncate:1,start:1,lock:1,show:1,pragma:1},aggregate:{count:1,sum:1,min:1,max:1,avg:1}},c:[{cN:"string",b:"'",e:"'",c:[hljs.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[hljs.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[hljs.BE]},hljs.CNM,{b:"\\n"}]},hljs.CBLCLM,{cN:"comment",b:"--",e:"$"}]}};hljs.LANGUAGES.ini={cI:true,dM:{i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9_\\[\\]]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:{on:1,off:1,"true":1,"false":1,yes:1,no:1},c:[hljs.QSM,hljs.NM]}]}]}};hljs.LANGUAGES.perl=function(){var c={getpwent:1,getservent:1,quotemeta:1,msgrcv:1,scalar:1,kill:1,dbmclose:1,undef:1,lc:1,ma:1,syswrite:1,tr:1,send:1,umask:1,sysopen:1,shmwrite:1,vec:1,qx:1,utime:1,local:1,oct:1,semctl:1,localtime:1,readpipe:1,"do":1,"return":1,format:1,read:1,sprintf:1,dbmopen:1,pop:1,getpgrp:1,not:1,getpwnam:1,rewinddir:1,qq:1,fileno:1,qw:1,endprotoent:1,wait:1,sethostent:1,bless:1,s:1,opendir:1,"continue":1,each:1,sleep:1,endgrent:1,shutdown:1,dump:1,chomp:1,connect:1,getsockname:1,die:1,socketpair:1,close:1,flock:1,exists:1,index:1,shmget:1,sub:1,"for":1,endpwent:1,redo:1,lstat:1,msgctl:1,setpgrp:1,abs:1,exit:1,select:1,print:1,ref:1,gethostbyaddr:1,unshift:1,fcntl:1,syscall:1,"goto":1,getnetbyaddr:1,join:1,gmtime:1,symlink:1,semget:1,splice:1,x:1,getpeername:1,recv:1,log:1,setsockopt:1,cos:1,last:1,reverse:1,gethostbyname:1,getgrnam:1,study:1,formline:1,endhostent:1,times:1,chop:1,length:1,gethostent:1,getnetent:1,pack:1,getprotoent:1,getservbyname:1,rand:1,mkdir:1,pos:1,chmod:1,y:1,substr:1,endnetent:1,printf:1,next:1,open:1,msgsnd:1,readdir:1,use:1,unlink:1,getsockopt:1,getpriority:1,rindex:1,wantarray:1,hex:1,system:1,getservbyport:1,endservent:1,"int":1,chr:1,untie:1,rmdir:1,prototype:1,tell:1,listen:1,fork:1,shmread:1,ucfirst:1,setprotoent:1,"else":1,sysseek:1,link:1,getgrgid:1,shmctl:1,waitpid:1,unpack:1,getnetbyname:1,reset:1,chdir:1,grep:1,split:1,require:1,caller:1,lcfirst:1,until:1,warn:1,"while":1,values:1,shift:1,telldir:1,getpwuid:1,my:1,getprotobynumber:1,"delete":1,and:1,sort:1,uc:1,defined:1,srand:1,accept:1,"package":1,seekdir:1,getprotobyname:1,semop:1,our:1,rename:1,seek:1,"if":1,q:1,chroot:1,sysread:1,setpwent:1,no:1,crypt:1,getc:1,chown:1,sqrt:1,write:1,setnetent:1,setpriority:1,foreach:1,tie:1,sin:1,msgget:1,map:1,stat:1,getlogin:1,unless:1,elsif:1,truncate:1,exec:1,keys:1,glob:1,tied:1,closedir:1,ioctl:1,socket:1,readlink:1,"eval":1,xor:1,readline:1,binmode:1,setservent:1,eof:1,ord:1,bind:1,alarm:1,pipe:1,atan2:1,getgrent:1,exp:1,time:1,push:1,setgrent:1,gt:1,lt:1,or:1,ne:1,m:1};var d={cN:"subst",b:"[$@]\\{",e:"}",k:c,r:10};var b={cN:"variable",b:"\\$\\d"};var a={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[hljs.BE,d,b,a];var e=[hljs.HCM,{cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5},{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[hljs.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[hljs.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[hljs.BE],r:0},{cN:"sub",b:"\\bsub\\b",e:"(\\s*\\(.*?\\))?[;{]",k:{sub:1},r:5},b,a,{cN:"operator",b:"-\\w\\b",r:0},{cN:"pod",b:"\\=\\w",e:"\\=cut"}];d.c=e;return{dM:{k:c,c:e}}}();hljs.LANGUAGES.scala=function(){var a={cN:"annotation",b:"@[A-Za-z]+"};var b={cN:"string",b:'u?r?"""',e:'"""',r:10};return{dM:{k:{type:1,yield:1,lazy:1,override:1,def:1,"with":1,val:1,"var":1,"false":1,"true":1,sealed:1,"abstract":1,"private":1,trait:1,object:1,"null":1,"if":1,"for":1,"while":1,"throw":1,"finally":1,"protected":1,"extends":1,"import":1,"final":1,"return":1,"else":1,"break":1,"new":1,"catch":1,"super":1,"class":1,"case":1,"package":1,"default":1,"try":1,"this":1,match:1,"continue":1,"throws":1},c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},hljs.CLCM,hljs.CBLCLM,hljs.ASM,hljs.QSM,b,{cN:"class",b:"((case )?class |object |trait )",e:"({|$)",i:":",k:{"case":1,"class":1,trait:1,object:1},c:[{b:"(extends|with)",k:{"extends":1,"with":1},r:10},{cN:"title",b:hljs.UIR},{cN:"params",b:"\\(",e:"\\)",c:[hljs.ASM,hljs.QSM,b,a]}]},hljs.CNM,a]}}}();hljs.LANGUAGES.objectivec=function(){var a={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,sizeof:2,typedef:2,"const":1,struct:1,"for":1,union:1,unsigned:1,"long":1,"volatile":2,"static":1,"protected":1,bool:1,mutable:1,"if":1,"public":1,"do":1,"return":1,"goto":1,"void":2,"enum":1,"else":1,"break":1,extern:1,"true":1,"class":1,asm:1,"case":1,"short":1,"default":1,"double":1,"throw":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,readonly:1,assign:1,property:1,protocol:10,self:1,"synchronized":1,end:1,synthesize:50,id:1,optional:1,required:1,implementation:10,nonatomic:1,"interface":1,"super":1,unichar:1,"finally":2,dynamic:2,nil:1},built_in:{YES:5,NO:5,NULL:1,IBOutlet:50,IBAction:50,NSString:50,NSDictionary:50,CGRect:50,CGPoint:50,NSRange:50,release:1,retain:1,autorelease:50,UIButton:50,UILabel:50,UITextView:50,UIWebView:50,MKMapView:50,UISegmentedControl:50,NSObject:50,UITableViewDelegate:50,UITableViewDataSource:50,NSThread:50,UIActivityIndicator:50,UITabbar:50,UIToolBar:50,UIBarButtonItem:50,UIImageView:50,NSAutoreleasePool:50,UITableView:50,BOOL:1,NSInteger:20,CGFloat:20,NSException:50,NSLog:50,NSMutableString:50,NSMutableArray:50,NSMutableDictionary:50,NSURL:50}};return{dM:{k:a,i:""}]},{cN:"preprocessor",b:"#",e:"$"},{cN:"class",b:"interface|class|protocol|implementation",e:"({|$)",k:{"interface":1,"class":1,protocol:5,implementation:5},c:[{cN:"id",b:hljs.UIR}]}]}}}();hljs.LANGUAGES.cpp=function(){var b={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};var a={cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b.built_in,r:10};a.c=[a];return{dM:{k:b,i:"").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
      a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
      ",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
      t
      ",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i. +shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

      ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
      ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div
      ","
      "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j +)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
      ").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
      ";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/war/js/jquery.cleditor.js b/war/js/jquery.cleditor.js new file mode 100755 index 0000000..4bc4de9 --- /dev/null +++ b/war/js/jquery.cleditor.js @@ -0,0 +1,1132 @@ +/** + @preserve CLEditor WYSIWYG HTML Editor v1.3.0 + http://premiumsoftware.net/cleditor + requires jQuery v1.4.2 or later + + Copyright 2010, Chris Landowski, Premium Software, LLC + Dual licensed under the MIT or GPL Version 2 licenses. +*/ + +// ==ClosureCompiler== +// @compilation_level SIMPLE_OPTIMIZATIONS +// @output_file_name jquery.cleditor.min.js +// ==/ClosureCompiler== + +(function($) { + + //============== + // jQuery Plugin + //============== + + $.cleditor = { + + // Define the defaults used for all new cleditor instances + defaultOptions: { + width: 500, // width not including margins, borders or padding + height: 250, // height not including margins, borders or padding + controls: // controls to add to the toolbar + "bold italic underline strikethrough subscript superscript | font size " + + "style | color highlight removeformat | bullets numbering | outdent " + + "indent | alignleft center alignright justify | undo redo | " + + "rule image link unlink | cut copy paste pastetext | print source", + colors: // colors in the color popup + "FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF " + + "CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F " + + "BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C " + + "999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C " + + "666 900 C60 C93 990 090 399 33F 60C 939 " + + "333 600 930 963 660 060 366 009 339 636 " + + "000 300 630 633 330 030 033 006 309 303", + fonts: // font names in the font popup + "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," + + "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana", + sizes: // sizes in the font size popup + "1,2,3,4,5,6,7", + styles: // styles in the style popup + [["Paragraph", "

      "], ["Header 1", "

      "], ["Header 2", "

      "], + ["Header 3", "

      "], ["Header 4","

      "], ["Header 5","

      "], + ["Header 6","
      "]], + useCSS: false, // use CSS to style HTML when possible (not supported in ie) + docType: // Document type contained within the editor + '', + docCSSFile: // CSS file used to style the document contained within the editor + "", + bodyStyle: // style to assign to document body contained within the editor + "margin:4px; font:10pt Arial,Verdana; cursor:text" + }, + + // Define all usable toolbar buttons - the init string property is + // expanded during initialization back into the buttons object and + // seperate object properties are created for each button. + // e.g. buttons.size.title = "Font Size" + buttons: { + // name,title,command,popupName (""=use name) + init: + "bold,,|" + + "italic,,|" + + "underline,,|" + + "strikethrough,,|" + + "subscript,,|" + + "superscript,,|" + + "font,,fontname,|" + + "size,Font Size,fontsize,|" + + "style,,formatblock,|" + + "color,Font Color,forecolor,|" + + "highlight,Text Highlight Color,hilitecolor,color|" + + "removeformat,Remove Formatting,|" + + "bullets,,insertunorderedlist|" + + "numbering,,insertorderedlist|" + + "outdent,,|" + + "indent,,|" + + "alignleft,Align Text Left,justifyleft|" + + "center,,justifycenter|" + + "alignright,Align Text Right,justifyright|" + + "justify,,justifyfull|" + + "undo,,|" + + "redo,,|" + + "rule,Insert Horizontal Rule,inserthorizontalrule|" + + "image,Insert Image,insertimage,url|" + + "link,Insert Hyperlink,createlink,url|" + + "unlink,Remove Hyperlink,|" + + "cut,,|" + + "copy,,|" + + "paste,,|" + + "pastetext,Paste as Text,inserthtml,|" + + "print,,|" + + "source,Show Source" + }, + + // imagesPath - returns the path to the images folder + imagesPath: function() { return imagesPath(); } + + }; + + // cleditor - creates a new editor for each of the matched textareas + $.fn.cleditor = function(options) { + + // Create a new jQuery object to hold the results + var $result = $([]); + + // Loop through all matching textareas and create the editors + this.each(function(idx, elem) { + if (elem.tagName == "TEXTAREA") { + var data = $.data(elem, CLEDITOR); + if (!data) data = new cleditor(elem, options); + $result = $result.add(data); + } + }); + + // return the new jQuery object + return $result; + + }; + + //================== + // Private Variables + //================== + + var + + // Misc constants + BACKGROUND_COLOR = "backgroundColor", + BUTTON = "button", + BUTTON_NAME = "buttonName", + CHANGE = "change", + CLEDITOR = "cleditor", + CLICK = "click", + DISABLED = "disabled", + DIV_TAG = "
      ", + TRANSPARENT = "transparent", + UNSELECTABLE = "unselectable", + + // Class name constants + MAIN_CLASS = "cleditorMain", // main containing div + TOOLBAR_CLASS = "cleditorToolbar", // toolbar div inside main div + GROUP_CLASS = "cleditorGroup", // group divs inside the toolbar div + BUTTON_CLASS = "cleditorButton", // button divs inside group div + DISABLED_CLASS = "cleditorDisabled",// disabled button divs + DIVIDER_CLASS = "cleditorDivider", // divider divs inside group div + POPUP_CLASS = "cleditorPopup", // popup divs inside body + LIST_CLASS = "cleditorList", // list popup divs inside body + COLOR_CLASS = "cleditorColor", // color popup div inside body + PROMPT_CLASS = "cleditorPrompt", // prompt popup divs inside body + MSG_CLASS = "cleditorMsg", // message popup div inside body + + // Test for ie + ie = $.browser.msie, + ie6 = /msie\s6/i.test(navigator.userAgent), + + // Test for iPhone/iTouch/iPad + iOS = /iphone|ipad|ipod/i.test(navigator.userAgent), + + // Popups are created once as needed and shared by all editor instances + popups = {}, + + // Used to prevent the document click event from being bound more than once + documentClickAssigned, + + // Local copy of the buttons object + buttons = $.cleditor.buttons; + + //=============== + // Initialization + //=============== + + // Expand the buttons.init string back into the buttons object + // and create seperate object properties for each button. + // e.g. buttons.size.title = "Font Size" + $.each(buttons.init.split("|"), function(idx, button) { + var items = button.split(","), name = items[0]; + buttons[name] = { + stripIndex: idx, + name: name, + title: items[1] === "" ? name.charAt(0).toUpperCase() + name.substr(1) : items[1], + command: items[2] === "" ? name : items[2], + popupName: items[3] === "" ? name : items[3] + }; + }); + delete buttons.init; + + //============ + // Constructor + //============ + + // cleditor - creates a new editor for the passed in textarea element + cleditor = function(area, options) { + + var editor = this; + + // Get the defaults and override with options + editor.options = options = $.extend({}, $.cleditor.defaultOptions, options); + + // Hide the textarea and associate it with this editor + var $area = editor.$area = $(area) + .hide() + .data(CLEDITOR, editor) + .blur(function() { + // Update the iframe when the textarea loses focus + updateFrame(editor, true); + }); + + // Create the main container and append the textarea + var $main = editor.$main = $(DIV_TAG) + .addClass(MAIN_CLASS) + .width(options.width) + .height(options.height); + + // Create the toolbar + var $toolbar = editor.$toolbar = $(DIV_TAG) + .addClass(TOOLBAR_CLASS) + .appendTo($main); + + // Add the first group to the toolbar + var $group = $(DIV_TAG) + .addClass(GROUP_CLASS) + .appendTo($toolbar); + + // Add the buttons to the toolbar + $.each(options.controls.split(" "), function(idx, buttonName) { + if (buttonName === "") return true; + + // Divider + if (buttonName == "|") { + + // Add a new divider to the group + var $div = $(DIV_TAG) + .addClass(DIVIDER_CLASS) + .appendTo($group); + + // Create a new group + $group = $(DIV_TAG) + .addClass(GROUP_CLASS) + .appendTo($toolbar); + + } + + // Button + else { + + // Get the button definition + var button = buttons[buttonName]; + + // Add a new button to the group + var $buttonDiv = $(DIV_TAG) + .data(BUTTON_NAME, button.name) + .addClass(BUTTON_CLASS) + .attr("title", button.title) + .bind(CLICK, $.proxy(buttonClick, editor)) + .appendTo($group) + .hover(hoverEnter, hoverLeave); + + // Prepare the button image + var map = {}; + if (button.css) map = button.css; + else if (button.image) map.backgroundImage = imageUrl(button.image); + if (button.stripIndex) map.backgroundPosition = button.stripIndex * -24; + $buttonDiv.css(map); + + // Add the unselectable attribute for ie + if (ie) + $buttonDiv.attr(UNSELECTABLE, "on"); + + // Create the popup + if (button.popupName) + createPopup(button.popupName, options, button.popupClass, + button.popupContent, button.popupHover); + + } + + }); + + // Add the main div to the DOM and append the textarea + $main.insertBefore($area) + .append($area); + + // Bind the document click event handler + if (!documentClickAssigned) { + $(document).click(function(e) { + // Dismiss all non-prompt popups + var $target = $(e.target); + if (!$target.add($target.parents()).is("." + PROMPT_CLASS)) + hidePopups(); + }); + documentClickAssigned = true; + } + + // Bind the window resize event when the width or height is auto or % + if (/auto|%/.test("" + options.width + options.height)) + $(window).resize(function() {refresh(editor);}); + + // Create the iframe and resize the controls + refresh(editor); + + }; + + //=============== + // Public Methods + //=============== + + var fn = cleditor.prototype, + + // Expose the following private functions as methods on the cleditor object. + // The closure compiler will rename the private functions. However, the + // exposed method names on the cleditor object will remain fixed. + methods = [ + ["clear", clear], + ["disable", disable], + ["execCommand", execCommand], + ["focus", focus], + ["hidePopups", hidePopups], + ["sourceMode", sourceMode, true], + ["refresh", refresh], + ["select", select], + ["selectedHTML", selectedHTML, true], + ["selectedText", selectedText, true], + ["showMessage", showMessage], + ["updateFrame", updateFrame], + ["updateTextArea", updateTextArea] + ]; + + $.each(methods, function(idx, method) { + fn[method[0]] = function() { + var editor = this, args = [editor]; + // using each here would cast booleans into objects! + for(var x = 0; x < arguments.length; x++) {args.push(arguments[x]);} + var result = method[1].apply(editor, args); + if (method[2]) return result; + return editor; + }; + }); + + // change - shortcut for .bind("change", handler) or .trigger("change") + fn.change = function(handler) { + var $this = $(this); + return handler ? $this.bind(CHANGE, handler) : $this.trigger(CHANGE); + }; + + //=============== + // Event Handlers + //=============== + + // buttonClick - click event handler for toolbar buttons + function buttonClick(e) { + + var editor = this, + buttonDiv = e.target, + buttonName = $.data(buttonDiv, BUTTON_NAME), + button = buttons[buttonName], + popupName = button.popupName, + popup = popups[popupName]; + + // Check if disabled + if (editor.disabled || $(buttonDiv).attr(DISABLED) == DISABLED) + return; + + // Fire the buttonClick event + var data = { + editor: editor, + button: buttonDiv, + buttonName: buttonName, + popup: popup, + popupName: popupName, + command: button.command, + useCSS: editor.options.useCSS + }; + + if (button.buttonClick && button.buttonClick(e, data) === false) + return false; + + // Toggle source + if (buttonName == "source") { + + // Show the iframe + if (sourceMode(editor)) { + delete editor.range; + editor.$area.hide(); + editor.$frame.show(); + buttonDiv.title = button.title; + } + + // Show the textarea + else { + editor.$frame.hide(); + editor.$area.show(); + buttonDiv.title = "Show Rich Text"; + } + + // Enable or disable the toolbar buttons + // IE requires the timeout + setTimeout(function() {refreshButtons(editor);}, 100); + + } + + // Check for rich text mode + else if (!sourceMode(editor)) { + + // Handle popups + if (popupName) { + var $popup = $(popup); + + // URL + if (popupName == "url") { + + // Check for selection before showing the link url popup + if (buttonName == "link" && selectedText(editor) === "") { + showMessage(editor, "A selection is required when inserting a link.", buttonDiv); + return false; + } + + // Wire up the submit button click event handler + $popup.children(":button") + .unbind(CLICK) + .bind(CLICK, function() { + + // Insert the image or link if a url was entered + var $text = $popup.find(":text"), + url = $.trim($text.val()); + if (url !== "") + execCommand(editor, data.command, url, null, data.button); + + // Reset the text, hide the popup and set focus + $text.val("http://"); + hidePopups(); + focus(editor); + + }); + + } + + // Paste as Text + else if (popupName == "pastetext") { + + // Wire up the submit button click event handler + $popup.children(":button") + .unbind(CLICK) + .bind(CLICK, function() { + + // Insert the unformatted text replacing new lines with break tags + var $textarea = $popup.find("textarea"), + text = $textarea.val().replace(/\n/g, "
      "); + if (text !== "") + execCommand(editor, data.command, text, null, data.button); + + // Reset the text, hide the popup and set focus + $textarea.val(""); + hidePopups(); + focus(editor); + + }); + + } + + // Show the popup if not already showing for this button + if (buttonDiv !== $.data(popup, BUTTON)) { + showPopup(editor, popup, buttonDiv); + return false; // stop propagination to document click + } + + // propaginate to documnt click + return; + + } + + // Print + else if (buttonName == "print") + editor.$frame[0].contentWindow.print(); + + // All other buttons + else if (!execCommand(editor, data.command, data.value, data.useCSS, buttonDiv)) + return false; + + } + + // Focus the editor + focus(editor); + + } + + // hoverEnter - mouseenter event handler for buttons and popup items + function hoverEnter(e) { + var $div = $(e.target).closest("div"); + $div.css(BACKGROUND_COLOR, $div.data(BUTTON_NAME) ? "#FFF" : "#FFC"); + } + + // hoverLeave - mouseleave event handler for buttons and popup items + function hoverLeave(e) { + $(e.target).closest("div").css(BACKGROUND_COLOR, "transparent"); + } + + // popupClick - click event handler for popup items + function popupClick(e) { + + var editor = this, + popup = e.data.popup, + target = e.target; + + // Check for message and prompt popups + if (popup === popups.msg || $(popup).hasClass(PROMPT_CLASS)) + return; + + // Get the button info + var buttonDiv = $.data(popup, BUTTON), + buttonName = $.data(buttonDiv, BUTTON_NAME), + button = buttons[buttonName], + command = button.command, + value, + useCSS = editor.options.useCSS; + + // Get the command value + if (buttonName == "font") + // Opera returns the fontfamily wrapped in quotes + value = target.style.fontFamily.replace(/"/g, ""); + else if (buttonName == "size") { + if (target.tagName == "DIV") + target = target.children[0]; + value = target.innerHTML; + } + else if (buttonName == "style") + value = "<" + target.tagName + ">"; + else if (buttonName == "color") + value = hex(target.style.backgroundColor); + else if (buttonName == "highlight") { + value = hex(target.style.backgroundColor); + if (ie) command = 'backcolor'; + else useCSS = true; + } + + // Fire the popupClick event + var data = { + editor: editor, + button: buttonDiv, + buttonName: buttonName, + popup: popup, + popupName: button.popupName, + command: command, + value: value, + useCSS: useCSS + }; + + if (button.popupClick && button.popupClick(e, data) === false) + return; + + // Execute the command + if (data.command && !execCommand(editor, data.command, data.value, data.useCSS, buttonDiv)) + return false; + + // Hide the popup and focus the editor + hidePopups(); + focus(editor); + + } + + //================== + // Private Functions + //================== + + // checksum - returns a checksum using the Adler-32 method + function checksum(text) + { + var a = 1, b = 0; + for (var index = 0; index < text.length; ++index) { + a = (a + text.charCodeAt(index)) % 65521; + b = (b + a) % 65521; + } + return (b << 16) | a; + } + + // clear - clears the contents of the editor + function clear(editor) { + editor.$area.val(""); + updateFrame(editor); + } + + // createPopup - creates a popup and adds it to the body + function createPopup(popupName, options, popupTypeClass, popupContent, popupHover) { + + // Check if popup already exists + if (popups[popupName]) + return popups[popupName]; + + // Create the popup + var $popup = $(DIV_TAG) + .hide() + .addClass(POPUP_CLASS) + .appendTo("body"); + + // Add the content + + // Custom popup + if (popupContent) + $popup.html(popupContent); + + // Color + else if (popupName == "color") { + var colors = options.colors.split(" "); + if (colors.length < 10) + $popup.width("auto"); + $.each(colors, function(idx, color) { + $(DIV_TAG).appendTo($popup) + .css(BACKGROUND_COLOR, "#" + color); + }); + popupTypeClass = COLOR_CLASS; + } + + // Font + else if (popupName == "font") + $.each(options.fonts.split(","), function(idx, font) { + $(DIV_TAG).appendTo($popup) + .css("fontFamily", font) + .html(font); + }); + + // Size + else if (popupName == "size") + $.each(options.sizes.split(","), function(idx, size) { + $(DIV_TAG).appendTo($popup) + .html("" + size + ""); + }); + + // Style + else if (popupName == "style") + $.each(options.styles, function(idx, style) { + $(DIV_TAG).appendTo($popup) + .html(style[1] + style[0] + style[1].replace("<", "
      '); + popupTypeClass = PROMPT_CLASS; + } + + // Paste as Text + else if (popupName == "pastetext") { + $popup.html('Paste your content here and click submit.

      '); + popupTypeClass = PROMPT_CLASS; + } + + // Add the popup type class name + if (!popupTypeClass && !popupContent) + popupTypeClass = LIST_CLASS; + $popup.addClass(popupTypeClass); + + // Add the unselectable attribute to all items + if (ie) { + $popup.attr(UNSELECTABLE, "on") + .find("div,font,p,h1,h2,h3,h4,h5,h6") + .attr(UNSELECTABLE, "on"); + } + + // Add the hover effect to all items + if ($popup.hasClass(LIST_CLASS) || popupHover === true) + $popup.children().hover(hoverEnter, hoverLeave); + + // Add the popup to the array and return it + popups[popupName] = $popup[0]; + return $popup[0]; + + } + + // disable - enables or disables the editor + function disable(editor, disabled) { + + // Update the textarea and save the state + if (disabled) { + editor.$area.attr(DISABLED, DISABLED); + editor.disabled = true; + } + else { + editor.$area.removeAttr(DISABLED); + delete editor.disabled; + } + + // Switch the iframe into design mode. + // ie6 does not support designMode. + // ie7 & ie8 do not properly support designMode="off". + try { + if (ie) editor.doc.body.contentEditable = !disabled; + else editor.doc.designMode = !disabled ? "on" : "off"; + } + // Firefox 1.5 throws an exception that can be ignored + // when toggling designMode from off to on. + catch (err) {} + + // Enable or disable the toolbar buttons + refreshButtons(editor); + + } + + // execCommand - executes a designMode command + function execCommand(editor, command, value, useCSS, button) { + + // Restore the current ie selection + restoreRange(editor); + + // Set the styling method + if (!ie) { + if (useCSS === undefined || useCSS === null) + useCSS = editor.options.useCSS; + editor.doc.execCommand("styleWithCSS", 0, useCSS.toString()); + } + + // Execute the command and check for error + var success = true, description; + if (ie && command.toLowerCase() == "inserthtml") + getRange(editor).pasteHTML(value); + else { + try { success = editor.doc.execCommand(command, 0, value || null); } + catch (err) { description = err.description; success = false; } + if (!success) { + if ("cutcopypaste".indexOf(command) > -1) + showMessage(editor, "For security reasons, your browser does not support the " + + command + " command. Try using the keyboard shortcut or context menu instead.", + button); + else + showMessage(editor, + (description ? description : "Error executing the " + command + " command."), + button); + } + } + + // Enable the buttons + refreshButtons(editor); + return success; + + } + + // focus - sets focus to either the textarea or iframe + function focus(editor) { + setTimeout(function() { + if (sourceMode(editor)) editor.$area.focus(); + else editor.$frame[0].contentWindow.focus(); + refreshButtons(editor); + }, 0); + } + + // getRange - gets the current text range object + function getRange(editor) { + if (ie) return getSelection(editor).createRange(); + return getSelection(editor).getRangeAt(0); + } + + // getSelection - gets the current text range object + function getSelection(editor) { + if (ie) return editor.doc.selection; + return editor.$frame[0].contentWindow.getSelection(); + } + + // Returns the hex value for the passed in string. + // hex("rgb(255, 0, 0)"); // #FF0000 + // hex("#FF0000"); // #FF0000 + // hex("#F00"); // #FF0000 + function hex(s) { + var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s), + c = s.split(""); + if (m) { + s = ( m[1] << 16 | m[2] << 8 | m[3] ).toString(16); + while (s.length < 6) + s = "0" + s; + } + return "#" + (s.length == 6 ? s : c[1] + c[1] + c[2] + c[2] + c[3] + c[3]); + } + + // hidePopups - hides all popups + function hidePopups() { + $.each(popups, function(idx, popup) { + $(popup) + .hide() + .unbind(CLICK) + .removeData(BUTTON); + }); + } + + // imagesPath - returns the path to the images folder + function imagesPath() { + var cssFile = "jquery.cleditor.css", + href = $("link[href$='" + cssFile +"']").attr("href"); + return href.substr(0, href.length - cssFile.length) + "images/"; + } + + // imageUrl - Returns the css url string for a filemane + function imageUrl(filename) { + return "url(" + imagesPath() + filename + ")"; + } + + // refresh - creates the iframe and resizes the controls + function refresh(editor) { + + var $main = editor.$main, + options = editor.options; + + // Remove the old iframe + if (editor.$frame) + editor.$frame.remove(); + + // Create a new iframe + var $frame = editor.$frame = $('