--- a/.classpath Fri Dec 21 16:22:08 2012 +0100
+++ b/.classpath Mon Dec 31 13:37:31 2012 +0100
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="server/src/main/java"/>
+ <classpathentry kind="src" path="server/src/test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="owner.project.facets" value="java"/>
@@ -8,18 +9,34 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
- <classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-bots/0.8.3/coweb-bots-0.8.3.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-server/0.8.3/coweb-server-0.8.3.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-operationengine/0.8.3/coweb-operationengine-0.8.3.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-server/2.4.0/cometd-java-server-2.4.0.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/cometd/java/bayeux-api/2.4.0/bayeux-api-2.4.0.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-common/2.4.0/cometd-java-common-2.4.0.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/7.6.0.v20120127/jetty-util-7.6.0.v20120127.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.4/slf4j-api-1.6.4.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/7.6.0.v20120127/jetty-continuation-7.6.0.v20120127.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-jmx/7.6.0.v20120127/jetty-jmx-7.6.0.v20120127.jar"/>
- <classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-server/1.13/jersey-server-1.13.jar"/>
- <classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-core/1.13/jersey-core-1.13.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/mongodb/mongo-java-driver/2.8.0/mongo-java-driver-2.8.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-bots/1.0/coweb-bots-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-server/1.0/coweb-server-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-operationengine/1.0/coweb-operationengine-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/cometd/java/bayeux-api/2.5.0/bayeux-api-2.5.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-common/2.5.0/cometd-java-common-2.5.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/7.6.7.v20120910/jetty-util-7.6.7.v20120910.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/7.6.7.v20120910/jetty-continuation-7.6.7.v20120910.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-jmx/7.6.7.v20120910/jetty-jmx-7.6.7.v20120910.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-server/1.16/jersey-server-1.16.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-core/1.16/jersey-core-1.16.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/mongodb/mongo-java-driver/2.9.0/mongo-java-driver-2.9.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/3.1.3.RELEASE/spring-context-3.1.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/3.1.3.RELEASE/spring-beans-3.1.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/persistence/persistence-api/1.0.2/persistence-api-1.0.2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-mongodb/1.1.0.RELEASE/spring-data-mongodb-1.1.0.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-commons-core/1.4.0.RELEASE/spring-data-commons-core-1.4.0.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-jpa/1.2.0.RELEASE/spring-data-jpa-1.2.0.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/inject/javax.inject/1/javax.inject-1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-annotations/2.5.0/cometd-java-annotations-2.5.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-server/2.5.0/cometd-java-server-2.5.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/3.1.3.RELEASE/spring-core-3.1.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/3.1.3.RELEASE/spring-web-3.1.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-webmvc/3.1.3.RELEASE/spring-webmvc-3.1.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.10/junit-4.10.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/springframework/spring-test/3.1.3.RELEASE/spring-test-3.1.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/servlet/jstl/1.2/jstl-1.2.jar"/>
<classpathentry kind="output" path="server/target/classes"/>
</classpath>
--- a/.settings/org.eclipse.wst.common.component Fri Dec 21 16:22:08 2012 +0100
+++ b/.settings/org.eclipse.wst.common.component Mon Dec 31 13:37:31 2012 +0100
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project-modules id="moduleCoreId" project-version="1.5.0">
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="renkan">
<wb-resource deploy-path="/" source-path="/server/src/main/webapp"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/server/src/main/java"/>
+ <wb-resource deploy-path="/WEB-INF/classes" source-path="/server/src/test/java"/>
<property name="java-output-path" value="/server/target/classes"/>
<property name="context-root" value="renkan"/>
</wb-module>
--- a/client/js/models.js Fri Dec 21 16:22:08 2012 +0100
+++ b/client/js/models.js Mon Dec 31 13:37:31 2012 +0100
@@ -88,7 +88,7 @@
description: this.get("description"),
position: this.get("position"),
image: this.get("image"),
- created_by: this.get("created_by").get("_id")
+ created_by: this.get("created_by") ? this.get("created_by").get("_id") : null
};
},
});
@@ -126,9 +126,9 @@
title: this.get("title"),
uri: this.get("uri"),
description: this.get("description"),
- from: this.get("from").get("_id"),
- to: this.get("to").get("_id"),
- created_by: this.get("created_by").get("_id"),
+ from: this.get("from") ? this.get("from").get("_id") : null,
+ to: this.get("to") ? this.get("to").get("_id") : null,
+ created_by: this.get("created_by") ? this.get("created_by").get("_id") : null
};
},
});
--- a/server/pom.xml Fri Dec 21 16:22:08 2012 +0100
+++ b/server/pom.xml Mon Dec 31 13:37:31 2012 +0100
@@ -8,7 +8,12 @@
<packaging>war</packaging>
<properties>
- <coweb-version>0.8.3</coweb-version>
+ <coweb-version>1.0</coweb-version>
+ <cowebx-version>0.8.4</cowebx-version>
+ <jersey-version>1.16</jersey-version>
+ <spring-version>3.1.3.RELEASE</spring-version>
+ <junit-version>4.10</junit-version>
+ <thymeleaf-version>2.0.14</thymeleaf-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@@ -28,7 +33,7 @@
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
- <version>7.3.0.v20110203</version>
+ <version>8.1.8.v20121106</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webAppConfig>
@@ -52,6 +57,16 @@
</excludes>
<targetPath>lib</targetPath>
</overlay>
+ <overlay>
+ <groupId>org.opencoweb.cowebx</groupId>
+ <artifactId>cowebx-widgets-dojo</artifactId>
+ <type>war</type>
+ <excludes>
+ <exclude>META-INF/**</exclude>
+ <exclude>WEB-INF/**</exclude>
+ </excludes>
+ <targetPath>lib/cowebx/dojo</targetPath>
+ </overlay>
</overlays>
<webResources>
<resource>
@@ -61,13 +76,42 @@
<exclude>**/data</exclude>
</excludes>
</resource>
+ <resource>
+ <directory>src/main/web-resources</directory>
+ </resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
-
+ <repositories>
+ <repository>
+ <id>spring-maven-release</id>
+ <name>Spring Maven Release Repository</name>
+ <url>http://maven.springframework.org/release</url>
+ </repository>
+ <repository>
+ <id>spring-maven-milestone</id>
+ <name>Spring Maven MILESTONE Repository</name>
+ <url>http://maven.springframework.org/milestone</url>
+ </repository>
+ </repositories>
<dependencies>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.cometd.java</groupId>
+ <artifactId>cometd-java-annotations</artifactId>
+ <version>2.5.0</version>
+ </dependency>
<dependency>
<groupId>org.opencoweb</groupId>
<artifactId>coweb-bots</artifactId>
@@ -85,25 +129,130 @@
<type>war</type>
</dependency>
<dependency>
+ <groupId>org.opencoweb.cowebx</groupId>
+ <artifactId>cowebx-widgets-dojo</artifactId>
+ <version>${cowebx-version}</version>
+ <type>war</type>
+ </dependency>
+ <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
- <version>1.13</version>
+ <version>${jersey-version}</version>
</dependency>
<dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-servlet</artifactId>
- <version>1.13</version>
+ <groupId>com.sun.jersey.contribs</groupId>
+ <artifactId>jersey-spring</artifactId>
+ <version>${jersey-version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
- <version>2.8.0</version>
+ <version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${spring-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>${spring-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <version>${spring-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${spring-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-commons-core</artifactId>
+ <version>1.4.0.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-jpa</artifactId>
+ <version>1.2.0.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-mongodb</artifactId>
+ <version>1.1.0.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.2</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.thymeleaf</groupId>
+ <artifactId>thymeleaf</artifactId>
+ <version>${thymeleaf-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.thymeleaf</groupId>
+ <artifactId>thymeleaf-spring3</artifactId>
+ <version>${thymeleaf-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.nekohtml</groupId>
+ <artifactId>nekohtml</artifactId>
+ <version>1.9.16</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ <version>2.1.2</version>
+ </dependency>
</dependencies>
<organization>
<name>IRI</name>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/RenkanException.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,25 @@
+package org.iri_research.renkan;
+
+public class RenkanException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6952770322990047437L;
+
+ public RenkanException() {
+ }
+
+ public RenkanException(String message) {
+ super(message);
+ }
+
+ public RenkanException(Throwable exc) {
+ super(exc);
+ }
+
+ public RenkanException(String message, Throwable exc) {
+ super(message, exc);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/controller/RenkanController.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,64 @@
+package org.iri_research.renkan.controller;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.HttpMediaTypeNotAcceptableException;
+import org.springframework.web.HttpMediaTypeNotSupportedException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+
+
+@Controller
+@RequestMapping("/")
+public class RenkanController {
+
+ private final Logger logger = LoggerFactory.getLogger(RenkanController.class);
+
+ @Autowired
+ private ProjectsRepository projectRepository;
+
+ @RequestMapping(value="/{project_id}", method = RequestMethod.GET, produces={"text/html", "!image/*"})
+ public ModelAndView renkanProject(@PathVariable(value="project_id") String project_id, @RequestHeader(value="Accept") String accept_header) throws HttpMediaTypeNotSupportedException {
+
+ this.logger.debug("renkanProject : " + project_id + " Accept : " + accept_header!=null?accept_header:"");
+
+ if(accept_header != null && accept_header.matches(".*image/.*")) {
+ throw new HttpMediaTypeNotSupportedException("Do not orduce image");
+ }
+
+ if(project_id == null || project_id.length() == 0) {
+ throw new IllegalArgumentException("RenkanContoller.renkanProject: Project id is null or empty.");
+ }
+
+ Project project = this.projectRepository.findOne(project_id);
+
+ if(project == null) {
+ project = new Project(project_id, "(New project)", "(Project Description)", "");
+ this.projectRepository.save(project);
+ }
+
+ Map<String, Object> model = new HashMap<String, Object>();
+ model.put("project", project);
+
+ return new ModelAndView("renkanProjectEdit", model);
+ }
+
+ /*@RequestMapping("/test")
+ public ModelAndView projectPrompt() {
+ String message = "Hello world, Spring";
+
+ return new ModelAndView("projectPrompt", "message", message);
+ }*/
+
+}
--- a/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java Fri Dec 21 16:22:08 2012 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java Mon Dec 31 13:37:31 2012 +0100
@@ -1,20 +1,71 @@
package org.iri_research.renkan.coweb;
+//import java.util.HashMap;
import java.util.Map;
+import javax.inject.Named;
+
import org.coweb.DefaultSessionModerator;
+import org.iri_research.renkan.coweb.event.ISyncEventManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+//import javax.inject.Inject;
+@Named
public class RenkanSessionModerator extends DefaultSessionModerator {
- private final Logger logger = LoggerFactory.getLogger(RenkanSessionModerator.class);
-
+ private final Logger logger = LoggerFactory.getLogger(RenkanSessionModerator.class);
+
+ @SuppressWarnings("unchecked")
@Override
- public boolean onSync(Map<String, Object> data) {
+ public void onSync(String clientId, Map<String, Object> data) {
+
+ this.logger.debug("Debugging onSync client id: " + clientId);
+ this.logger.debug("Debugging onSync: " + data.toString());
+ this.logger.debug("Debugging onSync channel: " + data.get("channel"));
+ this.logger.debug("Debugging onSync type: " + data.get("type"));
+ this.logger.debug("Debugging onSync site: " + data.get("site"));
+ this.logger.debug("Debugging onSync value: " + data.get("value"));
+ this.logger.debug("Debugging onSync position: " + data.get("position"));
+
+ Map<String, Object> values = null;
+ if(data.containsKey("value") && data.get("value") != null) {
+ values = ((Map<String, Object>) data.get("value"));
+ }
+
+ if(values == null) {
+ this.logger.warn("onSync : no values in message.");
+ return;
+ }
- this.logger.debug("Debugging onSync : " + data.toString());
- return super.onSync(data);
+ String sync_type = (String) values.get("_type");
+ if(sync_type == null || sync_type.length() == 0) {
+ this.logger.warn("onSync : no type in value of message.");
+ return;
+ }
+
+ ApplicationContext context = SpringConfigurer.getInstance().getApplicationContext();
+
+ //String className = String.format("org.iri_research.renkan.coweb.event.%sSyncEventManager", sync_type.substring(0, 1).toUpperCase()+sync_type.substring(1));
+ String beanName = String.format("%sSyncEventManager", sync_type.toLowerCase());
+
+ try {
+ ISyncEventManager<?, ?> eventManager = (ISyncEventManager<?, ?>)context.getBean(beanName);
+ logger.debug("Debugging on Sync : dispatch to " + beanName);
+ eventManager.dispatchEvent(data);
+ }
+ catch(Throwable e) {
+ this.logger.error(String.format("onSync EventManagerClass %s not found : error %s : %s", sync_type, e.toString(), e.getMessage()));
+ }
+ /*catch (ClassNotFoundException e) {
+ this.logger.error(String.format("onSync EventManagerClass %s not found : ClassNotFoundException : %s", sync_type, e.getMessage()));
+ } catch (InstantiationException e) {
+ this.logger.error(String.format("onSync EventManagerClass %s not found : InstantiationException : %s", sync_type, e.getMessage()));
+ } catch (IllegalAccessException e) {
+ this.logger.error(String.format("onSync EventManagerClass %s not found : IllegalAccessException : %s", sync_type, e.getMessage()));
+ }*/
+
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/SpringConfigurer.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,106 @@
+package org.iri_research.renkan.coweb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.servlet.ServletContext;
+
+import org.cometd.annotation.ServerAnnotationProcessor;
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.server.BayeuxServerImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.context.ServletContextAware;
+
+//@Component
+//@Scope("prototype")
+public class SpringConfigurer implements DestructionAwareBeanPostProcessor, ServletContextAware, ApplicationContextAware
+{
+
+ private BayeuxServer bayeuxServer;
+ private ServerAnnotationProcessor processor;
+ private final Logger logger = LoggerFactory.getLogger(SpringConfigurer.class);
+ private ApplicationContext context;
+
+ private static volatile SpringConfigurer instance = null;
+
+ private SpringConfigurer()
+ {
+ this.logger.debug("Buiding SpringCond=figurer");
+ }
+
+ public static SpringConfigurer getInstance() {
+ if (instance == null) {
+ synchronized (SpringConfigurer.class) {
+ if(instance == null) {
+ instance = new SpringConfigurer();
+ }
+ }
+ }
+ return instance;
+ }
+
+ @Inject
+ private void setBayeuxServer(BayeuxServer bayeuxServer)
+ {
+ this.bayeuxServer = bayeuxServer;
+ }
+
+ @PostConstruct
+ private void init()
+ {
+ this.processor = new ServerAnnotationProcessor(bayeuxServer);
+ }
+
+ public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException
+ {
+ processor.processDependencies(bean);
+ processor.processConfigurations(bean);
+ processor.processCallbacks(bean);
+ return bean;
+ }
+
+ public Object postProcessAfterInitialization(Object bean, String name) throws BeansException
+ {
+ return bean;
+ }
+
+ public void postProcessBeforeDestruction(Object bean, String name) throws BeansException
+ {
+ processor.deprocessCallbacks(bean);
+ }
+
+ @Bean(initMethod = "start", destroyMethod = "stop")
+ public BayeuxServer bayeuxServer()
+ {
+ BayeuxServerImpl bean = new BayeuxServerImpl();
+ Map<String, Object> options = new HashMap<String, Object>();
+ options.put(BayeuxServerImpl.LOG_LEVEL, "3");
+ options.put("timeout", "1500");
+ bean.setOptions(options);
+ return bean;
+ }
+
+ public void setServletContext(ServletContext servletContext)
+ {
+ servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
+ }
+
+ @Override
+ @Inject
+ public void setApplicationContext(ApplicationContext context)
+ throws BeansException {
+ this.context = context;
+ }
+
+ public ApplicationContext getApplicationContext() {
+ return this.context;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/AbstractSyncEventManager.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,206 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.coweb.CowebException;
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.models.IRenkanModel;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.ProjectSync;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.ProjectSyncsRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.WriteResult;
+
+
+public abstract class AbstractSyncEventManager<T extends IRenkanModel<ID>, ID extends Serializable> implements ISyncEventManager<T,ID> {
+
+ private final Logger logger = LoggerFactory.getLogger(AbstractSyncEventManager.class);
+
+ @Inject
+ private ProjectsRepository projectsRepository;
+
+ @Inject
+ private ProjectSyncsRepository projectSyncsRepository;
+
+ @Override
+ public ProjectsRepository getProjectsRepository() {
+ return this.projectsRepository;
+ }
+
+ @Override
+ public abstract IRenkanRepository<T, ID> getObjectRepository();
+
+ @Override
+ public void dispatchEvent(Map<String, Object> data) {
+
+ this.saveSyncEvent(data);
+
+ String eventType = (String) data.get("type");
+
+ if("null".equalsIgnoreCase(eventType)) {
+ this.nullOperation(data);
+ }
+ else if ("update".equalsIgnoreCase(eventType)) {
+ this.update(data);
+ }
+ else if ("insert".equalsIgnoreCase(eventType)) {
+ this.insert(data);
+ }
+ else if("delete".equalsIgnoreCase(eventType)) {
+ this.delete(data);
+ }
+ else {
+ logger.warn(String.format("dispatchEvent : eventType unknown %s", eventType));
+ }
+ }
+
+ private void saveSyncEvent(Map<String, Object> data) {
+
+ String project_id = null;
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+
+ if(values != null) {
+ project_id = (String) values.get("_project_id");
+ }
+
+ if (project_id == null || "".equals(project_id)) {
+ logger.warn("saveSyncEvent : project id is null. Can not save sync event");
+ return;
+ }
+
+ Project p = this.projectsRepository.findOne(project_id);
+
+ if (p == null) {
+ logger.warn("saveSyncEvent : project not found. Can not save sync event");
+ return;
+ }
+
+
+ try {
+ ProjectSync ps = this.projectSyncsRepository.getProjectSync(data.toString(), p);
+ this.projectSyncsRepository.save(ps);
+ } catch (RenkanException e) {
+ logger.warn("saveSyncEvent : Error when getting Projectr syn object",e);
+ }
+
+ }
+
+ protected abstract List<T> getObjectList(Project project);
+
+ @Override
+ public void update(Map<String, Object> data) {
+
+ this.logger.debug("AbstractSyncEventManager: update " + this.getClass().getName());
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String obj_id = (String) values.get("id");
+
+ this.logger.debug(String.format("update %s %s", this.getClass().getName(), obj_id));
+
+ DBCollection objCollection = this.getObjectRepository().getCollection();
+ DBObject obj = objCollection.findOne(obj_id);
+
+ if (null == obj) {
+ throw new CowebException("Object update: object not found", String.format("Object %s not found in %s", obj_id, objCollection.getName()));
+ }
+
+ boolean obj_changed = false;
+ // update object
+ for (String fieldname : values.keySet()) {
+ if(!"id".equalsIgnoreCase(fieldname) && !fieldname.startsWith("_"))
+ {
+ Object new_value = values.get(fieldname);
+ Object old_value = obj.get(fieldname);
+ if((new_value == null && old_value != null) || (new_value != null && !new_value.equals(old_value))) {
+ obj.put(fieldname, new_value);
+ obj_changed = true;
+ }
+ }
+ }
+
+ if(obj_changed) {
+ obj.put("_id", obj_id);
+ WriteResult res = this.getObjectRepository().getCollection().update(new BasicDBObject("_id", obj_id), obj, true, false);
+
+ if(!res.getLastError().ok()) {
+ throw new CowebException(String.format("Error when writing object %s in %s", obj_id, objCollection.getName()), res.getLastError().getErrorMessage());
+ }
+ }
+ }
+
+ @Override
+ public abstract void insert(Map<String, Object> data);
+
+ @Override
+ public void delete(Map<String, Object> data) {
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String project_id = (String) values.get("_project_id");
+ Project project = this.getProjectsRepository().findOne(project_id);
+
+ if (null == project) {
+ throw new CowebException(this.getClass().getName() + " delete: project not found", String.format("Project %s not found", project_id));
+ }
+
+ Integer position = (Integer)data.get("position");
+
+ if(position == null || position < 0) {
+ throw new CowebException("object delete: bad delete position", String.format("Bad position %s not found", position==null?"null":position.toString()));
+ }
+ int index = position.intValue();
+
+ @SuppressWarnings("unchecked")
+ ID object_id = (ID) values.get("id");
+
+ this.logger.debug(String.format("delete object %s in pos %d for project %s", object_id, index, project_id));
+
+ IRenkanModel<ID> currentObject = null;
+
+ List<T> objList = this.getObjectList(project);
+
+ if(index < objList.size()) {
+ currentObject = objList.get(index);
+ }
+
+ if(currentObject == null || !object_id.equals(currentObject.getId())) {
+ index = -1;
+ this.logger.warn(String.format("delete object %s in pos %d for project %s not current object", object_id, index, project_id));
+ for(int i=0;i<project.getNodes().size();i++) {
+ if(object_id.equals(objList.get(i).getId())) {
+ index = i;
+ break;
+ }
+ }
+ }
+
+ if(index<0) {
+ this.logger.warn(String.format("delete object %s in pos %d for project %s not found", object_id, index, project_id));
+ }
+ else {
+ objList.remove(index);
+ this.getObjectRepository().delete(object_id);
+ this.getProjectsRepository().save(project);
+ }
+
+ }
+
+ @Override
+ public abstract void nullOperation(Map<String, Object> data);
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/EdgeSyncEventManager.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,118 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.coweb.CowebException;
+import org.iri_research.renkan.models.Edge;
+import org.iri_research.renkan.models.Node;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.EdgesRepository;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.NodesRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Named
+public class EdgeSyncEventManager extends AbstractSyncEventManager<Edge, String> {
+
+ private final Logger logger = LoggerFactory.getLogger(EdgeSyncEventManager.class);
+
+ @Inject
+ private NodesRepository nodesRepository;
+
+ @Inject
+ private UsersRepository usersRepository;
+
+ @Inject
+ private EdgesRepository edgesRepository;
+
+
+ public NodesRepository getNodesRepository() {
+ return nodesRepository;
+ }
+
+ public UsersRepository getUsersRepository() {
+ return usersRepository;
+ }
+
+ public EdgesRepository getEdgesRepository() {
+ return edgesRepository;
+ }
+
+
+ @Override
+ public IRenkanRepository<Edge, String> getObjectRepository() {
+ return this.getEdgesRepository();
+ }
+
+
+ @Override
+ public void insert(Map<String, Object> data) {
+
+ // get project
+ this.logger.debug("EdgeSyncEventManager: insert Edge");
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String project_id = (String) values.get("_project_id");
+
+ Project project = this.getProjectsRepository().findOne(project_id);
+
+ if (null == project) {
+ throw new CowebException("Edge insert: project not found", String.format("Project %s not found", project_id));
+ }
+
+ String creator_id = (String) values.get("created_by");
+
+ String from_node_id = (String)values.get("from");
+ Node from_node = this.getNodesRepository().findOne(from_node_id);
+
+ if(null == from_node) {
+ throw new CowebException("Edge insert: from not found", String.format("from %s not found", from_node_id));
+ }
+
+ String to_node_id = (String)values.get("to");
+ Node to_node = this.getNodesRepository().findOne(to_node_id);
+
+ if(null == to_node) {
+ throw new CowebException("Edge insert: to not found", String.format("to %s not found", to_node_id));
+ }
+
+ String edge_id = (String)values.get("id");
+
+ Edge edge = new Edge(edge_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), from_node, to_node, creator_id, project_id);
+
+
+ Integer position = (Integer)data.get("position");
+
+ if(position == null || position < 0) {
+ throw new CowebException("Edge insert: bad insert position", String.format("Bad position %s not found", position==null?"null":position.toString()));
+ }
+ int index = position.intValue();
+ List<Edge> edges = project.getEdges();
+ if(index > edges.size()) {
+ index = edges.size();
+ }
+ edges.add(index,edge);
+
+ this.getEdgesRepository().save(edge);
+ this.getProjectsRepository().save(project);
+
+ }
+
+ @Override
+ public void nullOperation(Map<String, Object> data) {
+ this.logger.debug("nullOperation: NOP");
+ }
+
+ @Override
+ protected List<Edge> getObjectList(Project project) {
+ return project.getEdges();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/ISyncEventManager.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,21 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+
+public interface ISyncEventManager<T, ID extends Serializable> {
+
+ public void dispatchEvent(Map<String, Object> data);
+
+ public void update(Map<String, Object> data);
+ public void insert(Map<String, Object> data);
+ public void delete(Map<String, Object> data);
+ public void nullOperation(Map<String, Object> data);
+
+ public ProjectsRepository getProjectsRepository();
+ public IRenkanRepository<T,ID> getObjectRepository();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,101 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.coweb.CowebException;
+import org.iri_research.renkan.models.Node;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.NodesRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.geo.Point;
+
+@Named
+public class NodeSyncEventManager extends AbstractSyncEventManager<Node, String> {
+
+ private final Logger logger = LoggerFactory.getLogger(NodeSyncEventManager.class);
+
+ @Inject
+ private NodesRepository nodesRepository;
+
+ @Inject
+ private UsersRepository usersRepository;
+
+
+ public NodesRepository getNodesRepository() {
+ return nodesRepository;
+ }
+
+ @Override
+ public IRenkanRepository<Node, String> getObjectRepository() {
+ return this.getNodesRepository();
+ }
+
+ public UsersRepository getUsersRepository() {
+ return this.usersRepository;
+ }
+
+
+ @Override
+ public void insert(Map<String, Object> data) {
+
+ // get project
+ this.logger.debug("NodeSyncEventManager: insert Node");
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String project_id = (String) values.get("_project_id");
+
+ Project project = this.getProjectsRepository().findOne(project_id);
+
+ if (null == project) {
+ throw new CowebException("node insert: project not found", String.format("Project %s not found", project_id));
+ }
+
+ String creator_id = (String) values.get("created_by");
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> positionValues = (Map<String, Object>) values.get("position");
+
+ Point nodePosition = new Point(((Number)positionValues.get("x")).doubleValue(), ((Number)positionValues.get("y")).doubleValue());
+
+ String image = (String)values.get("image");
+
+ String node_id = (String)values.get("id");
+
+ Node node = new Node(node_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), project_id, creator_id, nodePosition, image);
+
+ Integer position = (Integer)data.get("position");
+
+ if(position == null || position < 0) {
+ throw new CowebException("node insert: bad insert position", String.format("Bad position %s not found", position==null?"null":position.toString()));
+ }
+ int index = position.intValue();
+ List<Node> nodes = project.getNodes();
+ if(index > nodes.size()) {
+ index = nodes.size();
+ }
+ nodes.add(index,node);
+
+ this.getNodesRepository().save(node);
+ this.getProjectsRepository().save(project);
+
+ }
+
+ @Override
+ public void nullOperation(Map<String, Object> data) {
+ this.logger.debug("nullOperation: NOP");
+ }
+
+ @Override
+ protected List<Node> getObjectList(Project project) {
+ return project.getNodes();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/ProjectSyncEventManager.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,64 @@
+/**
+ *
+ */
+package org.iri_research.renkan.coweb.event;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author ymh
+ *
+ */
+@Named
+public class ProjectSyncEventManager extends AbstractSyncEventManager<Project, String> {
+
+ private final Logger logger = LoggerFactory.getLogger(ProjectSyncEventManager.class);
+
+ @Override
+ public IRenkanRepository<Project, String> getObjectRepository() {
+ return this.getProjectsRepository();
+ }
+
+ /* (non-Javadoc)
+ * @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#insert(java.util.Map)
+ */
+ @Override
+ public void insert(Map<String, Object> data) {
+ this.logger.debug("Insert called, do nothing");
+ // do nothing
+ }
+
+ /* (non-Javadoc)
+ * @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#delete(java.util.Map)
+ */
+ @Override
+ public void delete(Map<String, Object> data) {
+ this.logger.debug("Delete called, do nothing");
+ // do nothing
+ }
+
+ /* (non-Javadoc)
+ * @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#nullOperation(java.util.Map)
+ */
+ @Override
+ public void nullOperation(Map<String, Object> data) {
+ this.logger.debug("Null called, do nothing");
+ // do nothing
+ }
+
+ @Override
+ protected List<Project> getObjectList(Project project) {
+ this.logger.error("Get object list called error");
+ throw new UnsupportedOperationException("Get object list called error");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/UserSyncEventManager.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,88 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.coweb.CowebException;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Named
+public class UserSyncEventManager extends AbstractSyncEventManager<User, String> {
+
+ private final Logger logger = LoggerFactory.getLogger(UserSyncEventManager.class);
+
+ private final static String DEFAULT_COLOR = "#000080";
+
+ @Inject
+ private UsersRepository usersRepository;
+
+ public UsersRepository getUsersRepository() {
+ return this.usersRepository;
+ }
+
+ @Override
+ public IRenkanRepository<User, String> getObjectRepository() {
+ return this.getUsersRepository();
+ }
+
+
+ @Override
+ public void insert(Map<String, Object> data) {
+
+ // get project
+ this.logger.debug("UserSyncEventManager: insert User");
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String project_id = (String) values.get("_project_id");
+
+ Project project = this.getProjectsRepository().findOne(project_id);
+
+ if (null == project) {
+ throw new CowebException("user insert: project not found", String.format("Project %s not found", project_id));
+ }
+
+ String user_id = (String)values.get("id");
+ String color = (String)values.get("color");
+ if(color == null || color.length() == 0) {
+ color = UserSyncEventManager.DEFAULT_COLOR;
+ }
+
+ User user = new User(user_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), color, project_id);
+
+ Integer position = (Integer)data.get("position");
+
+ if(position == null || position < 0) {
+ throw new CowebException("node insert: bad insert position", String.format("Bad position %s not found", position==null?"null":position.toString()));
+ }
+ int index = position.intValue();
+ List<User> users = project.getUsers();
+ if(index > users.size()) {
+ index = users.size();
+ }
+ users.add(index,user);
+
+ this.getUsersRepository().save(user);
+ this.getProjectsRepository().save(project);
+
+ }
+
+ @Override
+ public void nullOperation(Map<String, Object> data) {
+ this.logger.debug("nullOperation: NOP");
+ }
+
+ @Override
+ protected List<User> getObjectList(Project project) {
+ return project.getUsers();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/server/RenkanCometdServlet.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,28 @@
+package org.iri_research.renkan.coweb.server;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.server.BayeuxServerImpl;
+import org.cometd.server.CometdServlet;
+
+@Named
+public class RenkanCometdServlet extends CometdServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5362140618261972254L;
+
+ @Inject
+ private BayeuxServer _bayeux;
+
+ @Override
+ protected BayeuxServerImpl newBayeuxServer()
+ {
+ return (BayeuxServerImpl)_bayeux;
+ }
+
+
+}
--- a/server/src/main/java/org/iri_research/renkan/db/MongoConnectionManager.java Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/**
- *
- */
-package org.iri_research.renkan.db;
-
-import java.net.UnknownHostException;
-
-import com.mongodb.DB;
-import com.mongodb.Mongo;
-import com.mongodb.MongoException;
-
-/**
- * This singleton class manage the mongo connection.
- * This class is thread safe
- * The singleton class is implemented following this example : http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh
- * @author ymh
- *
- */
-public class MongoConnectionManager {
-
- //TODO: add application parameters
- public static final String HOST = "127.0.0.1";
- public static final int PORT = 27017;
- public static final String NAME = "renkan";
-
- private Mongo mongo = null;
- private DB db = null;
-
- public DB getDb() throws UnknownHostException, MongoException {
- if(null == this.db) {
- this.mongo = new Mongo(HOST, PORT);
- this.db = this.mongo.getDB(NAME);
- }
- return db;
- }
-
- // Private constructor suppresses generation
- // of a (public) default constructor
- private MongoConnectionManager() {}
-
- private static class SingletonHolder {
- public static final MongoConnectionManager INSTANCE = new MongoConnectionManager();
- }
-
- public static MongoConnectionManager getInstance() {
- return SingletonHolder.INSTANCE;
- }
-
-
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/AbstractRenkanModel.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,44 @@
+package org.iri_research.renkan.models;
+
+import java.io.Serializable;
+
+
+public abstract class AbstractRenkanModel<ID extends Serializable> implements IRenkanModel<ID> {
+
+ public AbstractRenkanModel(ID id, String title, String description, String uri) {
+ super();
+ this.id = id;
+ this.title = title;
+ this.description = description;
+ this.uri = uri;
+ }
+
+ protected AbstractRenkanModel() {
+ }
+
+ protected ID id;
+ protected String title;
+ protected String description;
+ protected String uri;
+
+ @Override
+ public String getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public String getDescription() {
+ return this.description;
+ }
+
+ @Override
+ public String getUri() {
+ return this.uri;
+ }
+
+ @Override
+ public ID getId() {
+ return this.id;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/Edge.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,57 @@
+package org.iri_research.renkan.models;
+
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+
+@Document(collection="edges")
+public class Edge extends AbstractRenkanModel<String> {
+
+ @DBRef
+ private Node from;
+
+ @DBRef
+ private Node to;
+
+ private String project_id;
+
+ private String created_by;
+
+
+ public Edge(String id, String title, String description, String uri, Node from, Node to, String created_by, String project_id) {
+ super(id,title, description, uri);
+ this.from = from;
+ this.to = to;
+ this.created_by = created_by;
+ this.project_id = project_id;
+ }
+
+
+ public String getProject_id() {
+ return project_id;
+ }
+
+
+ public String getCreated_by() {
+ return created_by;
+ }
+
+ public String getFrom() {
+ if(this.from != null) {
+ return this.from.id;
+ }
+ else {
+ return null;
+ }
+ }
+
+ public String getTo() {
+ if(this.to != null) {
+ return this.to.id;
+ }
+ else {
+ return null;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/IRenkanModel.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,13 @@
+package org.iri_research.renkan.models;
+
+import java.io.Serializable;
+
+
+public interface IRenkanModel<ID extends Serializable> {
+
+ public ID getId();
+ public String getTitle();
+ public String getDescription();
+ public String getUri();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/Node.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,43 @@
+package org.iri_research.renkan.models;
+
+import org.springframework.data.mongodb.core.geo.Point;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection="nodes")
+public class Node extends AbstractRenkanModel<String> {
+
+
+ public Node(String id, String title, String description, String uri, String project_id, String created_by, Point position, String image) {
+ super(id, title, description, uri);
+
+ this.project_id = project_id;
+ this.created_by = created_by;
+ this.position = position;
+ this.image = image;
+ }
+
+ private String project_id = null;
+
+ private String created_by = null;
+
+ private Point position = null;
+
+ public Point getPosition() {
+ return position;
+ }
+
+ private String image;
+
+ public String getImage() {
+ return image;
+ }
+
+ public String getProject_id() {
+ return project_id;
+ }
+
+ public String getCreated_by() {
+ return created_by;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/Project.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,63 @@
+package org.iri_research.renkan.models;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection="projects")
+public class Project extends AbstractRenkanModel<String> {
+
+ @SuppressWarnings("unused")
+ private static Logger logger = LoggerFactory.getLogger(Project.class);
+
+ private int revCounter = 1;
+
+ // Nodes
+ @DBRef
+ private List<Node> nodes = new ArrayList<Node>();
+
+ // edges
+ @DBRef
+ private List<Edge> edges = new ArrayList<Edge>();
+
+ // Users
+ @DBRef
+ private List<User> users = new ArrayList<User>();
+
+
+
+ public Project(String id, String title, String description, String uri,
+ int revCounter) {
+ super(id,title, description, uri);
+ this.revCounter = revCounter;
+ }
+
+ public Project(String id, String title, String description, String uri) {
+ this(id,title, description, uri, 1);
+ }
+
+ @SuppressWarnings("unused")
+ private Project() {
+ }
+
+ public int getRevCounter() {
+ return this.revCounter;
+ }
+
+ public List<Node> getNodes() {
+ return this.nodes;
+ }
+
+ public List<Edge> getEdges() {
+ return this.edges;
+ }
+
+ public List<User> getUsers() {
+ return this.users;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/ProjectRevision.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,68 @@
+package org.iri_research.renkan.models;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.bson.types.ObjectId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection="projectRevisions")
+public class ProjectRevision extends AbstractRenkanModel<ObjectId> {
+
+ @SuppressWarnings("unused")
+ private static Logger logger = LoggerFactory.getLogger(ProjectRevision.class);
+
+ private int revision;
+
+ @DBRef
+ private Project project;
+
+ private Date created;
+
+ // Nodes
+ private List<Node> nodes = new ArrayList<Node>();
+
+ // Edgess
+ private List<Edge> edges = new ArrayList<Edge>();
+
+
+ @SuppressWarnings("unused")
+ private ProjectRevision() {
+ super();
+ }
+
+ public ProjectRevision(ObjectId id, String title, String description,
+ String uri, Project project, int revision, Date created) {
+ super(id, title, description, uri);
+ this.project = project;
+ this.revision = revision;
+ if(created == null) {
+ this.created = new Date(System.currentTimeMillis());
+ }
+ }
+
+ public int getRevision() {
+ return revision;
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ public List<Node> getNodes() {
+ return nodes;
+ }
+
+ public List<Edge> getEgdes() {
+ return edges;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/ProjectSync.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,53 @@
+package org.iri_research.renkan.models;
+
+import java.util.Date;
+
+import org.bson.types.ObjectId;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+
+@Document(collection="projectSyncs")
+public class ProjectSync {
+
+ private ObjectId id;
+
+ private String data;
+
+ @DBRef
+ private Project project;
+
+ private int revision;
+
+ private Date created;
+
+ public ProjectSync(ObjectId id, String data, Project project, int revision,
+ Date created) {
+ this.id = id;
+ this.data = data;
+ this.project = project;
+ this.revision = revision;
+ this.created = created;
+ if(this.created == null) {
+ this.created = new Date(System.currentTimeMillis());
+ }
+ }
+
+ public ObjectId getId() {
+ return id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ public int getRevision() {
+ return revision;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/User.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,27 @@
+package org.iri_research.renkan.models;
+
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection="users")
+public class User extends AbstractRenkanModel<String> {
+
+ private String color;
+
+ private String project_id;
+
+ public User(String id, String title, String description, String uri, String color, String project_id) {
+ super(id, title, description, uri);
+
+ this.project_id = project_id;
+ this.color = color;
+ }
+
+ public String getColor() {
+ return this.color;
+ }
+
+ public String getProject_id() {
+ return project_id;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/EdgesRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,7 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.Edge;
+
+public interface EdgesRepository extends IRenkanRepository<Edge, String> {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/IRenkanRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,13 @@
+package org.iri_research.renkan.repositories;
+
+import java.io.Serializable;
+
+import org.springframework.data.repository.CrudRepository;
+
+import com.mongodb.DBCollection;
+
+public interface IRenkanRepository<T, ID extends Serializable> extends
+ CrudRepository<T, ID> {
+
+ public DBCollection getCollection();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/NodesRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,7 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.Node;
+
+public interface NodesRepository extends IRenkanRepository<Node, String> {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,10 @@
+package org.iri_research.renkan.repositories;
+
+import org.bson.types.ObjectId;
+import org.iri_research.renkan.models.ProjectRevision;
+
+public interface ProjectRevisionsRepository extends
+ IRenkanRepository<ProjectRevision, ObjectId>,
+ ProjectRevisionsRepositoryCustom {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepositoryCustom.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,10 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.ProjectRevision;
+
+public interface ProjectRevisionsRepositoryCustom {
+
+ public ProjectRevision getProjectRevision(Project project, int revision);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepositoryImpl.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,28 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.Date;
+
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.ProjectRevision;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ProjectRevisionsRepositoryImpl implements
+ ProjectRevisionsRepositoryCustom {
+
+ @Override
+ public ProjectRevision getProjectRevision(Project project, int revision) {
+ ProjectRevision pr = new ProjectRevision(
+ null,
+ project.getTitle(),
+ project.getDescription(),
+ project.getUri(),
+ project,
+ revision,
+ new Date(System.currentTimeMillis())
+ );
+
+ return pr;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,10 @@
+package org.iri_research.renkan.repositories;
+
+import org.bson.types.ObjectId;
+import org.iri_research.renkan.models.ProjectSync;
+
+public interface ProjectSyncsRepository extends
+ IRenkanRepository<ProjectSync, ObjectId>,
+ ProjectSyncsRepositoryCustom {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepositoryCustom.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,13 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.ProjectSync;
+
+public interface ProjectSyncsRepositoryCustom {
+
+ public ProjectSync getProjectSync(String data, Project project) throws RenkanException;
+
+ public ProjectSync getProjectSync(String data, String project_id) throws RenkanException;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepositoryImpl.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,54 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.Date;
+
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.ProjectSync;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ProjectSyncsRepositoryImpl implements
+ ProjectSyncsRepositoryCustom {
+
+ @Autowired
+ private ProjectsRepository projectRepository;
+
+ @Override
+ public ProjectSync getProjectSync(String data, Project project) throws RenkanException {
+
+ if(project == null) {
+ throw new RenkanException("ProjectSyncsRepository : Null Project.");
+ }
+
+ ProjectSync ps = new ProjectSync(
+ null,
+ data,
+ project,
+ this.projectRepository.getRevCounter(project.getId()),
+ new Date(System.currentTimeMillis())
+ );
+
+ return ps;
+ }
+
+ @Override
+ public ProjectSync getProjectSync(String data, String project_id)
+ throws RenkanException {
+
+ if(project_id == null || "".equals(project_id) ) {
+ throw new RenkanException("ProjectSyncsRepository : Null or empty project id.");
+ }
+
+ Project p = this.projectRepository.findOne(project_id);
+
+ if(p == null) {
+ throw new RenkanException("ProjectSyncsRepository : project not found for id " + project_id);
+ }
+
+ return this.getProjectSync(data, p);
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,7 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.Project;
+
+public interface ProjectsRepository extends IRenkanRepository<Project, String>, ProjectsRepositoryCustom {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryCustom.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,5 @@
+package org.iri_research.renkan.repositories;
+
+public interface ProjectsRepositoryCustom {
+ public int getRevCounter(String projectId);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryImpl.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,27 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.Project;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.stereotype.Component;
+import static org.springframework.data.mongodb.core.query.Query.query;
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import org.springframework.data.mongodb.core.query.Update;
+
+@Component
+public class ProjectsRepositoryImpl implements ProjectsRepositoryCustom {
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
+
+ @Override
+ public int getRevCounter(String projectId) {
+ Project p = this.mongoTemplate.findAndModify(query(where("id").is(projectId)), new Update().inc("revCounter", 1), Project.class);
+
+ if(p == null) {
+ return -1;
+ }
+ return p.getRevCounter();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,23 @@
+package org.iri_research.renkan.repositories;
+
+import java.io.Serializable;
+
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
+import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
+
+import com.mongodb.DBCollection;
+
+public class RenkanRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements
+ IRenkanRepository<T, ID> {
+
+ public RenkanRepository(MongoEntityInformation<T,ID> metadata,
+ MongoOperations mongoOperations) {
+ super(metadata, mongoOperations);
+ }
+
+ @Override
+ public DBCollection getCollection() {
+ return this.getMongoOperations().getCollection(this.getEntityInformation().getCollectionName());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryException.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,11 @@
+package org.iri_research.renkan.repositories;
+
+public class RenkanRepositoryException extends Exception {
+
+ private static final long serialVersionUID = -7433823426870169568L;
+
+ public RenkanRepositoryException(String message) {
+ super(message);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryFactory.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,50 @@
+package org.iri_research.renkan.repositories;
+
+import java.io.Serializable;
+
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
+import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
+import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
+import org.springframework.data.repository.core.RepositoryMetadata;
+
+public class RenkanRepositoryFactory extends MongoRepositoryFactory {
+
+ private MongoOperations mongoOperations;
+ public RenkanRepositoryFactory(MongoOperations mongoOperations) {
+ super(mongoOperations);
+ this.mongoOperations = mongoOperations;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryMetadata)
+ */
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected Object getTargetRepository(RepositoryMetadata metadata) {
+
+ Object res = super.getTargetRepository(metadata);
+
+ if(SimpleMongoRepository.class.equals(res.getClass())) {
+ MongoEntityInformation<?, Serializable> entityInformation = this.getEntityInformation(metadata.getDomainType());
+ return new RenkanRepository(entityInformation, this.mongoOperations);
+ }
+ else {
+ return res;
+ }
+
+ }
+
+ @Override
+ protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
+ Class<?> res = super.getRepositoryBaseClass(metadata);
+ if(SimpleMongoRepository.class.equals(res)) {
+ return RenkanRepository.class;
+ }
+ else {
+ return res;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryFactoryBean.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,17 @@
+package org.iri_research.renkan.repositories;
+
+import java.io.Serializable;
+
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
+import org.springframework.data.repository.Repository;
+import org.springframework.data.repository.core.support.RepositoryFactorySupport;
+
+public class RenkanRepositoryFactoryBean<T extends Repository<S,ID>,S,ID extends Serializable> extends MongoRepositoryFactoryBean<T,S,ID> {
+
+ @Override
+ protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
+ return new RenkanRepositoryFactory(operations);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/UsersRepository.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,7 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.User;
+
+public interface UsersRepository extends IRenkanRepository<User, String> {
+
+}
--- a/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java Fri Dec 21 16:22:08 2012 +0100
+++ b/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java Mon Dec 31 13:37:31 2012 +0100
@@ -1,9 +1,11 @@
package org.iri_research.renkan.rest;
-import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.UUID;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@@ -17,174 +19,67 @@
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
-import org.iri_research.renkan.db.MongoConnectionManager;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.ProjectsRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
import com.mongodb.BasicDBObject;
-import com.mongodb.DB;
import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
import com.mongodb.DBObject;
-import com.mongodb.MongoException;
import com.mongodb.WriteResult;
import com.mongodb.util.JSON;
import com.sun.jersey.spi.resource.Singleton;
+
@Singleton
@Path("projects")
+@Component
public class ProjectsResource {
- private Logger logger = LoggerFactory.getLogger(ProjectsResource.class);
+ private Logger logger = LoggerFactory.getLogger(ProjectsResource.class);
+
+ @Autowired
+ private ProjectsRepository projectRepository;
@Context
private UriInfo uriInfo;
-
- private DB getDb() {
- DB db = null;
- try {
- db = MongoConnectionManager.getInstance().getDb();
- } catch (UnknownHostException e) {
- throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
- } catch (MongoException e) {
- throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
- }
- return db;
- }
-
+
private DBCollection getCollection() {
- DB db = this.getDb();
- return db.getCollection("projects");
+ return projectRepository.getCollection();
}
@GET
@Path("{id : [a-zA-Z\\-0-9]+}")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
- public String getProject(@PathParam("id") String projectId) {
+ public Project getProjectSd(@PathParam("id") String projectId) {
- this.logger.debug("GetProject : id " + projectId);
-
- DBCollection projectCollection = this.getCollection();
- DBObject project = projectCollection.findOne(projectId);
+ this.logger.debug("GetProject: " + projectId);
+
+ Project project = this.projectRepository.findOne(projectId);
if (null == project) {
throw new WebApplicationException(Status.NOT_FOUND);
}
- return project.toString();
-
- /*return "{" +
- "\"title\": \"Test Graph\"," +
- "\"creation_date\": \"2012-07-25T11:00:00.0Z\"," +
- "\"users\": [" +
- "{" +
- "\"id\": \"u-cybunk\"," +
- "\"title\": \"Samuel\"," +
- "\"uri\": \"http://twitter.com/cybunk\"," +
- "\"color\": \"#e00000\"" +
- "}," +
- "{" +
- "\"id\": \"u-raphv\"," +
- "\"title\": \"Raphael\"," +
- "\"uri\": \"http://twitter.com/raphv\"," +
- "\"color\": \"#00a000\"" +
- "}" +
- "]," +
- "\"nodes\": [" +
- "{" +
- "\"id\": \"n-001\"," +
- "\"title\": \"連環 (Renkan)\"," +
- "\"uri\": \"http://ja.wikipedia.org/wiki/%E7%99%BE%E5%AD%A6%E9%80%A3%E7%92%B0\"," +
- "\"created_by\": \"u-cybunk\"," +
- "\"position\": {" +
- "\"x\": 0," +
- "\"y\": 0" +
- "}" +
- "}," +
- "{" +
- "\"id\": \"n-002\"," +
- "\"title\": \"Savoir\"," +
- "\"uri\": \"http://fr.wikipedia.org/wiki/Savoir\"," +
- "\"created_by\": \"u-raphv\"," +
- "\"position\": {" +
- "\"x\": 200," +
- "\"y\": 50" +
- "}" +
- "}," +
- "{" +
- "\"id\": \"n-003\"," +
- "\"title\": \"Connaissance\","+
- "\"uri\": \"http://fr.wikipedia.org/wiki/Connaissance\","+
- "\"created_by\": \"u-raphv\","+
- "\"position\": {"+
- "\"x\": 300,"+
- "\"y\": -50"+
- "}"+
- "},"+
- "{"+
- "\"id\": \"n-004\","+
- "\"title\": \"graphe\","+
- "\"uri\": \"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes\","+
- "\"created_by\": \"u-cybunk\","+
- "\"position\": {"+
- "\"x\": -200,"+
- "\"y\": 0"+
- "}"+
- "},"+
- "{"+
- "\"id\": \"n-005\","+
- "\"title\": \"nœud\","+
- "\"uri\": \"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes\","+
- "\"created_by\": \"u-cybunk\","+
- "\"position\": {"+
- "\"x\": -350,"+
- "\"y\": 100"+
- "}"+
- "},"+
- "{"+
- "\"id\": \"n-006\","+
- "\"title\": \"lien\","+
- "\"uri\": \"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes\","+
- "\"created_by\": \"u-cybunk\","+
- "\"position\": {"+
- "\"x\": -300,"+
- "\"y\": -100"+
- "}"+
- "}"+
- "],"+
- "\"edges\": ["+
- "{"+
- "\"id\": \"e-001\","+
- "\"from\": \"n-001\","+
- "\"to\": \"n-002\","+
- "\"created_by\": \"u-raphv\""+
- "},"+
- "{"+
- "\"id\": \"e-002\","+
- "\"from\": \"n-002\","+
- "\"to\": \"n-003\","+
- "\"created_by\": \"u-raphv\""+
- "},"+
- "{"+
- "\"id\": \"e-003\","+
- "\"from\": \"n-001\","+
- "\"to\": \"n-004\","+
- "\"created_by\": \"u-cybunk\""+
- "},"+
- "{"+
- "\"id\": \"e-004\","+
- "\"from\": \"n-004\","+
- "\"to\": \"n-005\","+
- "\"created_by\": \"u-cybunk\""+
- "},"+
- "{"+
- "\"id\": \"e-005\","+
- "\"from\": \"n-004\","+
- "\"to\": \"n-006\","+
- "\"created_by\": \"u-cybunk\""+
- "}"+
- "]"+
- "}";*/
+ return project;
}
+
+ @DELETE
+ @Path("{id : [a-zA-Z\\-0-9]+}")
+ @Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
+ public Response deleteProject(@PathParam("id") String projectId) {
+
+ this.logger.debug("DeleteProject : id " + projectId);
+
+ this.projectRepository.delete(projectId);
+ return Response.ok(this.uriInfo.getAbsolutePathBuilder().segment(projectId).build().toString() + " deleted").build();
+
+ }
+
/**
* test: curl -i -X PUT -H 'Content-Type: application/json' -d @test-data.json http://localhost:8080/renkan/rest/projects/12eff140-e65c-11e1-aff1-0800200c9a66
@@ -193,20 +88,68 @@
*/
@PUT
@Path("{id : [a-zA-Z\\-0-9]+}")
- @Consumes(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response putProject(@PathParam("id") String projectId, String projectContent) {
return this.createOrUpdateProject(projectId, projectContent);
}
@POST
- @Consumes(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response postProject(String projectContent) {
return this.createOrUpdateProject(null, projectContent);
}
+ //TODO: uses spring data
+ @GET
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public String getProjectList() {
+
+ DBCollection projectCollection = this.getCollection();
+ BasicDBObject keys = new BasicDBObject();
+ keys.put("description", 1);
+ keys.put("title", 1);
+ keys.put("uri", 1);
+ DBCursor cursor = projectCollection.find(new BasicDBObject(), keys);
+
+ List<DBObject> res = new ArrayList<DBObject>();
+
+ try {
+ while(cursor.hasNext()) {
+ DBObject obj = cursor.next();
+ DBObject links = new BasicDBObject();
+
+ DBObject linkdef = new BasicDBObject();
+ linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
+ linkdef.put("method", "get");
+ linkdef.put("produces", MediaType.APPLICATION_JSON + ";charset=utf-8");
+ links.put("view", linkdef);
+
+ linkdef = new BasicDBObject();
+ linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
+ linkdef.put("method", "put");
+ linkdef.put("consumes", MediaType.APPLICATION_JSON + ";charset=utf-8");
+ links.put("update", linkdef);
+
+ linkdef = new BasicDBObject();
+ linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
+ linkdef.put("method", "delete");
+ links.put("delete", linkdef);
+
+ obj.put("__links", links);
+ res.add(obj);
+ }
+ }
+ finally {
+ cursor.close();
+ }
+
+ return JSON.serialize(res);
+ }
+
+ //TODO: rewrite for recursive object and use spring data
private Response createOrUpdateProject(String projectId, String projectContent) {
if(null == projectContent || projectContent.isEmpty()) {
--- a/server/src/main/resources/_firebug/LICENSE Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-License Disclaimer:
-
-All contents of this directory are Copyright (c) the Dojo Foundation, with the
-following exceptions:
--------------------------------------------------------------------------------
-
-firebug.html, firebug.js, errIcon.png, infoIcon.png, warningIcon.png:
- * Copyright (c) 2006-2007, Joe Hewitt, All rights reserved.
- Distributed under the terms of the BSD License (see below)
-
--------------------------------------------------------------------------------
-
-Copyright (c) 2006-2007, Joe Hewitt
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the Dojo Foundation nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Binary file server/src/main/resources/_firebug/errorIcon.png has changed
--- a/server/src/main/resources/_firebug/firebug.css Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-.firebug {
- margin: 0;
- background:#fff;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
- overflow: hidden;
- border: 1px solid black;
- position: relative;
-}
-.firebug a {
- text-decoration: none;
-}
-.firebug a:hover {
- text-decoration: underline;
-}
-.firebug a:visited{
- color:#0000FF;
-}
-.firebug #firebugToolbar {
- height: 18px;
- line-height:18px;
- border-top: 1px solid ThreeDHighlight;
- border-bottom: 1px solid ThreeDShadow;
- padding: 2px 6px;
-
- background:#f0f0f0;
-}
-.firebug #firebugLog, .firebug #objectLog {
- overflow: auto;
- position: absolute;
- left: 0;
- width: 100%;
-}
-#objectLog{
- overflow:scroll;
- height:258px;
-}
-.firebug #firebugCommandLine {
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 18px;
- border: none;
- border-top: 1px solid ThreeDShadow;
-}
-.firebug .logRow {
- position: relative;
- border-bottom: 1px solid #D7D7D7;
- padding: 2px 4px 1px 6px;
- background-color: #FFFFFF;
-}
-.firebug .logRow-command {
- font-family: Monaco, monospace;
- color: blue;
-}
-.firebug .objectBox-null {
- padding: 0 2px;
- border: 1px solid #666666;
- background-color: #888888;
- color: #FFFFFF;
-}
-.firebug .objectBox-string {
- font-family: Monaco, monospace;
- color: red;
- white-space: pre;
-}
-.firebug .objectBox-number {
- color: #000088;
-}
-.firebug .objectBox-function {
- font-family: Monaco, monospace;
- color: DarkGreen;
-}
-.firebug .objectBox-object {
- color: DarkGreen;
- font-weight: bold;
-}
-.firebug .logRow-info,
-.firebug .logRow-error,
-.firebug .logRow-warning
- {
- background: #00FFFF no-repeat 2px 2px;
- padding-left: 20px;
- padding-bottom: 3px;
-}
-.firebug .logRow-info {
- background: #FFF url(infoIcon.png) no-repeat 2px 2px;
- padding-left: 20px;
- padding-bottom: 3px;
-}
-.firebug .logRow-warning {
-
- background: #00FFFF url(warningIcon.png) no-repeat 2px 2px;
- padding-left: 20px;
- padding-bottom: 3px;
-}
-.firebug .logRow-error {
- background: LightYellow url(errorIcon.png) no-repeat 2px 2px;
- padding-left: 20px;
- padding-bottom: 3px;
-}
-.firebug .errorMessage {
- vertical-align: top;
- color: #FF0000;
-}
-.firebug .objectBox-sourceLink {
- position: absolute;
- right: 4px;
- top: 2px;
- padding-left: 8px;
- font-family: Lucida Grande, sans-serif;
- font-weight: bold;
- color: #0000FF;
-}
-.firebug .logRow-group {
- background: #EEEEEE;
- border-bottom: none;
-}
-.firebug .logGroup {
- background: #EEEEEE;
-}
-.firebug .logGroupBox {
- margin-left: 24px;
- border-top: 1px solid #D7D7D7;
- border-left: 1px solid #D7D7D7;
-}
-.firebug .selectorTag,
-.firebug .selectorId,
-.firebug .selectorClass {
- font-family: Monaco, monospace;
- font-weight: normal;
-}
-.firebug .selectorTag {
- color: #0000FF;
-}
-.firebug .selectorId {
- color: DarkBlue;
-}
-.firebug .selectorClass {
- color: red;
-}
-.firebug .objectBox-element {
- font-family: Monaco, monospace;
- color: #000088;
-}
-.firebug .nodeChildren {
- margin-left: 16px;
-}
-.firebug .nodeTag {
- color: blue;
-}
-.firebug .nodeValue {
- color: #FF0000;
- font-weight: normal;
-}
-.firebug .nodeText,
-.firebug .nodeComment {
- margin: 0 2px;
- vertical-align: top;
-}
-.firebug .nodeText {
- color: #333333;
-}
-.firebug .nodeComment {
- color: DarkGreen;
-}
-.firebug .propertyNameCell {
- vertical-align: top;
-}
-.firebug .propertyName {
- font-weight: bold;
-}
-#firebugToolbar ul.tabs{
- margin:0 !important;
- padding:0;
-}
-#firebugToolbar ul.tabs li{
- list-style:none;
- background:transparent url(tab_lft_norm.png) no-repeat left;
- line-height:18px;
- float:left;
- margin-left:5px;
-}
-#firebugToolbar ul.tabs li.right{
- float:right;
- margin-right:5px;
- margin-left:0;
-}
-#firebugToolbar ul.tabs li.gap{
- margin-left:20px;
-}
-#firebugToolbar .tabs a{
- text-decoration:none;
- background:transparent url(tab_rgt_norm.png) no-repeat right;
- line-height:18px;
- padding:3px 9px 4px 0px;
- margin-left:9px;
- color:#333333;
-}
-#firebugToolbar .tabs li:hover{
- background:transparent url(tab_lft_over.png) no-repeat left;
-}
-#firebugToolbar .tabs a:hover{
- text-decoration:none;
- background:transparent url(tab_rgt_over.png) no-repeat right;
- color:#FFFFFF;
-}
--- a/server/src/main/resources/_firebug/firebug.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,898 +0,0 @@
-/*
- Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
-*/
-
-//>>built
-define("dojo/_firebug/firebug",["../_base/kernel","require","../_base/html","../sniff","../_base/array","../_base/lang","../_base/event","../_base/unload"],function(_1,_2,_3,_4){
-var _5=(/Trident/.test(window.navigator.userAgent));
-if(_5){
-var _6=["log","info","debug","warn","error"];
-for(var i=0;i<_6.length;i++){
-var m=_6[i];
-if(!console[m]||console[m]._fake){
-continue;
-}
-var n="_"+_6[i];
-console[n]=console[m];
-console[m]=(function(){
-var _7=n;
-return function(){
-console[_7](Array.prototype.join.call(arguments," "));
-};
-})();
-}
-try{
-console.clear();
-}
-catch(e){
-}
-}
-if(_4("ff")||_4("chrome")||_4("safari")||_5||window.firebug||(typeof console!="undefined"&&console.firebug)||_1.config.useCustomLogger||_4("air")){
-return;
-}
-try{
-if(window!=window.parent){
-if(window.parent["console"]){
-window.console=window.parent.console;
-}
-return;
-}
-}
-catch(e){
-}
-var _8=document;
-var _9=window;
-var _a=0;
-var _b=null;
-var _c=null;
-var _d=null;
-var _e=null;
-var _f=null;
-var _10=null;
-var _11=false;
-var _12=[];
-var _13=[];
-var _14={};
-var _15={};
-var _16=null;
-var _17;
-var _18;
-var _19=false;
-var _1a=null;
-var _1b=document.createElement("div");
-var _1c;
-var _1d;
-window.console={_connects:[],log:function(){
-_1e(arguments,"");
-},debug:function(){
-_1e(arguments,"debug");
-},info:function(){
-_1e(arguments,"info");
-},warn:function(){
-_1e(arguments,"warning");
-},error:function(){
-_1e(arguments,"error");
-},assert:function(_1f,_20){
-if(!_1f){
-var _21=[];
-for(var i=1;i<arguments.length;++i){
-_21.push(arguments[i]);
-}
-_1e(_21.length?_21:["Assertion Failure"],"error");
-throw _20?_20:"Assertion Failure";
-}
-},dir:function(obj){
-var str=_22(obj);
-str=str.replace(/\n/g,"<br />");
-str=str.replace(/\t/g," ");
-_23([str],"dir");
-},dirxml:function(_24){
-var _25=[];
-_26(_24,_25);
-_23(_25,"dirxml");
-},group:function(){
-_23(arguments,"group",_27);
-},groupEnd:function(){
-_23(arguments,"",_28);
-},time:function(_29){
-_14[_29]=new Date().getTime();
-},timeEnd:function(_2a){
-if(_2a in _14){
-var _2b=(new Date()).getTime()-_14[_2a];
-_1e([_2a+":",_2b+"ms"]);
-delete _14[_2a];
-}
-},count:function(_2c){
-if(!_15[_2c]){
-_15[_2c]=0;
-}
-_15[_2c]++;
-_1e([_2c+": "+_15[_2c]]);
-},trace:function(_2d){
-var _2e=_2d||3;
-var f=console.trace.caller;
-for(var i=0;i<_2e;i++){
-var _2f=f.toString();
-var _30=[];
-for(var a=0;a<f.arguments.length;a++){
-_30.push(f.arguments[a]);
-}
-if(f.arguments.length){
-}else{
-}
-f=f.caller;
-}
-},profile:function(){
-this.warn(["profile() not supported."]);
-},profileEnd:function(){
-},clear:function(){
-if(_c){
-while(_c.childNodes.length){
-_1.destroy(_c.firstChild);
-}
-}
-_1.forEach(this._connects,_1.disconnect);
-},open:function(){
-_31(true);
-},close:function(){
-if(_11){
-_31();
-}
-},_restoreBorder:function(){
-if(_1c){
-_1c.style.border=_1d;
-}
-},openDomInspector:function(){
-_19=true;
-_c.style.display="none";
-_16.style.display="block";
-_d.style.display="none";
-document.body.style.cursor="pointer";
-_17=_1.connect(document,"mousemove",function(evt){
-if(!_19){
-return;
-}
-if(!_1a){
-_1a=setTimeout(function(){
-_1a=null;
-},50);
-}else{
-return;
-}
-var _32=evt.target;
-if(_32&&(_1c!==_32)){
-var _33=true;
-console._restoreBorder();
-var _34=[];
-_26(_32,_34);
-_16.innerHTML=_34.join("");
-_1c=_32;
-_1d=_1c.style.border;
-_1c.style.border="#0000FF 1px solid";
-}
-});
-setTimeout(function(){
-_18=_1.connect(document,"click",function(evt){
-document.body.style.cursor="";
-_19=!_19;
-_1.disconnect(_18);
-});
-},30);
-},_closeDomInspector:function(){
-document.body.style.cursor="";
-_1.disconnect(_17);
-_1.disconnect(_18);
-_19=false;
-console._restoreBorder();
-},openConsole:function(){
-_c.style.display="block";
-_16.style.display="none";
-_d.style.display="none";
-console._closeDomInspector();
-},openObjectInspector:function(){
-_c.style.display="none";
-_16.style.display="none";
-_d.style.display="block";
-console._closeDomInspector();
-},recss:function(){
-var i,a,s;
-a=document.getElementsByTagName("link");
-for(i=0;i<a.length;i++){
-s=a[i];
-if(s.rel.toLowerCase().indexOf("stylesheet")>=0&&s.href){
-var h=s.href.replace(/(&|%5C?)forceReload=\d+/,"");
-s.href=h+(h.indexOf("?")>=0?"&":"?")+"forceReload="+new Date().valueOf();
-}
-}
-}};
-function _31(_35){
-_11=_35||!_11;
-if(_b){
-_b.style.display=_11?"block":"none";
-}
-};
-function _36(){
-_31(true);
-if(_f){
-_f.focus();
-}
-};
-function _37(x,y,w,h){
-var win=window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
-if(!win){
-var msg="Firebug Lite could not open a pop-up window, most likely because of a blocker.\n"+"Either enable pop-ups for this domain, or change the djConfig to popup=false.";
-alert(msg);
-}
-_38(win);
-var _39=win.document;
-var _3a="<html style=\"height:100%;\"><head><title>Firebug Lite</title></head>\n"+"<body bgColor=\"#ccc\" style=\"height:97%;\" onresize=\"opener.onFirebugResize()\">\n"+"<div id=\"fb\"></div>"+"</body></html>";
-_39.write(_3a);
-_39.close();
-return win;
-};
-function _38(wn){
-var d=new Date();
-d.setTime(d.getTime()+(60*24*60*60*1000));
-d=d.toUTCString();
-var dc=wn.document,_3b;
-if(wn.innerWidth){
-_3b=function(){
-return {w:wn.innerWidth,h:wn.innerHeight};
-};
-}else{
-if(dc.documentElement&&dc.documentElement.clientWidth){
-_3b=function(){
-return {w:dc.documentElement.clientWidth,h:dc.documentElement.clientHeight};
-};
-}else{
-if(dc.body){
-_3b=function(){
-return {w:dc.body.clientWidth,h:dc.body.clientHeight};
-};
-}
-}
-}
-window.onFirebugResize=function(){
-_49(_3b().h);
-clearInterval(wn._firebugWin_resize);
-wn._firebugWin_resize=setTimeout(function(){
-var x=wn.screenLeft,y=wn.screenTop,w=wn.outerWidth||wn.document.body.offsetWidth,h=wn.outerHeight||wn.document.body.offsetHeight;
-document.cookie="_firebugPosition="+[x,y,w,h].join(",")+"; expires="+d+"; path=/";
-},5000);
-};
-};
-function _3c(){
-if(_b){
-return;
-}
-_31(true);
-if(_1.config.popup){
-var _3d="100%";
-var _3e=document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
-var p=_3e?_3e[1].split(","):[2,2,320,480];
-_9=_37(p[0],p[1],p[2],p[3]);
-_8=_9.document;
-_1.config.debugContainerId="fb";
-_9.console=window.console;
-_9.dojo=window.dojo;
-}else{
-_8=document;
-_3d=(_1.config.debugHeight||300)+"px";
-}
-var _3f=_8.createElement("link");
-_3f.href=_2.toUrl("./firebug.css");
-_3f.rel="stylesheet";
-_3f.type="text/css";
-var _40=_8.getElementsByTagName("head");
-if(_40){
-_40=_40[0];
-}
-if(!_40){
-_40=_8.getElementsByTagName("html")[0];
-}
-if(_4("ie")){
-window.setTimeout(function(){
-_40.appendChild(_3f);
-},0);
-}else{
-_40.appendChild(_3f);
-}
-if(_1.config.debugContainerId){
-_b=_8.getElementById(_1.config.debugContainerId);
-}
-if(!_b){
-_b=_8.createElement("div");
-_8.body.appendChild(_b);
-}
-_b.className+=" firebug";
-_b.id="firebug";
-_b.style.height=_3d;
-_b.style.display=(_11?"block":"none");
-var _41=function(_42,_43,_44,_45){
-return "<li class=\""+_45+"\"><a href=\"javascript:void(0);\" onclick=\"console."+_44+"(); return false;\" title=\""+_43+"\">"+_42+"</a></li>";
-};
-_b.innerHTML="<div id=\"firebugToolbar\">"+" <ul id=\"fireBugTabs\" class=\"tabs\">"+_41("Clear","Remove All Console Logs","clear","")+_41("ReCSS","Refresh CSS without reloading page","recss","")+_41("Console","Show Console Logs","openConsole","gap")+_41("DOM","Show DOM Inspector","openDomInspector","")+_41("Object","Show Object Inspector","openObjectInspector","")+((_1.config.popup)?"":_41("Close","Close the console","close","gap"))+"\t</ul>"+"</div>"+"<input type=\"text\" id=\"firebugCommandLine\" />"+"<div id=\"firebugLog\"></div>"+"<div id=\"objectLog\" style=\"display:none;\">Click on an object in the Log display</div>"+"<div id=\"domInspect\" style=\"display:none;\">Hover over HTML elements in the main page. Click to hold selection.</div>";
-_10=_8.getElementById("firebugToolbar");
-_f=_8.getElementById("firebugCommandLine");
-_46(_f,"keydown",_47);
-_46(_8,_4("ie")||_4("safari")?"keydown":"keypress",_48);
-_c=_8.getElementById("firebugLog");
-_d=_8.getElementById("objectLog");
-_16=_8.getElementById("domInspect");
-_e=_8.getElementById("fireBugTabs");
-_49();
-_4a();
-};
-_1.addOnLoad(_3c);
-function _4b(){
-_8=null;
-if(_9.console){
-_9.console.clear();
-}
-_9=null;
-_b=null;
-_c=null;
-_d=null;
-_16=null;
-_f=null;
-_12=[];
-_13=[];
-_14={};
-};
-function _4c(){
-var _4d=_f.value;
-_f.value="";
-_23(["> ",_4d],"command");
-var _4e;
-try{
-_4e=eval(_4d);
-}
-catch(e){
-}
-};
-function _49(h){
-var _4f=25;
-var _50=h?h-(_4f+_f.offsetHeight+25+(h*0.01))+"px":(_b.offsetHeight-_4f-_f.offsetHeight)+"px";
-_c.style.top=_4f+"px";
-_c.style.height=_50;
-_d.style.height=_50;
-_d.style.top=_4f+"px";
-_16.style.height=_50;
-_16.style.top=_4f+"px";
-_f.style.bottom=0;
-_1.addOnWindowUnload(_4b);
-};
-function _23(_51,_52,_53){
-if(_c){
-_54(_51,_52,_53);
-}else{
-_12.push([_51,_52,_53]);
-}
-};
-function _4a(){
-var _55=_12;
-_12=[];
-for(var i=0;i<_55.length;++i){
-_54(_55[i][0],_55[i][1],_55[i][2]);
-}
-};
-function _54(_56,_57,_58){
-var _59=_c.scrollTop+_c.offsetHeight>=_c.scrollHeight;
-_58=_58||_5a;
-_58(_56,_57);
-if(_59){
-_c.scrollTop=_c.scrollHeight-_c.offsetHeight;
-}
-};
-function _5b(row){
-var _5c=_13.length?_13[_13.length-1]:_c;
-_5c.appendChild(row);
-};
-function _5a(_5d,_5e){
-var row=_c.ownerDocument.createElement("div");
-row.className="logRow"+(_5e?" logRow-"+_5e:"");
-row.innerHTML=_5d.join("");
-_5b(row);
-};
-function _27(_5f,_60){
-_1e(_5f,_60);
-var _61=_c.ownerDocument.createElement("div");
-_61.className="logGroupBox";
-_5b(_61);
-_13.push(_61);
-};
-function _28(){
-_13.pop();
-};
-function _1e(_62,_63){
-var _64=[];
-var _65=_62[0];
-var _66=0;
-if(typeof (_65)!="string"){
-_65="";
-_66=-1;
-}
-var _67=_68(_65);
-for(var i=0;i<_67.length;++i){
-var _69=_67[i];
-if(_69&&typeof _69=="object"){
-_69.appender(_62[++_66],_64);
-}else{
-_6a(_69,_64);
-}
-}
-var ids=[];
-var obs=[];
-for(i=_66+1;i<_62.length;++i){
-_6a(" ",_64);
-var _6b=_62[i];
-if(_6b===undefined||_6b===null){
-_6c(_6b,_64);
-}else{
-if(typeof (_6b)=="string"){
-_6a(_6b,_64);
-}else{
-if(_6b instanceof Date){
-_6a(_6b.toString(),_64);
-}else{
-if(_6b.nodeType==9){
-_6a("[ XmlDoc ]",_64);
-}else{
-var id="_a"+_a++;
-ids.push(id);
-obs.push(_6b);
-var str="<a id=\""+id+"\" href=\"javascript:void(0);\">"+_6d(_6b)+"</a>";
-_6e(str,_64);
-}
-}
-}
-}
-}
-_23(_64,_63);
-for(i=0;i<ids.length;i++){
-var btn=_8.getElementById(ids[i]);
-if(!btn){
-continue;
-}
-btn.obj=obs[i];
-_9.console._connects.push(_1.connect(btn,"onclick",function(){
-console.openObjectInspector();
-try{
-_22(this.obj);
-}
-catch(e){
-this.obj=e;
-}
-_d.innerHTML="<pre>"+_22(this.obj)+"</pre>";
-}));
-}
-};
-function _68(_6f){
-var _70=[];
-var reg=/((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
-var _71={s:_6a,d:_72,i:_72,f:_73};
-for(var m=reg.exec(_6f);m;m=reg.exec(_6f)){
-var _74=m[8]?m[8]:m[5];
-var _75=_74 in _71?_71[_74]:_76;
-var _77=m[3]?parseInt(m[3]):(m[4]=="."?-1:0);
-_70.push(_6f.substr(0,m[0][0]=="%"?m.index:m.index+1));
-_70.push({appender:_75,precision:_77});
-_6f=_6f.substr(m.index+m[0].length);
-}
-_70.push(_6f);
-return _70;
-};
-function _78(_79){
-function _7a(ch){
-switch(ch){
-case "<":
-return "<";
-case ">":
-return ">";
-case "&":
-return "&";
-case "'":
-return "'";
-case "\"":
-return """;
-}
-return "?";
-};
-return String(_79).replace(/[<>&"']/g,_7a);
-};
-function _7b(_7c){
-try{
-return _7c+"";
-}
-catch(e){
-return null;
-}
-};
-function _6e(_7d,_7e){
-_7e.push(_7b(_7d));
-};
-function _6a(_7f,_80){
-_80.push(_78(_7b(_7f)));
-};
-function _6c(_81,_82){
-_82.push("<span class=\"objectBox-null\">",_78(_7b(_81)),"</span>");
-};
-function _83(_84,_85){
-_85.push("<span class=\"objectBox-string\">"",_78(_7b(_84)),""</span>");
-};
-function _72(_86,_87){
-_87.push("<span class=\"objectBox-number\">",_78(_7b(_86)),"</span>");
-};
-function _73(_88,_89){
-_89.push("<span class=\"objectBox-number\">",_78(_7b(_88)),"</span>");
-};
-function _8a(_8b,_8c){
-_8c.push("<span class=\"objectBox-function\">",_6d(_8b),"</span>");
-};
-function _76(_8d,_8e){
-try{
-if(_8d===undefined){
-_6c("undefined",_8e);
-}else{
-if(_8d===null){
-_6c("null",_8e);
-}else{
-if(typeof _8d=="string"){
-_83(_8d,_8e);
-}else{
-if(typeof _8d=="number"){
-_72(_8d,_8e);
-}else{
-if(typeof _8d=="function"){
-_8a(_8d,_8e);
-}else{
-if(_8d.nodeType==1){
-_8f(_8d,_8e);
-}else{
-if(typeof _8d=="object"){
-_90(_8d,_8e);
-}else{
-_6a(_8d,_8e);
-}
-}
-}
-}
-}
-}
-}
-}
-catch(e){
-}
-};
-function _90(_91,_92){
-var _93=_7b(_91);
-var _94=/\[object (.*?)\]/;
-var m=_94.exec(_93);
-_92.push("<span class=\"objectBox-object\">",m?m[1]:_93,"</span>");
-};
-function _8f(_95,_96){
-_96.push("<span class=\"objectBox-selector\">");
-_96.push("<span class=\"selectorTag\">",_78(_95.nodeName.toLowerCase()),"</span>");
-if(_95.id){
-_96.push("<span class=\"selectorId\">#",_78(_95.id),"</span>");
-}
-if(_95.className){
-_96.push("<span class=\"selectorClass\">.",_78(_95.className),"</span>");
-}
-_96.push("</span>");
-};
-function _26(_97,_98){
-if(_97.nodeType==1){
-_98.push("<div class=\"objectBox-element\">","<<span class=\"nodeTag\">",_97.nodeName.toLowerCase(),"</span>");
-for(var i=0;i<_97.attributes.length;++i){
-var _99=_97.attributes[i];
-if(!_99.specified){
-continue;
-}
-_98.push(" <span class=\"nodeName\">",_99.nodeName.toLowerCase(),"</span>="<span class=\"nodeValue\">",_78(_99.nodeValue),"</span>"");
-}
-if(_97.firstChild){
-_98.push("></div><div class=\"nodeChildren\">");
-for(var _9a=_97.firstChild;_9a;_9a=_9a.nextSibling){
-_26(_9a,_98);
-}
-_98.push("</div><div class=\"objectBox-element\"></<span class=\"nodeTag\">",_97.nodeName.toLowerCase(),"></span></div>");
-}else{
-_98.push("/></div>");
-}
-}else{
-if(_97.nodeType==3){
-_98.push("<div class=\"nodeText\">",_78(_97.nodeValue),"</div>");
-}
-}
-};
-function _46(_9b,_9c,_9d){
-if(document.all){
-_9b.attachEvent("on"+_9c,_9d);
-}else{
-_9b.addEventListener(_9c,_9d,false);
-}
-};
-function _9e(_9f,_a0,_a1){
-if(document.all){
-_9f.detachEvent("on"+_a0,_a1);
-}else{
-_9f.removeEventListener(_a0,_a1,false);
-}
-};
-function _a2(_a3){
-if(document.all){
-_a3.cancelBubble=true;
-}else{
-_a3.stopPropagation();
-}
-};
-function _a4(msg,_a5,_a6){
-var _a7=_a5.lastIndexOf("/");
-var _a8=_a7==-1?_a5:_a5.substr(_a7+1);
-var _a9=["<span class=\"errorMessage\">",msg,"</span>","<div class=\"objectBox-sourceLink\">",_a8," (line ",_a6,")</div>"];
-_23(_a9,"error");
-};
-var _aa=new Date().getTime();
-function _48(_ab){
-var _ac=(new Date()).getTime();
-if(_ac>_aa+200){
-_ab=_1.fixEvent(_ab);
-var _ad=_1.keys;
-var ekc=_ab.keyCode;
-_aa=_ac;
-if(ekc==_ad.F12){
-_31();
-}else{
-if((ekc==_ad.NUMPAD_ENTER||ekc==76)&&_ab.shiftKey&&(_ab.metaKey||_ab.ctrlKey)){
-_36();
-}else{
-return;
-}
-}
-_a2(_ab);
-}
-};
-function _47(e){
-var dk=_1.keys;
-if(e.keyCode==13&&_f.value){
-_ae(_f.value);
-_4c();
-}else{
-if(e.keyCode==27){
-_f.value="";
-}else{
-if(e.keyCode==dk.UP_ARROW||e.charCode==dk.UP_ARROW){
-_af("older");
-}else{
-if(e.keyCode==dk.DOWN_ARROW||e.charCode==dk.DOWN_ARROW){
-_af("newer");
-}else{
-if(e.keyCode==dk.HOME||e.charCode==dk.HOME){
-_b0=1;
-_af("older");
-}else{
-if(e.keyCode==dk.END||e.charCode==dk.END){
-_b0=999999;
-_af("newer");
-}
-}
-}
-}
-}
-}
-};
-var _b0=-1;
-var _b1=null;
-function _ae(_b2){
-var _b3=_b4("firebug_history");
-_b3=(_b3)?_1.fromJson(_b3):[];
-var pos=_1.indexOf(_b3,_b2);
-if(pos!=-1){
-_b3.splice(pos,1);
-}
-_b3.push(_b2);
-_b4("firebug_history",_1.toJson(_b3),30);
-while(_b3.length&&!_b4("firebug_history")){
-_b3.shift();
-_b4("firebug_history",_1.toJson(_b3),30);
-}
-_b1=null;
-_b0=-1;
-};
-function _af(_b5){
-var _b6=_b4("firebug_history");
-_b6=(_b6)?_1.fromJson(_b6):[];
-if(!_b6.length){
-return;
-}
-if(_b1===null){
-_b1=_f.value;
-}
-if(_b0==-1){
-_b0=_b6.length;
-}
-if(_b5=="older"){
---_b0;
-if(_b0<0){
-_b0=0;
-}
-}else{
-if(_b5=="newer"){
-++_b0;
-if(_b0>_b6.length){
-_b0=_b6.length;
-}
-}
-}
-if(_b0==_b6.length){
-_f.value=_b1;
-_b1=null;
-}else{
-_f.value=_b6[_b0];
-}
-};
-function _b4(_b7,_b8){
-var c=document.cookie;
-if(arguments.length==1){
-var _b9=c.match(new RegExp("(?:^|; )"+_b7+"=([^;]*)"));
-return _b9?decodeURIComponent(_b9[1]):undefined;
-}else{
-var d=new Date();
-d.setMonth(d.getMonth()+1);
-document.cookie=_b7+"="+encodeURIComponent(_b8)+((d.toUtcString)?"; expires="+d.toUTCString():"");
-}
-};
-function _ba(it){
-return it&&it instanceof Array||typeof it=="array";
-};
-function _bb(o){
-var cnt=0;
-for(var nm in o){
-cnt++;
-}
-return cnt;
-};
-function _22(o,i,txt,_bc){
-var ind=" \t";
-txt=txt||"";
-i=i||ind;
-_bc=_bc||[];
-var _bd;
-if(o&&o.nodeType==1){
-var _be=[];
-_26(o,_be);
-return _be.join("");
-}
-var br=",\n",cnt=0,_bf=_bb(o);
-if(o instanceof Date){
-return i+o.toString()+br;
-}
-looking:
-for(var nm in o){
-cnt++;
-if(cnt==_bf){
-br="\n";
-}
-if(o[nm]===window||o[nm]===document){
-}else{
-if(o[nm]===null){
-txt+=i+nm+" : NULL"+br;
-}else{
-if(o[nm]&&o[nm].nodeType){
-if(o[nm].nodeType==1){
-}else{
-if(o[nm].nodeType==3){
-txt+=i+nm+" : [ TextNode "+o[nm].data+" ]"+br;
-}
-}
-}else{
-if(typeof o[nm]=="object"&&(o[nm] instanceof String||o[nm] instanceof Number||o[nm] instanceof Boolean)){
-txt+=i+nm+" : "+o[nm]+","+br;
-}else{
-if(o[nm] instanceof Date){
-txt+=i+nm+" : "+o[nm].toString()+br;
-}else{
-if(typeof (o[nm])=="object"&&o[nm]){
-for(var j=0,_c0;_c0=_bc[j];j++){
-if(o[nm]===_c0){
-txt+=i+nm+" : RECURSION"+br;
-continue looking;
-}
-}
-_bc.push(o[nm]);
-_bd=(_ba(o[nm]))?["[","]"]:["{","}"];
-txt+=i+nm+" : "+_bd[0]+"\n";
-txt+=_22(o[nm],i+ind,"",_bc);
-txt+=i+_bd[1]+br;
-}else{
-if(typeof o[nm]=="undefined"){
-txt+=i+nm+" : undefined"+br;
-}else{
-if(nm=="toString"&&typeof o[nm]=="function"){
-var _c1=o[nm]();
-if(typeof _c1=="string"&&_c1.match(/function ?(.*?)\(/)){
-_c1=_78(_6d(o[nm]));
-}
-txt+=i+nm+" : "+_c1+br;
-}else{
-txt+=i+nm+" : "+_78(_6d(o[nm]))+br;
-}
-}
-}
-}
-}
-}
-}
-}
-}
-return txt;
-};
-function _6d(obj){
-var _c2=(obj instanceof Error);
-if(obj.nodeType==1){
-return _78("< "+obj.tagName.toLowerCase()+" id=\""+obj.id+"\" />");
-}
-if(obj.nodeType==3){
-return _78("[TextNode: \""+obj.nodeValue+"\"]");
-}
-var nm=(obj&&(obj.id||obj.name||obj.ObjectID||obj.widgetId));
-if(!_c2&&nm){
-return "{"+nm+"}";
-}
-var _c3=2;
-var _c4=4;
-var cnt=0;
-if(_c2){
-nm="[ Error: "+(obj.message||obj.description||obj)+" ]";
-}else{
-if(_ba(obj)){
-nm="["+obj.slice(0,_c4).join(",");
-if(obj.length>_c4){
-nm+=" ... ("+obj.length+" items)";
-}
-nm+="]";
-}else{
-if(typeof obj=="function"){
-nm=obj+"";
-var reg=/function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/;
-var m=reg.exec(nm);
-if(m){
-if(!m[1]){
-m[1]="function";
-}
-nm=m[1]+m[2];
-}else{
-nm="function()";
-}
-}else{
-if(typeof obj!="object"||typeof obj=="string"){
-nm=obj+"";
-}else{
-nm="{";
-for(var i in obj){
-cnt++;
-if(cnt>_c3){
-break;
-}
-nm+=i+":"+_78(obj[i])+" ";
-}
-nm+="}";
-}
-}
-}
-}
-return nm;
-};
-_46(document,_4("ie")||_4("safari")?"keydown":"keypress",_48);
-if((document.documentElement.getAttribute("debug")=="true")||(_1.config.isDebug)){
-_31(true);
-}
-_1.addOnWindowUnload(function(){
-_9e(document,_4("ie")||_4("safari")?"keydown":"keypress",_48);
-window.onFirebugResize=null;
-window.console=null;
-});
-});
--- a/server/src/main/resources/_firebug/firebug.js.uncompressed.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1191 +0,0 @@
-define("dojo/_firebug/firebug", [
- "../_base/kernel",
- "require",
- "../_base/html",
- "../sniff",
- "../_base/array",
- "../_base/lang",
- "../_base/event",
- "../_base/unload"], function(dojo, require, html, has){
-
- // module:
- // dojo/_firebug/firebug
- // summary:
- // Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox
- // description:
- // Opens a console for logging, debugging, and error messages.
- // Contains partial functionality to Firebug. See function list below.
- //
- // NOTE:
- // Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug.
- // Firebug Lite is included in Dojo by permission from Joe Hewitt
- // If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug
- // functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html
- //
- // NOTE:
- // To test Firebug Lite in Firefox:
- //
- // - FF2: set "console = null" before loading dojo and set djConfig.isDebug=true
- // - FF3: disable Firebug and set djConfig.isDebug=true
- //
- // example:
- // Supports inline objects in object inspector window (only simple trace of dom nodes, however)
- // | console.log("my object", {foo:"bar"})
- // example:
- // Option for console to open in popup window
- // | var djConfig = {isDebug: true, popup:true };
- // example:
- // Option for console height (ignored for popup)
- // | var djConfig = {isDebug: true, debugHeight:100 }
-
-
- var isNewIE = (/Trident/.test(window.navigator.userAgent));
- if(isNewIE){
- // Fixing IE's console
- // IE doesn't insert space between arguments. How annoying.
- var calls = ["log", "info", "debug", "warn", "error"];
- for(var i=0;i<calls.length;i++){
- var m = calls[i];
- if(!console[m] ||console[m]._fake){
- // IE9 doesn't have console.debug method, a fake one is added later
- continue;
- }
- var n = "_"+calls[i];
- console[n] = console[m];
- console[m] = (function(){
- var type = n;
- return function(){
- console[type](Array.prototype.join.call(arguments, " "));
- };
- })();
- }
- // clear the console on load. This is more than a convenience - too many logs crashes it.
- // If closed it throws an error
- try{ console.clear(); }catch(e){}
- }
-
- if(
- has("ff") || // Firefox has Firebug
- has("chrome") || // Chrome 3+ has a console
- has("safari") || // Safari 4 has a console
- isNewIE || // Has the new IE console
- window.firebug || // Testing for mozilla firebug lite
- (typeof console != "undefined" && console.firebug) || //The firebug console
- dojo.config.useCustomLogger || // Allow custom loggers
- has("air") // isDebug triggers AIRInsector, not Firebug
- ){
- return;
- }
-
- // don't build firebug in iframes
- try{
- if(window != window.parent){
- // but if we've got a parent logger, connect to it
- if(window.parent["console"]){
- window.console = window.parent.console;
- }
- return;
- }
- }catch(e){/*squelch*/}
-
- // ***************************************************************************
- // Placing these variables before the functions that use them to avoid a
- // shrinksafe bug where variable renaming does not happen correctly otherwise.
-
- // most of the objects in this script are run anonomously
- var _firebugDoc = document;
- var _firebugWin = window;
- var __consoleAnchorId__ = 0;
-
- var consoleFrame = null;
- var consoleBody = null;
- var consoleObjectInspector = null;
- var fireBugTabs = null;
- var commandLine = null;
- var consoleToolbar = null;
-
- var frameVisible = false;
- var messageQueue = [];
- var groupStack = [];
- var timeMap = {};
- var countMap = {};
-
- var consoleDomInspector = null;
- var _inspectionMoveConnection;
- var _inspectionClickConnection;
- var _inspectionEnabled = false;
- var _inspectionTimer = null;
- var _inspectTempNode = document.createElement("div");
-
-
- var _inspectCurrentNode;
- var _restoreBorderStyle;
-
- // ***************************************************************************
-
- window.console = {
- _connects: [],
- log: function(){
- // summary:
- // Sends arguments to console.
- logFormatted(arguments, "");
- },
-
- debug: function(){
- // summary:
- // Sends arguments to console. Missing finctionality to show script line of trace.
- logFormatted(arguments, "debug");
- },
-
- info: function(){
- // summary:
- // Sends arguments to console, highlighted with (I) icon.
- logFormatted(arguments, "info");
- },
-
- warn: function(){
- // summary:
- // Sends warning arguments to console, highlighted with (!) icon and blue style.
- logFormatted(arguments, "warning");
- },
-
- error: function(){
- // summary:
- // Sends error arguments (object) to console, highlighted with (X) icon and yellow style
- // NEW: error object now displays in object inspector
- logFormatted(arguments, "error");
- },
-
- assert: function(truth, message){
- // summary:
- // Tests for true. Throws exception if false.
- if(!truth){
- var args = [];
- for(var i = 1; i < arguments.length; ++i){
- args.push(arguments[i]);
- }
-
- logFormatted(args.length ? args : ["Assertion Failure"], "error");
- throw message ? message : "Assertion Failure";
- }
- },
-
- dir: function(obj){
- var str = printObject( obj );
- str = str.replace(/\n/g, "<br />");
- str = str.replace(/\t/g, " ");
- logRow([str], "dir");
- },
-
- dirxml: function(node){
- var html = [];
- appendNode(node, html);
- logRow(html, "dirxml");
- },
-
- group: function(){
- // summary:
- // collects log messages into a group, starting with this call and ending with
- // groupEnd(). Missing collapse functionality
- logRow(arguments, "group", pushGroup);
- },
-
- groupEnd: function(){
- // summary:
- // Closes group. See above
- logRow(arguments, "", popGroup);
- },
-
- time: function(name){
- // summary:
- // Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title);
- // example:
- // | console.time("load");
- // | console.time("myFunction");
- // | console.timeEnd("load");
- // | console.timeEnd("myFunction");
- timeMap[name] = new Date().getTime();
- },
-
- timeEnd: function(name){
- // summary:
- // See above.
- if(name in timeMap){
- var delta = (new Date()).getTime() - timeMap[name];
- logFormatted([name+ ":", delta+"ms"]);
- delete timeMap[name];
- }
- },
-
- count: function(name){
- // summary:
- // Not supported
- if(!countMap[name]) countMap[name] = 0;
- countMap[name]++;
- logFormatted([name+": "+countMap[name]]);
- },
-
- trace: function(_value){
- var stackAmt = _value || 3;
- var f = console.trace.caller; //function that called trace
- console.log(">>> console.trace(stack)");
- for(var i=0;i<stackAmt;i++){
- var func = f.toString();
- var args=[];
- for (var a = 0; a < f.arguments.length; a++){
- args.push(f.arguments[a]);
- }
- if(f.arguments.length){
- console.dir({"function":func, "arguments":args});
- }else{
- console.dir({"function":func});
- }
-
- f = f.caller;
- }
- },
-
- profile: function(){
- // summary:
- // Not supported
- this.warn(["profile() not supported."]);
- },
-
- profileEnd: function(){ },
-
- clear: function(){
- // summary:
- // Clears message console. Do not call this directly
- if(consoleBody){
- while(consoleBody.childNodes.length){
- dojo.destroy(consoleBody.firstChild);
- }
- }
- dojo.forEach(this._connects,dojo.disconnect);
- },
-
- open: function(){
- // summary:
- // Opens message console. Do not call this directly
- toggleConsole(true);
- },
-
- close: function(){
- // summary:
- // Closes message console. Do not call this directly
- if(frameVisible){
- toggleConsole();
- }
- },
- _restoreBorder: function(){
- if(_inspectCurrentNode){
- _inspectCurrentNode.style.border = _restoreBorderStyle;
- }
- },
- openDomInspector: function(){
- _inspectionEnabled = true;
- consoleBody.style.display = "none";
- consoleDomInspector.style.display = "block";
- consoleObjectInspector.style.display = "none";
- document.body.style.cursor = "pointer";
- _inspectionMoveConnection = dojo.connect(document, "mousemove", function(evt){
- if(!_inspectionEnabled){ return; }
- if(!_inspectionTimer){
- _inspectionTimer = setTimeout(function(){ _inspectionTimer = null; }, 50);
- }else{
- return;
- }
- var node = evt.target;
- if(node && (_inspectCurrentNode !== node)){
- var parent = true;
-
- console._restoreBorder();
- var html = [];
- appendNode(node, html);
- consoleDomInspector.innerHTML = html.join("");
-
- _inspectCurrentNode = node;
- _restoreBorderStyle = _inspectCurrentNode.style.border;
- _inspectCurrentNode.style.border = "#0000FF 1px solid";
- }
- });
- setTimeout(function(){
- _inspectionClickConnection = dojo.connect(document, "click", function(evt){
- document.body.style.cursor = "";
- _inspectionEnabled = !_inspectionEnabled;
- dojo.disconnect(_inspectionClickConnection);
- // console._restoreBorder();
- });
- }, 30);
- },
- _closeDomInspector: function(){
- document.body.style.cursor = "";
- dojo.disconnect(_inspectionMoveConnection);
- dojo.disconnect(_inspectionClickConnection);
- _inspectionEnabled = false;
- console._restoreBorder();
- },
- openConsole:function(){
- // summary:
- // Closes object inspector and opens message console. Do not call this directly
- consoleBody.style.display = "block";
- consoleDomInspector.style.display = "none";
- consoleObjectInspector.style.display = "none";
- console._closeDomInspector();
- },
- openObjectInspector:function(){
- consoleBody.style.display = "none";
- consoleDomInspector.style.display = "none";
- consoleObjectInspector.style.display = "block";
- console._closeDomInspector();
- },
- recss: function(){
- // this is placed in dojo since the console is most likely
- // in another window and dojo is easilly accessible
- var i,a,s;a=document.getElementsByTagName('link');
- for(i=0;i<a.length;i++){
- s=a[i];
- if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href){
- var h=s.href.replace(/(&|%5C?)forceReload=\d+/,'');
- s.href=h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+new Date().valueOf();
- }
- }
- }
- };
-
- // ***************************************************************************
-
- function toggleConsole(forceOpen){
- frameVisible = forceOpen || !frameVisible;
- if(consoleFrame){
- consoleFrame.style.display = frameVisible ? "block" : "none";
- }
- }
-
- function focusCommandLine(){
- toggleConsole(true);
- if(commandLine){
- commandLine.focus();
- }
- }
-
- function openWin(x,y,w,h){
- var win = window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
- if(!win){
- var msg = "Firebug Lite could not open a pop-up window, most likely because of a blocker.\n" +
- "Either enable pop-ups for this domain, or change the djConfig to popup=false.";
- alert(msg);
- }
- createResizeHandler(win);
- var newDoc=win.document;
- //Safari needs an HTML height
- var HTMLstring= '<html style="height:100%;"><head><title>Firebug Lite</title></head>\n' +
- '<body bgColor="#ccc" style="height:97%;" onresize="opener.onFirebugResize()">\n' +
- '<div id="fb"></div>' +
- '</body></html>';
-
- newDoc.write(HTMLstring);
- newDoc.close();
- return win;
- }
-
- function createResizeHandler(wn){
- // summary:
- // Creates handle for onresize window. Called from script in popup's body tag (so that it will work with IE).
- //
-
- var d = new Date();
- d.setTime(d.getTime()+(60*24*60*60*1000)); // 60 days
- d = d.toUTCString();
-
- var dc = wn.document,
- getViewport;
-
- if (wn.innerWidth){
- getViewport = function(){
- return{w:wn.innerWidth, h:wn.innerHeight};
- };
- }else if (dc.documentElement && dc.documentElement.clientWidth){
- getViewport = function(){
- return{w:dc.documentElement.clientWidth, h:dc.documentElement.clientHeight};
- };
- }else if (dc.body){
- getViewport = function(){
- return{w:dc.body.clientWidth, h:dc.body.clientHeight};
- };
- }
-
-
- window.onFirebugResize = function(){
-
- //resize the height of the console log body
- layout(getViewport().h);
-
- clearInterval(wn._firebugWin_resize);
- wn._firebugWin_resize = setTimeout(function(){
- var x = wn.screenLeft,
- y = wn.screenTop,
- w = wn.outerWidth || wn.document.body.offsetWidth,
- h = wn.outerHeight || wn.document.body.offsetHeight;
-
- document.cookie = "_firebugPosition=" + [x,y,w,h].join(",") + "; expires="+d+"; path=/";
-
- }, 5000); //can't capture window.onMove - long timeout gives better chance of capturing a resize, then the move
-
- };
- }
-
-
- /*****************************************************************************/
-
-
- function createFrame(){
- if(consoleFrame){
- return;
- }
- toggleConsole(true);
- if(dojo.config.popup){
- var containerHeight = "100%";
- var cookieMatch = document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
- var p = cookieMatch ? cookieMatch[1].split(",") : [2,2,320,480];
-
- _firebugWin = openWin(p[0],p[1],p[2],p[3]); // global
- _firebugDoc = _firebugWin.document; // global
-
- dojo.config.debugContainerId = 'fb';
-
- // connecting popup
- _firebugWin.console = window.console;
- _firebugWin.dojo = window.dojo;
- }else{
- _firebugDoc = document;
- containerHeight = (dojo.config.debugHeight || 300) + "px";
- }
-
- var styleElement = _firebugDoc.createElement("link");
- styleElement.href = require.toUrl("./firebug.css");
- styleElement.rel = "stylesheet";
- styleElement.type = "text/css";
- var styleParent = _firebugDoc.getElementsByTagName("head");
- if(styleParent){
- styleParent = styleParent[0];
- }
- if(!styleParent){
- styleParent = _firebugDoc.getElementsByTagName("html")[0];
- }
- if(has("ie")){
- window.setTimeout(function(){ styleParent.appendChild(styleElement); }, 0);
- }else{
- styleParent.appendChild(styleElement);
- }
-
- if(dojo.config.debugContainerId){
- consoleFrame = _firebugDoc.getElementById(dojo.config.debugContainerId);
- }
- if(!consoleFrame){
- consoleFrame = _firebugDoc.createElement("div");
- _firebugDoc.body.appendChild(consoleFrame);
- }
- consoleFrame.className += " firebug";
- consoleFrame.id = "firebug";
- consoleFrame.style.height = containerHeight;
- consoleFrame.style.display = (frameVisible ? "block" : "none");
-
- var buildLink = function(label, title, method, _class){
- return '<li class="'+_class+'"><a href="javascript:void(0);" onclick="console.'+ method +'(); return false;" title="'+title+'">'+label+'</a></li>';
- };
- consoleFrame.innerHTML =
- '<div id="firebugToolbar">'
- + ' <ul id="fireBugTabs" class="tabs">'
-
- + buildLink("Clear", "Remove All Console Logs", "clear", "")
- + buildLink("ReCSS", "Refresh CSS without reloading page", "recss", "")
-
- + buildLink("Console", "Show Console Logs", "openConsole", "gap")
- + buildLink("DOM", "Show DOM Inspector", "openDomInspector", "")
- + buildLink("Object", "Show Object Inspector", "openObjectInspector", "")
- + ((dojo.config.popup) ? "" : buildLink("Close", "Close the console", "close", "gap"))
-
- + ' </ul>'
- + '</div>'
- + '<input type="text" id="firebugCommandLine" />'
- + '<div id="firebugLog"></div>'
- + '<div id="objectLog" style="display:none;">Click on an object in the Log display</div>'
- + '<div id="domInspect" style="display:none;">Hover over HTML elements in the main page. Click to hold selection.</div>';
-
-
- consoleToolbar = _firebugDoc.getElementById("firebugToolbar");
-
- commandLine = _firebugDoc.getElementById("firebugCommandLine");
- addEvent(commandLine, "keydown", onCommandLineKeyDown);
-
- addEvent(_firebugDoc, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
-
- consoleBody = _firebugDoc.getElementById("firebugLog");
- consoleObjectInspector = _firebugDoc.getElementById("objectLog");
- consoleDomInspector = _firebugDoc.getElementById("domInspect");
- fireBugTabs = _firebugDoc.getElementById("fireBugTabs");
- layout();
- flush();
- }
-
- dojo.addOnLoad(createFrame);
-
- function clearFrame(){
- _firebugDoc = null;
-
- if(_firebugWin.console){
- _firebugWin.console.clear();
- }
- _firebugWin = null;
- consoleFrame = null;
- consoleBody = null;
- consoleObjectInspector = null;
- consoleDomInspector = null;
- commandLine = null;
- messageQueue = [];
- groupStack = [];
- timeMap = {};
- }
-
-
- function evalCommandLine(){
- var text = commandLine.value;
- commandLine.value = "";
-
- logRow(["> ", text], "command");
-
- var value;
- try{
- value = eval(text);
- }catch(e){
- console.debug(e); // put exception on the console
- }
-
- console.log(value);
- }
-
- function layout(h){
- var tHeight = 25; //consoleToolbar.offsetHeight; // tab style not ready on load - throws off layout
- var height = h ?
- h - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" :
- (consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px";
-
- consoleBody.style.top = tHeight + "px";
- consoleBody.style.height = height;
- consoleObjectInspector.style.height = height;
- consoleObjectInspector.style.top = tHeight + "px";
- consoleDomInspector.style.height = height;
- consoleDomInspector.style.top = tHeight + "px";
- commandLine.style.bottom = 0;
-
- dojo.addOnWindowUnload(clearFrame);
- }
-
- function logRow(message, className, handler){
- if(consoleBody){
- writeMessage(message, className, handler);
- }else{
- messageQueue.push([message, className, handler]);
- }
- }
-
- function flush(){
- var queue = messageQueue;
- messageQueue = [];
-
- for(var i = 0; i < queue.length; ++i){
- writeMessage(queue[i][0], queue[i][1], queue[i][2]);
- }
- }
-
- function writeMessage(message, className, handler){
- var isScrolledToBottom =
- consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
-
- handler = handler||writeRow;
-
- handler(message, className);
-
- if(isScrolledToBottom){
- consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
- }
- }
-
- function appendRow(row){
- var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
- container.appendChild(row);
- }
-
- function writeRow(message, className){
- var row = consoleBody.ownerDocument.createElement("div");
- row.className = "logRow" + (className ? " logRow-"+className : "");
- row.innerHTML = message.join("");
- appendRow(row);
- }
-
- function pushGroup(message, className){
- logFormatted(message, className);
-
- //var groupRow = consoleBody.ownerDocument.createElement("div");
- //groupRow.className = "logGroup";
- var groupRowBox = consoleBody.ownerDocument.createElement("div");
- groupRowBox.className = "logGroupBox";
- //groupRow.appendChild(groupRowBox);
- appendRow(groupRowBox);
- groupStack.push(groupRowBox);
- }
-
- function popGroup(){
- groupStack.pop();
- }
-
- // ***************************************************************************
-
- function logFormatted(objects, className){
- var html = [];
-
- var format = objects[0];
- var objIndex = 0;
-
- if(typeof(format) != "string"){
- format = "";
- objIndex = -1;
- }
-
- var parts = parseFormat(format);
-
- for(var i = 0; i < parts.length; ++i){
- var part = parts[i];
- if(part && typeof part == "object"){
- part.appender(objects[++objIndex], html);
- }else{
- appendText(part, html);
- }
- }
-
-
- var ids = [];
- var obs = [];
- for(i = objIndex+1; i < objects.length; ++i){
- appendText(" ", html);
-
- var object = objects[i];
- if(object === undefined || object === null ){
- appendNull(object, html);
-
- }else if(typeof(object) == "string"){
- appendText(object, html);
-
- }else if(object instanceof Date){
- appendText(object.toString(), html);
-
- }else if(object.nodeType == 9){
- appendText("[ XmlDoc ]", html);
-
- }else{
- // Create link for object inspector
- // need to create an ID for this link, since it is currently text
- var id = "_a" + __consoleAnchorId__++;
- ids.push(id);
- // need to save the object, so the arrays line up
- obs.push(object);
- var str = '<a id="'+id+'" href="javascript:void(0);">'+getObjectAbbr(object)+'</a>';
-
- appendLink( str , html);
- }
- }
-
- logRow(html, className);
-
- // Now that the row is inserted in the DOM, loop through all of the links that were just created
- for(i=0; i<ids.length; i++){
- var btn = _firebugDoc.getElementById(ids[i]);
- if(!btn){ continue; }
-
- // store the object in the dom btn for reference later
- // avoid parsing these objects unless necessary
- btn.obj = obs[i];
-
- _firebugWin.console._connects.push(dojo.connect(btn, "onclick", function(){
-
- console.openObjectInspector();
-
- try{
- printObject(this.obj);
- }catch(e){
- this.obj = e;
- }
- consoleObjectInspector.innerHTML = "<pre>" + printObject( this.obj ) + "</pre>";
- }));
- }
- }
-
- function parseFormat(format){
- var parts = [];
-
- var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
- var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
-
- for(var m = reg.exec(format); m; m = reg.exec(format)){
- var type = m[8] ? m[8] : m[5];
- var appender = type in appenderMap ? appenderMap[type] : appendObject;
- var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
-
- parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
- parts.push({appender: appender, precision: precision});
-
- format = format.substr(m.index+m[0].length);
- }
-
- parts.push(format);
-
- return parts;
- }
-
- function escapeHTML(value){
- function replaceChars(ch){
- switch(ch){
- case "<":
- return "<";
- case ">":
- return ">";
- case "&":
- return "&";
- case "'":
- return "'";
- case '"':
- return """;
- }
- return "?";
- }
- return String(value).replace(/[<>&"']/g, replaceChars);
- }
-
- function objectToString(object){
- try{
- return object+"";
- }catch(e){
- return null;
- }
- }
-
- // ***************************************************************************
- function appendLink(object, html){
- // needed for object links - no HTML escaping
- html.push( objectToString(object) );
- }
-
- function appendText(object, html){
- html.push(escapeHTML(objectToString(object)));
- }
-
- function appendNull(object, html){
- html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
- }
-
- function appendString(object, html){
- html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)),
- '"</span>');
- }
-
- function appendInteger(object, html){
- html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
- }
-
- function appendFloat(object, html){
- html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
- }
-
- function appendFunction(object, html){
- html.push('<span class="objectBox-function">', getObjectAbbr(object), '</span>');
- }
-
- function appendObject(object, html){
- try{
- if(object === undefined){
- appendNull("undefined", html);
- }else if(object === null){
- appendNull("null", html);
- }else if(typeof object == "string"){
- appendString(object, html);
- }else if(typeof object == "number"){
- appendInteger(object, html);
- }else if(typeof object == "function"){
- appendFunction(object, html);
- }else if(object.nodeType == 1){
- appendSelector(object, html);
- }else if(typeof object == "object"){
- appendObjectFormatted(object, html);
- }else{
- appendText(object, html);
- }
- }catch(e){
- /* squelch */
- }
- }
-
- function appendObjectFormatted(object, html){
- var text = objectToString(object);
- var reObject = /\[object (.*?)\]/;
-
- var m = reObject.exec(text);
- html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>');
- }
-
- function appendSelector(object, html){
- html.push('<span class="objectBox-selector">');
-
- html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
- if(object.id){
- html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
- }
- if(object.className){
- html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
- }
-
- html.push('</span>');
- }
-
- function appendNode(node, html){
- if(node.nodeType == 1){
- html.push(
- '<div class="objectBox-element">',
- '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
-
- for(var i = 0; i < node.attributes.length; ++i){
- var attr = node.attributes[i];
- if(!attr.specified){ continue; }
-
- html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(),
- '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue),
- '</span>"');
- }
-
- if(node.firstChild){
- html.push('></div><div class="nodeChildren">');
-
- for(var child = node.firstChild; child; child = child.nextSibling){
- appendNode(child, html);
- }
-
- html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
- node.nodeName.toLowerCase(), '></span></div>');
- }else{
- html.push('/></div>');
- }
- }else if (node.nodeType == 3){
- html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
- '</div>');
- }
- }
-
- // ***************************************************************************
-
- function addEvent(object, name, handler){
- if(document.all){
- object.attachEvent("on"+name, handler);
- }else{
- object.addEventListener(name, handler, false);
- }
- }
-
- function removeEvent(object, name, handler){
- if(document.all){
- object.detachEvent("on"+name, handler);
- }else{
- object.removeEventListener(name, handler, false);
- }
- }
-
- function cancelEvent(event){
- if(document.all){
- event.cancelBubble = true;
- }else{
- event.stopPropagation();
- }
- }
-
- function onError(msg, href, lineNo){
- var lastSlash = href.lastIndexOf("/");
- var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
-
- var html = [
- '<span class="errorMessage">', msg, '</span>',
- '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
- ];
-
- logRow(html, "error");
- }
-
-
- //After converting to div instead of iframe, now getting two keydowns right away in IE 6.
- //Make sure there is a little bit of delay.
- var onKeyDownTime = new Date().getTime();
-
- function onKeyDown(event){
- var timestamp = (new Date()).getTime();
- if(timestamp > onKeyDownTime + 200){
- event = dojo.fixEvent(event);
- var keys = dojo.keys;
- var ekc = event.keyCode;
- onKeyDownTime = timestamp;
- if(ekc == keys.F12){
- toggleConsole();
- }else if(
- (ekc == keys.NUMPAD_ENTER || ekc == 76) &&
- event.shiftKey &&
- (event.metaKey || event.ctrlKey)
- ){
- focusCommandLine();
- }else{
- return;
- }
- cancelEvent(event);
- }
- }
-
- function onCommandLineKeyDown(e){
- var dk = dojo.keys;
- if(e.keyCode == 13 && commandLine.value){
- addToHistory(commandLine.value);
- evalCommandLine();
- }else if(e.keyCode == 27){
- commandLine.value = "";
- }else if(e.keyCode == dk.UP_ARROW || e.charCode == dk.UP_ARROW){
- navigateHistory("older");
- }else if(e.keyCode == dk.DOWN_ARROW || e.charCode == dk.DOWN_ARROW){
- navigateHistory("newer");
- }else if(e.keyCode == dk.HOME || e.charCode == dk.HOME){
- historyPosition = 1;
- navigateHistory("older");
- }else if(e.keyCode == dk.END || e.charCode == dk.END){
- historyPosition = 999999;
- navigateHistory("newer");
- }
- }
-
- var historyPosition = -1;
- var historyCommandLine = null;
-
- function addToHistory(value){
- var history = cookie("firebug_history");
- history = (history) ? dojo.fromJson(history) : [];
- var pos = dojo.indexOf(history, value);
- if (pos != -1){
- history.splice(pos, 1);
- }
- history.push(value);
- cookie("firebug_history", dojo.toJson(history), 30);
- while(history.length && !cookie("firebug_history")){
- history.shift();
- cookie("firebug_history", dojo.toJson(history), 30);
- }
- historyCommandLine = null;
- historyPosition = -1;
- }
-
- function navigateHistory(direction){
- var history = cookie("firebug_history");
- history = (history) ? dojo.fromJson(history) : [];
- if(!history.length){
- return;
- }
-
- if(historyCommandLine === null){
- historyCommandLine = commandLine.value;
- }
-
- if(historyPosition == -1){
- historyPosition = history.length;
- }
-
- if(direction == "older"){
- --historyPosition;
- if(historyPosition < 0){
- historyPosition = 0;
- }
- }else if(direction == "newer"){
- ++historyPosition;
- if(historyPosition > history.length){
- historyPosition = history.length;
- }
- }
-
- if(historyPosition == history.length){
- commandLine.value = historyCommandLine;
- historyCommandLine = null;
- }else{
- commandLine.value = history[historyPosition];
- }
- }
-
- function cookie(name, value){
- var c = document.cookie;
- if(arguments.length == 1){
- var matches = c.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
- return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined
- }else{
- var d = new Date();
- d.setMonth(d.getMonth()+1);
- document.cookie = name + "=" + encodeURIComponent(value) + ((d.toUtcString) ? "; expires=" + d.toUTCString() : "");
- }
- }
-
- function isArray(it){
- return it && it instanceof Array || typeof it == "array";
- }
-
- //***************************************************************************************************
- // Print Object Helpers
- function objectLength(o){
- var cnt = 0;
- for(var nm in o){
- cnt++;
- }
- return cnt;
- }
-
- function printObject(o, i, txt, used){
- // Recursively trace object, indenting to represent depth for display in object inspector
- var ind = " \t";
- txt = txt || "";
- i = i || ind;
- used = used || [];
- var opnCls;
-
- if(o && o.nodeType == 1){
- var html = [];
- appendNode(o, html);
- return html.join("");
- }
-
- var br=",\n", cnt = 0, length = objectLength(o);
-
- if(o instanceof Date){
- return i + o.toString() + br;
- }
- looking:
- for(var nm in o){
- cnt++;
- if(cnt==length){br = "\n";}
- if(o[nm] === window || o[nm] === document){
- // do nothing
- }else if(o[nm] === null){
- txt += i+nm + " : NULL" + br;
- }else if(o[nm] && o[nm].nodeType){
- if(o[nm].nodeType == 1){
- //txt += i+nm + " : < "+o[nm].tagName+" id=\""+ o[nm].id+"\" />" + br;
- }else if(o[nm].nodeType == 3){
- txt += i+nm + " : [ TextNode "+o[nm].data + " ]" + br;
- }
-
- }else if(typeof o[nm] == "object" && (o[nm] instanceof String || o[nm] instanceof Number || o[nm] instanceof Boolean)){
- txt += i+nm + " : " + o[nm] + "," + br;
-
- }else if(o[nm] instanceof Date){
- txt += i+nm + " : " + o[nm].toString() + br;
-
- }else if(typeof(o[nm]) == "object" && o[nm]){
- for(var j = 0, seen; seen = used[j]; j++){
- if(o[nm] === seen){
- txt += i+nm + " : RECURSION" + br;
- continue looking;
- }
- }
- used.push(o[nm]);
-
- opnCls = (isArray(o[nm]))?["[","]"]:["{","}"];
- txt += i+nm +" : " + opnCls[0] + "\n";//non-standard break, (no comma)
- txt += printObject(o[nm], i+ind, "", used);
- txt += i + opnCls[1] + br;
-
- }else if(typeof o[nm] == "undefined"){
- txt += i+nm + " : undefined" + br;
- }else if(nm == "toString" && typeof o[nm] == "function"){
- var toString = o[nm]();
- if(typeof toString == "string" && toString.match(/function ?(.*?)\(/)){
- toString = escapeHTML(getObjectAbbr(o[nm]));
- }
- txt += i+nm +" : " + toString + br;
- }else{
- txt += i+nm +" : "+ escapeHTML(getObjectAbbr(o[nm])) + br;
- }
- }
- return txt;
- }
-
- function getObjectAbbr(obj){
- // Gets an abbreviation of an object for display in log
- // X items in object, including id
- // X items in an array
- // TODO: Firebug Sr. actually goes by char count
- var isError = (obj instanceof Error);
- if(obj.nodeType == 1){
- return escapeHTML('< '+obj.tagName.toLowerCase()+' id=\"'+ obj.id+ '\" />');
- }
- if(obj.nodeType == 3){
- return escapeHTML('[TextNode: "'+obj.nodeValue+'"]');
- }
- var nm = (obj && (obj.id || obj.name || obj.ObjectID || obj.widgetId));
- if(!isError && nm){ return "{"+nm+"}"; }
-
- var obCnt = 2;
- var arCnt = 4;
- var cnt = 0;
-
- if(isError){
- nm = "[ Error: "+(obj.message || obj.description || obj)+" ]";
- }else if(isArray(obj)){
- nm = "[" + obj.slice(0,arCnt).join(",");
- if(obj.length > arCnt){
- nm += " ... ("+obj.length+" items)";
- }
- nm += "]";
- }else if(typeof obj == "function"){
- nm = obj + "";
- var reg = /function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/;
- var m = reg.exec(nm);
- if(m){
- if(!m[1]){
- m[1] = "function";
- }
- nm = m[1] + m[2];
- }else{
- nm = "function()";
- }
- }else if(typeof obj != "object" || typeof obj == "string"){
- nm = obj + "";
- }else{
- nm = "{";
- for(var i in obj){
- cnt++;
- if(cnt > obCnt){ break; }
- nm += i+":"+escapeHTML(obj[i])+" ";
- }
- nm+="}";
- }
-
- return nm;
- }
-
- //*************************************************************************************
-
- //window.onerror = onError;
-
- addEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
-
- if( (document.documentElement.getAttribute("debug") == "true")||
- (dojo.config.isDebug)
- ){
- toggleConsole(true);
- }
-
- dojo.addOnWindowUnload(function(){
- // Erase the globals and event handlers I created, to prevent spurious leak warnings
- removeEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
- window.onFirebugResize = null;
- window.console = null;
- });
-
-});
Binary file server/src/main/resources/_firebug/infoIcon.png has changed
Binary file server/src/main/resources/_firebug/tab_lft_norm.png has changed
Binary file server/src/main/resources/_firebug/tab_lft_over.png has changed
Binary file server/src/main/resources/_firebug/tab_rgt_norm.png has changed
Binary file server/src/main/resources/_firebug/tab_rgt_over.png has changed
Binary file server/src/main/resources/_firebug/warningIcon.png has changed
--- a/server/src/main/resources/log4j.xml Fri Dec 21 16:22:08 2012 +0100
+++ b/server/src/main/resources/log4j.xml Mon Dec 31 13:37:31 2012 +0100
@@ -5,15 +5,40 @@
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n"/>
</layout>
- </appender>
+ </appender>
<logger name="org.iri_research.renkan">
<level value="DEBUG" />
</logger>
+ <logger name="org.eclipse.jetty.util.log">
+ <level value="INFO" />
+ </logger>
+ <logger name="org.springframework.beans.factory">
+ <level value="DEBUG" />
+ </logger>
<root>
<priority value ="WARN" />
<appender-ref ref="console" />
</root>
+ <!--
+log4j.rootCategory=INFO, stdout
+
+log4j.appender.stdout=org.springframework.data.document.mongodb.log4j.MongoLog4jAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
+log4j.appender.stdout.host = localhost
+log4j.appender.stdout.port = 27017
+log4j.appender.stdout.database = logs
+log4j.appender.stdout.collectionPattern = %X{year}%X{month}
+log4j.appender.stdout.applicationId = my.application
+log4j.appender.stdout.warnOrHigherWriteConcern = FSYNC_SAFE
+
+log4j.category.org.apache.activemq=ERROR
+log4j.category.org.springframework.batch=DEBUG
+log4j.category.org.springframework.data.document.mongodb=DEBUG
+log4j.category.org.springframework.transaction=INFO
+-->
-</log4j:configuration>
\ No newline at end of file
+</log4j:configuration>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/web-resources/_firebug/LICENSE Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,37 @@
+License Disclaimer:
+
+All contents of this directory are Copyright (c) the Dojo Foundation, with the
+following exceptions:
+-------------------------------------------------------------------------------
+
+firebug.html, firebug.js, errIcon.png, infoIcon.png, warningIcon.png:
+ * Copyright (c) 2006-2007, Joe Hewitt, All rights reserved.
+ Distributed under the terms of the BSD License (see below)
+
+-------------------------------------------------------------------------------
+
+Copyright (c) 2006-2007, Joe Hewitt
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the Dojo Foundation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Binary file server/src/main/web-resources/_firebug/errorIcon.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/web-resources/_firebug/firebug.css Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,208 @@
+.firebug {
+ margin: 0;
+ background:#fff;
+ font-family: Lucida Grande, Tahoma, sans-serif;
+ font-size: 11px;
+ overflow: hidden;
+ border: 1px solid black;
+ position: relative;
+}
+.firebug a {
+ text-decoration: none;
+}
+.firebug a:hover {
+ text-decoration: underline;
+}
+.firebug a:visited{
+ color:#0000FF;
+}
+.firebug #firebugToolbar {
+ height: 18px;
+ line-height:18px;
+ border-top: 1px solid ThreeDHighlight;
+ border-bottom: 1px solid ThreeDShadow;
+ padding: 2px 6px;
+
+ background:#f0f0f0;
+}
+.firebug #firebugLog, .firebug #objectLog {
+ overflow: auto;
+ position: absolute;
+ left: 0;
+ width: 100%;
+}
+#objectLog{
+ overflow:scroll;
+ height:258px;
+}
+.firebug #firebugCommandLine {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 18px;
+ border: none;
+ border-top: 1px solid ThreeDShadow;
+}
+.firebug .logRow {
+ position: relative;
+ border-bottom: 1px solid #D7D7D7;
+ padding: 2px 4px 1px 6px;
+ background-color: #FFFFFF;
+}
+.firebug .logRow-command {
+ font-family: Monaco, monospace;
+ color: blue;
+}
+.firebug .objectBox-null {
+ padding: 0 2px;
+ border: 1px solid #666666;
+ background-color: #888888;
+ color: #FFFFFF;
+}
+.firebug .objectBox-string {
+ font-family: Monaco, monospace;
+ color: red;
+ white-space: pre;
+}
+.firebug .objectBox-number {
+ color: #000088;
+}
+.firebug .objectBox-function {
+ font-family: Monaco, monospace;
+ color: DarkGreen;
+}
+.firebug .objectBox-object {
+ color: DarkGreen;
+ font-weight: bold;
+}
+.firebug .logRow-info,
+.firebug .logRow-error,
+.firebug .logRow-warning
+ {
+ background: #00FFFF no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+.firebug .logRow-info {
+ background: #FFF url(infoIcon.png) no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+.firebug .logRow-warning {
+
+ background: #00FFFF url(warningIcon.png) no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+.firebug .logRow-error {
+ background: LightYellow url(errorIcon.png) no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+.firebug .errorMessage {
+ vertical-align: top;
+ color: #FF0000;
+}
+.firebug .objectBox-sourceLink {
+ position: absolute;
+ right: 4px;
+ top: 2px;
+ padding-left: 8px;
+ font-family: Lucida Grande, sans-serif;
+ font-weight: bold;
+ color: #0000FF;
+}
+.firebug .logRow-group {
+ background: #EEEEEE;
+ border-bottom: none;
+}
+.firebug .logGroup {
+ background: #EEEEEE;
+}
+.firebug .logGroupBox {
+ margin-left: 24px;
+ border-top: 1px solid #D7D7D7;
+ border-left: 1px solid #D7D7D7;
+}
+.firebug .selectorTag,
+.firebug .selectorId,
+.firebug .selectorClass {
+ font-family: Monaco, monospace;
+ font-weight: normal;
+}
+.firebug .selectorTag {
+ color: #0000FF;
+}
+.firebug .selectorId {
+ color: DarkBlue;
+}
+.firebug .selectorClass {
+ color: red;
+}
+.firebug .objectBox-element {
+ font-family: Monaco, monospace;
+ color: #000088;
+}
+.firebug .nodeChildren {
+ margin-left: 16px;
+}
+.firebug .nodeTag {
+ color: blue;
+}
+.firebug .nodeValue {
+ color: #FF0000;
+ font-weight: normal;
+}
+.firebug .nodeText,
+.firebug .nodeComment {
+ margin: 0 2px;
+ vertical-align: top;
+}
+.firebug .nodeText {
+ color: #333333;
+}
+.firebug .nodeComment {
+ color: DarkGreen;
+}
+.firebug .propertyNameCell {
+ vertical-align: top;
+}
+.firebug .propertyName {
+ font-weight: bold;
+}
+#firebugToolbar ul.tabs{
+ margin:0 !important;
+ padding:0;
+}
+#firebugToolbar ul.tabs li{
+ list-style:none;
+ background:transparent url(tab_lft_norm.png) no-repeat left;
+ line-height:18px;
+ float:left;
+ margin-left:5px;
+}
+#firebugToolbar ul.tabs li.right{
+ float:right;
+ margin-right:5px;
+ margin-left:0;
+}
+#firebugToolbar ul.tabs li.gap{
+ margin-left:20px;
+}
+#firebugToolbar .tabs a{
+ text-decoration:none;
+ background:transparent url(tab_rgt_norm.png) no-repeat right;
+ line-height:18px;
+ padding:3px 9px 4px 0px;
+ margin-left:9px;
+ color:#333333;
+}
+#firebugToolbar .tabs li:hover{
+ background:transparent url(tab_lft_over.png) no-repeat left;
+}
+#firebugToolbar .tabs a:hover{
+ text-decoration:none;
+ background:transparent url(tab_rgt_over.png) no-repeat right;
+ color:#FFFFFF;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/web-resources/_firebug/firebug.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,898 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+//>>built
+define("dojo/_firebug/firebug",["../_base/kernel","require","../_base/html","../sniff","../_base/array","../_base/lang","../_base/event","../_base/unload"],function(_1,_2,_3,_4){
+var _5=(/Trident/.test(window.navigator.userAgent));
+if(_5){
+var _6=["log","info","debug","warn","error"];
+for(var i=0;i<_6.length;i++){
+var m=_6[i];
+if(!console[m]||console[m]._fake){
+continue;
+}
+var n="_"+_6[i];
+console[n]=console[m];
+console[m]=(function(){
+var _7=n;
+return function(){
+console[_7](Array.prototype.join.call(arguments," "));
+};
+})();
+}
+try{
+console.clear();
+}
+catch(e){
+}
+}
+if(_4("ff")||_4("chrome")||_4("safari")||_5||window.firebug||(typeof console!="undefined"&&console.firebug)||_1.config.useCustomLogger||_4("air")){
+return;
+}
+try{
+if(window!=window.parent){
+if(window.parent["console"]){
+window.console=window.parent.console;
+}
+return;
+}
+}
+catch(e){
+}
+var _8=document;
+var _9=window;
+var _a=0;
+var _b=null;
+var _c=null;
+var _d=null;
+var _e=null;
+var _f=null;
+var _10=null;
+var _11=false;
+var _12=[];
+var _13=[];
+var _14={};
+var _15={};
+var _16=null;
+var _17;
+var _18;
+var _19=false;
+var _1a=null;
+var _1b=document.createElement("div");
+var _1c;
+var _1d;
+window.console={_connects:[],log:function(){
+_1e(arguments,"");
+},debug:function(){
+_1e(arguments,"debug");
+},info:function(){
+_1e(arguments,"info");
+},warn:function(){
+_1e(arguments,"warning");
+},error:function(){
+_1e(arguments,"error");
+},assert:function(_1f,_20){
+if(!_1f){
+var _21=[];
+for(var i=1;i<arguments.length;++i){
+_21.push(arguments[i]);
+}
+_1e(_21.length?_21:["Assertion Failure"],"error");
+throw _20?_20:"Assertion Failure";
+}
+},dir:function(obj){
+var str=_22(obj);
+str=str.replace(/\n/g,"<br />");
+str=str.replace(/\t/g," ");
+_23([str],"dir");
+},dirxml:function(_24){
+var _25=[];
+_26(_24,_25);
+_23(_25,"dirxml");
+},group:function(){
+_23(arguments,"group",_27);
+},groupEnd:function(){
+_23(arguments,"",_28);
+},time:function(_29){
+_14[_29]=new Date().getTime();
+},timeEnd:function(_2a){
+if(_2a in _14){
+var _2b=(new Date()).getTime()-_14[_2a];
+_1e([_2a+":",_2b+"ms"]);
+delete _14[_2a];
+}
+},count:function(_2c){
+if(!_15[_2c]){
+_15[_2c]=0;
+}
+_15[_2c]++;
+_1e([_2c+": "+_15[_2c]]);
+},trace:function(_2d){
+var _2e=_2d||3;
+var f=console.trace.caller;
+for(var i=0;i<_2e;i++){
+var _2f=f.toString();
+var _30=[];
+for(var a=0;a<f.arguments.length;a++){
+_30.push(f.arguments[a]);
+}
+if(f.arguments.length){
+}else{
+}
+f=f.caller;
+}
+},profile:function(){
+this.warn(["profile() not supported."]);
+},profileEnd:function(){
+},clear:function(){
+if(_c){
+while(_c.childNodes.length){
+_1.destroy(_c.firstChild);
+}
+}
+_1.forEach(this._connects,_1.disconnect);
+},open:function(){
+_31(true);
+},close:function(){
+if(_11){
+_31();
+}
+},_restoreBorder:function(){
+if(_1c){
+_1c.style.border=_1d;
+}
+},openDomInspector:function(){
+_19=true;
+_c.style.display="none";
+_16.style.display="block";
+_d.style.display="none";
+document.body.style.cursor="pointer";
+_17=_1.connect(document,"mousemove",function(evt){
+if(!_19){
+return;
+}
+if(!_1a){
+_1a=setTimeout(function(){
+_1a=null;
+},50);
+}else{
+return;
+}
+var _32=evt.target;
+if(_32&&(_1c!==_32)){
+var _33=true;
+console._restoreBorder();
+var _34=[];
+_26(_32,_34);
+_16.innerHTML=_34.join("");
+_1c=_32;
+_1d=_1c.style.border;
+_1c.style.border="#0000FF 1px solid";
+}
+});
+setTimeout(function(){
+_18=_1.connect(document,"click",function(evt){
+document.body.style.cursor="";
+_19=!_19;
+_1.disconnect(_18);
+});
+},30);
+},_closeDomInspector:function(){
+document.body.style.cursor="";
+_1.disconnect(_17);
+_1.disconnect(_18);
+_19=false;
+console._restoreBorder();
+},openConsole:function(){
+_c.style.display="block";
+_16.style.display="none";
+_d.style.display="none";
+console._closeDomInspector();
+},openObjectInspector:function(){
+_c.style.display="none";
+_16.style.display="none";
+_d.style.display="block";
+console._closeDomInspector();
+},recss:function(){
+var i,a,s;
+a=document.getElementsByTagName("link");
+for(i=0;i<a.length;i++){
+s=a[i];
+if(s.rel.toLowerCase().indexOf("stylesheet")>=0&&s.href){
+var h=s.href.replace(/(&|%5C?)forceReload=\d+/,"");
+s.href=h+(h.indexOf("?")>=0?"&":"?")+"forceReload="+new Date().valueOf();
+}
+}
+}};
+function _31(_35){
+_11=_35||!_11;
+if(_b){
+_b.style.display=_11?"block":"none";
+}
+};
+function _36(){
+_31(true);
+if(_f){
+_f.focus();
+}
+};
+function _37(x,y,w,h){
+var win=window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
+if(!win){
+var msg="Firebug Lite could not open a pop-up window, most likely because of a blocker.\n"+"Either enable pop-ups for this domain, or change the djConfig to popup=false.";
+alert(msg);
+}
+_38(win);
+var _39=win.document;
+var _3a="<html style=\"height:100%;\"><head><title>Firebug Lite</title></head>\n"+"<body bgColor=\"#ccc\" style=\"height:97%;\" onresize=\"opener.onFirebugResize()\">\n"+"<div id=\"fb\"></div>"+"</body></html>";
+_39.write(_3a);
+_39.close();
+return win;
+};
+function _38(wn){
+var d=new Date();
+d.setTime(d.getTime()+(60*24*60*60*1000));
+d=d.toUTCString();
+var dc=wn.document,_3b;
+if(wn.innerWidth){
+_3b=function(){
+return {w:wn.innerWidth,h:wn.innerHeight};
+};
+}else{
+if(dc.documentElement&&dc.documentElement.clientWidth){
+_3b=function(){
+return {w:dc.documentElement.clientWidth,h:dc.documentElement.clientHeight};
+};
+}else{
+if(dc.body){
+_3b=function(){
+return {w:dc.body.clientWidth,h:dc.body.clientHeight};
+};
+}
+}
+}
+window.onFirebugResize=function(){
+_49(_3b().h);
+clearInterval(wn._firebugWin_resize);
+wn._firebugWin_resize=setTimeout(function(){
+var x=wn.screenLeft,y=wn.screenTop,w=wn.outerWidth||wn.document.body.offsetWidth,h=wn.outerHeight||wn.document.body.offsetHeight;
+document.cookie="_firebugPosition="+[x,y,w,h].join(",")+"; expires="+d+"; path=/";
+},5000);
+};
+};
+function _3c(){
+if(_b){
+return;
+}
+_31(true);
+if(_1.config.popup){
+var _3d="100%";
+var _3e=document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
+var p=_3e?_3e[1].split(","):[2,2,320,480];
+_9=_37(p[0],p[1],p[2],p[3]);
+_8=_9.document;
+_1.config.debugContainerId="fb";
+_9.console=window.console;
+_9.dojo=window.dojo;
+}else{
+_8=document;
+_3d=(_1.config.debugHeight||300)+"px";
+}
+var _3f=_8.createElement("link");
+_3f.href=_2.toUrl("./firebug.css");
+_3f.rel="stylesheet";
+_3f.type="text/css";
+var _40=_8.getElementsByTagName("head");
+if(_40){
+_40=_40[0];
+}
+if(!_40){
+_40=_8.getElementsByTagName("html")[0];
+}
+if(_4("ie")){
+window.setTimeout(function(){
+_40.appendChild(_3f);
+},0);
+}else{
+_40.appendChild(_3f);
+}
+if(_1.config.debugContainerId){
+_b=_8.getElementById(_1.config.debugContainerId);
+}
+if(!_b){
+_b=_8.createElement("div");
+_8.body.appendChild(_b);
+}
+_b.className+=" firebug";
+_b.id="firebug";
+_b.style.height=_3d;
+_b.style.display=(_11?"block":"none");
+var _41=function(_42,_43,_44,_45){
+return "<li class=\""+_45+"\"><a href=\"javascript:void(0);\" onclick=\"console."+_44+"(); return false;\" title=\""+_43+"\">"+_42+"</a></li>";
+};
+_b.innerHTML="<div id=\"firebugToolbar\">"+" <ul id=\"fireBugTabs\" class=\"tabs\">"+_41("Clear","Remove All Console Logs","clear","")+_41("ReCSS","Refresh CSS without reloading page","recss","")+_41("Console","Show Console Logs","openConsole","gap")+_41("DOM","Show DOM Inspector","openDomInspector","")+_41("Object","Show Object Inspector","openObjectInspector","")+((_1.config.popup)?"":_41("Close","Close the console","close","gap"))+"\t</ul>"+"</div>"+"<input type=\"text\" id=\"firebugCommandLine\" />"+"<div id=\"firebugLog\"></div>"+"<div id=\"objectLog\" style=\"display:none;\">Click on an object in the Log display</div>"+"<div id=\"domInspect\" style=\"display:none;\">Hover over HTML elements in the main page. Click to hold selection.</div>";
+_10=_8.getElementById("firebugToolbar");
+_f=_8.getElementById("firebugCommandLine");
+_46(_f,"keydown",_47);
+_46(_8,_4("ie")||_4("safari")?"keydown":"keypress",_48);
+_c=_8.getElementById("firebugLog");
+_d=_8.getElementById("objectLog");
+_16=_8.getElementById("domInspect");
+_e=_8.getElementById("fireBugTabs");
+_49();
+_4a();
+};
+_1.addOnLoad(_3c);
+function _4b(){
+_8=null;
+if(_9.console){
+_9.console.clear();
+}
+_9=null;
+_b=null;
+_c=null;
+_d=null;
+_16=null;
+_f=null;
+_12=[];
+_13=[];
+_14={};
+};
+function _4c(){
+var _4d=_f.value;
+_f.value="";
+_23(["> ",_4d],"command");
+var _4e;
+try{
+_4e=eval(_4d);
+}
+catch(e){
+}
+};
+function _49(h){
+var _4f=25;
+var _50=h?h-(_4f+_f.offsetHeight+25+(h*0.01))+"px":(_b.offsetHeight-_4f-_f.offsetHeight)+"px";
+_c.style.top=_4f+"px";
+_c.style.height=_50;
+_d.style.height=_50;
+_d.style.top=_4f+"px";
+_16.style.height=_50;
+_16.style.top=_4f+"px";
+_f.style.bottom=0;
+_1.addOnWindowUnload(_4b);
+};
+function _23(_51,_52,_53){
+if(_c){
+_54(_51,_52,_53);
+}else{
+_12.push([_51,_52,_53]);
+}
+};
+function _4a(){
+var _55=_12;
+_12=[];
+for(var i=0;i<_55.length;++i){
+_54(_55[i][0],_55[i][1],_55[i][2]);
+}
+};
+function _54(_56,_57,_58){
+var _59=_c.scrollTop+_c.offsetHeight>=_c.scrollHeight;
+_58=_58||_5a;
+_58(_56,_57);
+if(_59){
+_c.scrollTop=_c.scrollHeight-_c.offsetHeight;
+}
+};
+function _5b(row){
+var _5c=_13.length?_13[_13.length-1]:_c;
+_5c.appendChild(row);
+};
+function _5a(_5d,_5e){
+var row=_c.ownerDocument.createElement("div");
+row.className="logRow"+(_5e?" logRow-"+_5e:"");
+row.innerHTML=_5d.join("");
+_5b(row);
+};
+function _27(_5f,_60){
+_1e(_5f,_60);
+var _61=_c.ownerDocument.createElement("div");
+_61.className="logGroupBox";
+_5b(_61);
+_13.push(_61);
+};
+function _28(){
+_13.pop();
+};
+function _1e(_62,_63){
+var _64=[];
+var _65=_62[0];
+var _66=0;
+if(typeof (_65)!="string"){
+_65="";
+_66=-1;
+}
+var _67=_68(_65);
+for(var i=0;i<_67.length;++i){
+var _69=_67[i];
+if(_69&&typeof _69=="object"){
+_69.appender(_62[++_66],_64);
+}else{
+_6a(_69,_64);
+}
+}
+var ids=[];
+var obs=[];
+for(i=_66+1;i<_62.length;++i){
+_6a(" ",_64);
+var _6b=_62[i];
+if(_6b===undefined||_6b===null){
+_6c(_6b,_64);
+}else{
+if(typeof (_6b)=="string"){
+_6a(_6b,_64);
+}else{
+if(_6b instanceof Date){
+_6a(_6b.toString(),_64);
+}else{
+if(_6b.nodeType==9){
+_6a("[ XmlDoc ]",_64);
+}else{
+var id="_a"+_a++;
+ids.push(id);
+obs.push(_6b);
+var str="<a id=\""+id+"\" href=\"javascript:void(0);\">"+_6d(_6b)+"</a>";
+_6e(str,_64);
+}
+}
+}
+}
+}
+_23(_64,_63);
+for(i=0;i<ids.length;i++){
+var btn=_8.getElementById(ids[i]);
+if(!btn){
+continue;
+}
+btn.obj=obs[i];
+_9.console._connects.push(_1.connect(btn,"onclick",function(){
+console.openObjectInspector();
+try{
+_22(this.obj);
+}
+catch(e){
+this.obj=e;
+}
+_d.innerHTML="<pre>"+_22(this.obj)+"</pre>";
+}));
+}
+};
+function _68(_6f){
+var _70=[];
+var reg=/((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+var _71={s:_6a,d:_72,i:_72,f:_73};
+for(var m=reg.exec(_6f);m;m=reg.exec(_6f)){
+var _74=m[8]?m[8]:m[5];
+var _75=_74 in _71?_71[_74]:_76;
+var _77=m[3]?parseInt(m[3]):(m[4]=="."?-1:0);
+_70.push(_6f.substr(0,m[0][0]=="%"?m.index:m.index+1));
+_70.push({appender:_75,precision:_77});
+_6f=_6f.substr(m.index+m[0].length);
+}
+_70.push(_6f);
+return _70;
+};
+function _78(_79){
+function _7a(ch){
+switch(ch){
+case "<":
+return "<";
+case ">":
+return ">";
+case "&":
+return "&";
+case "'":
+return "'";
+case "\"":
+return """;
+}
+return "?";
+};
+return String(_79).replace(/[<>&"']/g,_7a);
+};
+function _7b(_7c){
+try{
+return _7c+"";
+}
+catch(e){
+return null;
+}
+};
+function _6e(_7d,_7e){
+_7e.push(_7b(_7d));
+};
+function _6a(_7f,_80){
+_80.push(_78(_7b(_7f)));
+};
+function _6c(_81,_82){
+_82.push("<span class=\"objectBox-null\">",_78(_7b(_81)),"</span>");
+};
+function _83(_84,_85){
+_85.push("<span class=\"objectBox-string\">"",_78(_7b(_84)),""</span>");
+};
+function _72(_86,_87){
+_87.push("<span class=\"objectBox-number\">",_78(_7b(_86)),"</span>");
+};
+function _73(_88,_89){
+_89.push("<span class=\"objectBox-number\">",_78(_7b(_88)),"</span>");
+};
+function _8a(_8b,_8c){
+_8c.push("<span class=\"objectBox-function\">",_6d(_8b),"</span>");
+};
+function _76(_8d,_8e){
+try{
+if(_8d===undefined){
+_6c("undefined",_8e);
+}else{
+if(_8d===null){
+_6c("null",_8e);
+}else{
+if(typeof _8d=="string"){
+_83(_8d,_8e);
+}else{
+if(typeof _8d=="number"){
+_72(_8d,_8e);
+}else{
+if(typeof _8d=="function"){
+_8a(_8d,_8e);
+}else{
+if(_8d.nodeType==1){
+_8f(_8d,_8e);
+}else{
+if(typeof _8d=="object"){
+_90(_8d,_8e);
+}else{
+_6a(_8d,_8e);
+}
+}
+}
+}
+}
+}
+}
+}
+catch(e){
+}
+};
+function _90(_91,_92){
+var _93=_7b(_91);
+var _94=/\[object (.*?)\]/;
+var m=_94.exec(_93);
+_92.push("<span class=\"objectBox-object\">",m?m[1]:_93,"</span>");
+};
+function _8f(_95,_96){
+_96.push("<span class=\"objectBox-selector\">");
+_96.push("<span class=\"selectorTag\">",_78(_95.nodeName.toLowerCase()),"</span>");
+if(_95.id){
+_96.push("<span class=\"selectorId\">#",_78(_95.id),"</span>");
+}
+if(_95.className){
+_96.push("<span class=\"selectorClass\">.",_78(_95.className),"</span>");
+}
+_96.push("</span>");
+};
+function _26(_97,_98){
+if(_97.nodeType==1){
+_98.push("<div class=\"objectBox-element\">","<<span class=\"nodeTag\">",_97.nodeName.toLowerCase(),"</span>");
+for(var i=0;i<_97.attributes.length;++i){
+var _99=_97.attributes[i];
+if(!_99.specified){
+continue;
+}
+_98.push(" <span class=\"nodeName\">",_99.nodeName.toLowerCase(),"</span>="<span class=\"nodeValue\">",_78(_99.nodeValue),"</span>"");
+}
+if(_97.firstChild){
+_98.push("></div><div class=\"nodeChildren\">");
+for(var _9a=_97.firstChild;_9a;_9a=_9a.nextSibling){
+_26(_9a,_98);
+}
+_98.push("</div><div class=\"objectBox-element\"></<span class=\"nodeTag\">",_97.nodeName.toLowerCase(),"></span></div>");
+}else{
+_98.push("/></div>");
+}
+}else{
+if(_97.nodeType==3){
+_98.push("<div class=\"nodeText\">",_78(_97.nodeValue),"</div>");
+}
+}
+};
+function _46(_9b,_9c,_9d){
+if(document.all){
+_9b.attachEvent("on"+_9c,_9d);
+}else{
+_9b.addEventListener(_9c,_9d,false);
+}
+};
+function _9e(_9f,_a0,_a1){
+if(document.all){
+_9f.detachEvent("on"+_a0,_a1);
+}else{
+_9f.removeEventListener(_a0,_a1,false);
+}
+};
+function _a2(_a3){
+if(document.all){
+_a3.cancelBubble=true;
+}else{
+_a3.stopPropagation();
+}
+};
+function _a4(msg,_a5,_a6){
+var _a7=_a5.lastIndexOf("/");
+var _a8=_a7==-1?_a5:_a5.substr(_a7+1);
+var _a9=["<span class=\"errorMessage\">",msg,"</span>","<div class=\"objectBox-sourceLink\">",_a8," (line ",_a6,")</div>"];
+_23(_a9,"error");
+};
+var _aa=new Date().getTime();
+function _48(_ab){
+var _ac=(new Date()).getTime();
+if(_ac>_aa+200){
+_ab=_1.fixEvent(_ab);
+var _ad=_1.keys;
+var ekc=_ab.keyCode;
+_aa=_ac;
+if(ekc==_ad.F12){
+_31();
+}else{
+if((ekc==_ad.NUMPAD_ENTER||ekc==76)&&_ab.shiftKey&&(_ab.metaKey||_ab.ctrlKey)){
+_36();
+}else{
+return;
+}
+}
+_a2(_ab);
+}
+};
+function _47(e){
+var dk=_1.keys;
+if(e.keyCode==13&&_f.value){
+_ae(_f.value);
+_4c();
+}else{
+if(e.keyCode==27){
+_f.value="";
+}else{
+if(e.keyCode==dk.UP_ARROW||e.charCode==dk.UP_ARROW){
+_af("older");
+}else{
+if(e.keyCode==dk.DOWN_ARROW||e.charCode==dk.DOWN_ARROW){
+_af("newer");
+}else{
+if(e.keyCode==dk.HOME||e.charCode==dk.HOME){
+_b0=1;
+_af("older");
+}else{
+if(e.keyCode==dk.END||e.charCode==dk.END){
+_b0=999999;
+_af("newer");
+}
+}
+}
+}
+}
+}
+};
+var _b0=-1;
+var _b1=null;
+function _ae(_b2){
+var _b3=_b4("firebug_history");
+_b3=(_b3)?_1.fromJson(_b3):[];
+var pos=_1.indexOf(_b3,_b2);
+if(pos!=-1){
+_b3.splice(pos,1);
+}
+_b3.push(_b2);
+_b4("firebug_history",_1.toJson(_b3),30);
+while(_b3.length&&!_b4("firebug_history")){
+_b3.shift();
+_b4("firebug_history",_1.toJson(_b3),30);
+}
+_b1=null;
+_b0=-1;
+};
+function _af(_b5){
+var _b6=_b4("firebug_history");
+_b6=(_b6)?_1.fromJson(_b6):[];
+if(!_b6.length){
+return;
+}
+if(_b1===null){
+_b1=_f.value;
+}
+if(_b0==-1){
+_b0=_b6.length;
+}
+if(_b5=="older"){
+--_b0;
+if(_b0<0){
+_b0=0;
+}
+}else{
+if(_b5=="newer"){
+++_b0;
+if(_b0>_b6.length){
+_b0=_b6.length;
+}
+}
+}
+if(_b0==_b6.length){
+_f.value=_b1;
+_b1=null;
+}else{
+_f.value=_b6[_b0];
+}
+};
+function _b4(_b7,_b8){
+var c=document.cookie;
+if(arguments.length==1){
+var _b9=c.match(new RegExp("(?:^|; )"+_b7+"=([^;]*)"));
+return _b9?decodeURIComponent(_b9[1]):undefined;
+}else{
+var d=new Date();
+d.setMonth(d.getMonth()+1);
+document.cookie=_b7+"="+encodeURIComponent(_b8)+((d.toUtcString)?"; expires="+d.toUTCString():"");
+}
+};
+function _ba(it){
+return it&&it instanceof Array||typeof it=="array";
+};
+function _bb(o){
+var cnt=0;
+for(var nm in o){
+cnt++;
+}
+return cnt;
+};
+function _22(o,i,txt,_bc){
+var ind=" \t";
+txt=txt||"";
+i=i||ind;
+_bc=_bc||[];
+var _bd;
+if(o&&o.nodeType==1){
+var _be=[];
+_26(o,_be);
+return _be.join("");
+}
+var br=",\n",cnt=0,_bf=_bb(o);
+if(o instanceof Date){
+return i+o.toString()+br;
+}
+looking:
+for(var nm in o){
+cnt++;
+if(cnt==_bf){
+br="\n";
+}
+if(o[nm]===window||o[nm]===document){
+}else{
+if(o[nm]===null){
+txt+=i+nm+" : NULL"+br;
+}else{
+if(o[nm]&&o[nm].nodeType){
+if(o[nm].nodeType==1){
+}else{
+if(o[nm].nodeType==3){
+txt+=i+nm+" : [ TextNode "+o[nm].data+" ]"+br;
+}
+}
+}else{
+if(typeof o[nm]=="object"&&(o[nm] instanceof String||o[nm] instanceof Number||o[nm] instanceof Boolean)){
+txt+=i+nm+" : "+o[nm]+","+br;
+}else{
+if(o[nm] instanceof Date){
+txt+=i+nm+" : "+o[nm].toString()+br;
+}else{
+if(typeof (o[nm])=="object"&&o[nm]){
+for(var j=0,_c0;_c0=_bc[j];j++){
+if(o[nm]===_c0){
+txt+=i+nm+" : RECURSION"+br;
+continue looking;
+}
+}
+_bc.push(o[nm]);
+_bd=(_ba(o[nm]))?["[","]"]:["{","}"];
+txt+=i+nm+" : "+_bd[0]+"\n";
+txt+=_22(o[nm],i+ind,"",_bc);
+txt+=i+_bd[1]+br;
+}else{
+if(typeof o[nm]=="undefined"){
+txt+=i+nm+" : undefined"+br;
+}else{
+if(nm=="toString"&&typeof o[nm]=="function"){
+var _c1=o[nm]();
+if(typeof _c1=="string"&&_c1.match(/function ?(.*?)\(/)){
+_c1=_78(_6d(o[nm]));
+}
+txt+=i+nm+" : "+_c1+br;
+}else{
+txt+=i+nm+" : "+_78(_6d(o[nm]))+br;
+}
+}
+}
+}
+}
+}
+}
+}
+}
+return txt;
+};
+function _6d(obj){
+var _c2=(obj instanceof Error);
+if(obj.nodeType==1){
+return _78("< "+obj.tagName.toLowerCase()+" id=\""+obj.id+"\" />");
+}
+if(obj.nodeType==3){
+return _78("[TextNode: \""+obj.nodeValue+"\"]");
+}
+var nm=(obj&&(obj.id||obj.name||obj.ObjectID||obj.widgetId));
+if(!_c2&&nm){
+return "{"+nm+"}";
+}
+var _c3=2;
+var _c4=4;
+var cnt=0;
+if(_c2){
+nm="[ Error: "+(obj.message||obj.description||obj)+" ]";
+}else{
+if(_ba(obj)){
+nm="["+obj.slice(0,_c4).join(",");
+if(obj.length>_c4){
+nm+=" ... ("+obj.length+" items)";
+}
+nm+="]";
+}else{
+if(typeof obj=="function"){
+nm=obj+"";
+var reg=/function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/;
+var m=reg.exec(nm);
+if(m){
+if(!m[1]){
+m[1]="function";
+}
+nm=m[1]+m[2];
+}else{
+nm="function()";
+}
+}else{
+if(typeof obj!="object"||typeof obj=="string"){
+nm=obj+"";
+}else{
+nm="{";
+for(var i in obj){
+cnt++;
+if(cnt>_c3){
+break;
+}
+nm+=i+":"+_78(obj[i])+" ";
+}
+nm+="}";
+}
+}
+}
+}
+return nm;
+};
+_46(document,_4("ie")||_4("safari")?"keydown":"keypress",_48);
+if((document.documentElement.getAttribute("debug")=="true")||(_1.config.isDebug)){
+_31(true);
+}
+_1.addOnWindowUnload(function(){
+_9e(document,_4("ie")||_4("safari")?"keydown":"keypress",_48);
+window.onFirebugResize=null;
+window.console=null;
+});
+});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/web-resources/_firebug/firebug.js.uncompressed.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,1191 @@
+define("dojo/_firebug/firebug", [
+ "../_base/kernel",
+ "require",
+ "../_base/html",
+ "../sniff",
+ "../_base/array",
+ "../_base/lang",
+ "../_base/event",
+ "../_base/unload"], function(dojo, require, html, has){
+
+ // module:
+ // dojo/_firebug/firebug
+ // summary:
+ // Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox
+ // description:
+ // Opens a console for logging, debugging, and error messages.
+ // Contains partial functionality to Firebug. See function list below.
+ //
+ // NOTE:
+ // Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug.
+ // Firebug Lite is included in Dojo by permission from Joe Hewitt
+ // If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug
+ // functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html
+ //
+ // NOTE:
+ // To test Firebug Lite in Firefox:
+ //
+ // - FF2: set "console = null" before loading dojo and set djConfig.isDebug=true
+ // - FF3: disable Firebug and set djConfig.isDebug=true
+ //
+ // example:
+ // Supports inline objects in object inspector window (only simple trace of dom nodes, however)
+ // | console.log("my object", {foo:"bar"})
+ // example:
+ // Option for console to open in popup window
+ // | var djConfig = {isDebug: true, popup:true };
+ // example:
+ // Option for console height (ignored for popup)
+ // | var djConfig = {isDebug: true, debugHeight:100 }
+
+
+ var isNewIE = (/Trident/.test(window.navigator.userAgent));
+ if(isNewIE){
+ // Fixing IE's console
+ // IE doesn't insert space between arguments. How annoying.
+ var calls = ["log", "info", "debug", "warn", "error"];
+ for(var i=0;i<calls.length;i++){
+ var m = calls[i];
+ if(!console[m] ||console[m]._fake){
+ // IE9 doesn't have console.debug method, a fake one is added later
+ continue;
+ }
+ var n = "_"+calls[i];
+ console[n] = console[m];
+ console[m] = (function(){
+ var type = n;
+ return function(){
+ console[type](Array.prototype.join.call(arguments, " "));
+ };
+ })();
+ }
+ // clear the console on load. This is more than a convenience - too many logs crashes it.
+ // If closed it throws an error
+ try{ console.clear(); }catch(e){}
+ }
+
+ if(
+ has("ff") || // Firefox has Firebug
+ has("chrome") || // Chrome 3+ has a console
+ has("safari") || // Safari 4 has a console
+ isNewIE || // Has the new IE console
+ window.firebug || // Testing for mozilla firebug lite
+ (typeof console != "undefined" && console.firebug) || //The firebug console
+ dojo.config.useCustomLogger || // Allow custom loggers
+ has("air") // isDebug triggers AIRInsector, not Firebug
+ ){
+ return;
+ }
+
+ // don't build firebug in iframes
+ try{
+ if(window != window.parent){
+ // but if we've got a parent logger, connect to it
+ if(window.parent["console"]){
+ window.console = window.parent.console;
+ }
+ return;
+ }
+ }catch(e){/*squelch*/}
+
+ // ***************************************************************************
+ // Placing these variables before the functions that use them to avoid a
+ // shrinksafe bug where variable renaming does not happen correctly otherwise.
+
+ // most of the objects in this script are run anonomously
+ var _firebugDoc = document;
+ var _firebugWin = window;
+ var __consoleAnchorId__ = 0;
+
+ var consoleFrame = null;
+ var consoleBody = null;
+ var consoleObjectInspector = null;
+ var fireBugTabs = null;
+ var commandLine = null;
+ var consoleToolbar = null;
+
+ var frameVisible = false;
+ var messageQueue = [];
+ var groupStack = [];
+ var timeMap = {};
+ var countMap = {};
+
+ var consoleDomInspector = null;
+ var _inspectionMoveConnection;
+ var _inspectionClickConnection;
+ var _inspectionEnabled = false;
+ var _inspectionTimer = null;
+ var _inspectTempNode = document.createElement("div");
+
+
+ var _inspectCurrentNode;
+ var _restoreBorderStyle;
+
+ // ***************************************************************************
+
+ window.console = {
+ _connects: [],
+ log: function(){
+ // summary:
+ // Sends arguments to console.
+ logFormatted(arguments, "");
+ },
+
+ debug: function(){
+ // summary:
+ // Sends arguments to console. Missing finctionality to show script line of trace.
+ logFormatted(arguments, "debug");
+ },
+
+ info: function(){
+ // summary:
+ // Sends arguments to console, highlighted with (I) icon.
+ logFormatted(arguments, "info");
+ },
+
+ warn: function(){
+ // summary:
+ // Sends warning arguments to console, highlighted with (!) icon and blue style.
+ logFormatted(arguments, "warning");
+ },
+
+ error: function(){
+ // summary:
+ // Sends error arguments (object) to console, highlighted with (X) icon and yellow style
+ // NEW: error object now displays in object inspector
+ logFormatted(arguments, "error");
+ },
+
+ assert: function(truth, message){
+ // summary:
+ // Tests for true. Throws exception if false.
+ if(!truth){
+ var args = [];
+ for(var i = 1; i < arguments.length; ++i){
+ args.push(arguments[i]);
+ }
+
+ logFormatted(args.length ? args : ["Assertion Failure"], "error");
+ throw message ? message : "Assertion Failure";
+ }
+ },
+
+ dir: function(obj){
+ var str = printObject( obj );
+ str = str.replace(/\n/g, "<br />");
+ str = str.replace(/\t/g, " ");
+ logRow([str], "dir");
+ },
+
+ dirxml: function(node){
+ var html = [];
+ appendNode(node, html);
+ logRow(html, "dirxml");
+ },
+
+ group: function(){
+ // summary:
+ // collects log messages into a group, starting with this call and ending with
+ // groupEnd(). Missing collapse functionality
+ logRow(arguments, "group", pushGroup);
+ },
+
+ groupEnd: function(){
+ // summary:
+ // Closes group. See above
+ logRow(arguments, "", popGroup);
+ },
+
+ time: function(name){
+ // summary:
+ // Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title);
+ // example:
+ // | console.time("load");
+ // | console.time("myFunction");
+ // | console.timeEnd("load");
+ // | console.timeEnd("myFunction");
+ timeMap[name] = new Date().getTime();
+ },
+
+ timeEnd: function(name){
+ // summary:
+ // See above.
+ if(name in timeMap){
+ var delta = (new Date()).getTime() - timeMap[name];
+ logFormatted([name+ ":", delta+"ms"]);
+ delete timeMap[name];
+ }
+ },
+
+ count: function(name){
+ // summary:
+ // Not supported
+ if(!countMap[name]) countMap[name] = 0;
+ countMap[name]++;
+ logFormatted([name+": "+countMap[name]]);
+ },
+
+ trace: function(_value){
+ var stackAmt = _value || 3;
+ var f = console.trace.caller; //function that called trace
+ console.log(">>> console.trace(stack)");
+ for(var i=0;i<stackAmt;i++){
+ var func = f.toString();
+ var args=[];
+ for (var a = 0; a < f.arguments.length; a++){
+ args.push(f.arguments[a]);
+ }
+ if(f.arguments.length){
+ console.dir({"function":func, "arguments":args});
+ }else{
+ console.dir({"function":func});
+ }
+
+ f = f.caller;
+ }
+ },
+
+ profile: function(){
+ // summary:
+ // Not supported
+ this.warn(["profile() not supported."]);
+ },
+
+ profileEnd: function(){ },
+
+ clear: function(){
+ // summary:
+ // Clears message console. Do not call this directly
+ if(consoleBody){
+ while(consoleBody.childNodes.length){
+ dojo.destroy(consoleBody.firstChild);
+ }
+ }
+ dojo.forEach(this._connects,dojo.disconnect);
+ },
+
+ open: function(){
+ // summary:
+ // Opens message console. Do not call this directly
+ toggleConsole(true);
+ },
+
+ close: function(){
+ // summary:
+ // Closes message console. Do not call this directly
+ if(frameVisible){
+ toggleConsole();
+ }
+ },
+ _restoreBorder: function(){
+ if(_inspectCurrentNode){
+ _inspectCurrentNode.style.border = _restoreBorderStyle;
+ }
+ },
+ openDomInspector: function(){
+ _inspectionEnabled = true;
+ consoleBody.style.display = "none";
+ consoleDomInspector.style.display = "block";
+ consoleObjectInspector.style.display = "none";
+ document.body.style.cursor = "pointer";
+ _inspectionMoveConnection = dojo.connect(document, "mousemove", function(evt){
+ if(!_inspectionEnabled){ return; }
+ if(!_inspectionTimer){
+ _inspectionTimer = setTimeout(function(){ _inspectionTimer = null; }, 50);
+ }else{
+ return;
+ }
+ var node = evt.target;
+ if(node && (_inspectCurrentNode !== node)){
+ var parent = true;
+
+ console._restoreBorder();
+ var html = [];
+ appendNode(node, html);
+ consoleDomInspector.innerHTML = html.join("");
+
+ _inspectCurrentNode = node;
+ _restoreBorderStyle = _inspectCurrentNode.style.border;
+ _inspectCurrentNode.style.border = "#0000FF 1px solid";
+ }
+ });
+ setTimeout(function(){
+ _inspectionClickConnection = dojo.connect(document, "click", function(evt){
+ document.body.style.cursor = "";
+ _inspectionEnabled = !_inspectionEnabled;
+ dojo.disconnect(_inspectionClickConnection);
+ // console._restoreBorder();
+ });
+ }, 30);
+ },
+ _closeDomInspector: function(){
+ document.body.style.cursor = "";
+ dojo.disconnect(_inspectionMoveConnection);
+ dojo.disconnect(_inspectionClickConnection);
+ _inspectionEnabled = false;
+ console._restoreBorder();
+ },
+ openConsole:function(){
+ // summary:
+ // Closes object inspector and opens message console. Do not call this directly
+ consoleBody.style.display = "block";
+ consoleDomInspector.style.display = "none";
+ consoleObjectInspector.style.display = "none";
+ console._closeDomInspector();
+ },
+ openObjectInspector:function(){
+ consoleBody.style.display = "none";
+ consoleDomInspector.style.display = "none";
+ consoleObjectInspector.style.display = "block";
+ console._closeDomInspector();
+ },
+ recss: function(){
+ // this is placed in dojo since the console is most likely
+ // in another window and dojo is easilly accessible
+ var i,a,s;a=document.getElementsByTagName('link');
+ for(i=0;i<a.length;i++){
+ s=a[i];
+ if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href){
+ var h=s.href.replace(/(&|%5C?)forceReload=\d+/,'');
+ s.href=h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+new Date().valueOf();
+ }
+ }
+ }
+ };
+
+ // ***************************************************************************
+
+ function toggleConsole(forceOpen){
+ frameVisible = forceOpen || !frameVisible;
+ if(consoleFrame){
+ consoleFrame.style.display = frameVisible ? "block" : "none";
+ }
+ }
+
+ function focusCommandLine(){
+ toggleConsole(true);
+ if(commandLine){
+ commandLine.focus();
+ }
+ }
+
+ function openWin(x,y,w,h){
+ var win = window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
+ if(!win){
+ var msg = "Firebug Lite could not open a pop-up window, most likely because of a blocker.\n" +
+ "Either enable pop-ups for this domain, or change the djConfig to popup=false.";
+ alert(msg);
+ }
+ createResizeHandler(win);
+ var newDoc=win.document;
+ //Safari needs an HTML height
+ var HTMLstring= '<html style="height:100%;"><head><title>Firebug Lite</title></head>\n' +
+ '<body bgColor="#ccc" style="height:97%;" onresize="opener.onFirebugResize()">\n' +
+ '<div id="fb"></div>' +
+ '</body></html>';
+
+ newDoc.write(HTMLstring);
+ newDoc.close();
+ return win;
+ }
+
+ function createResizeHandler(wn){
+ // summary:
+ // Creates handle for onresize window. Called from script in popup's body tag (so that it will work with IE).
+ //
+
+ var d = new Date();
+ d.setTime(d.getTime()+(60*24*60*60*1000)); // 60 days
+ d = d.toUTCString();
+
+ var dc = wn.document,
+ getViewport;
+
+ if (wn.innerWidth){
+ getViewport = function(){
+ return{w:wn.innerWidth, h:wn.innerHeight};
+ };
+ }else if (dc.documentElement && dc.documentElement.clientWidth){
+ getViewport = function(){
+ return{w:dc.documentElement.clientWidth, h:dc.documentElement.clientHeight};
+ };
+ }else if (dc.body){
+ getViewport = function(){
+ return{w:dc.body.clientWidth, h:dc.body.clientHeight};
+ };
+ }
+
+
+ window.onFirebugResize = function(){
+
+ //resize the height of the console log body
+ layout(getViewport().h);
+
+ clearInterval(wn._firebugWin_resize);
+ wn._firebugWin_resize = setTimeout(function(){
+ var x = wn.screenLeft,
+ y = wn.screenTop,
+ w = wn.outerWidth || wn.document.body.offsetWidth,
+ h = wn.outerHeight || wn.document.body.offsetHeight;
+
+ document.cookie = "_firebugPosition=" + [x,y,w,h].join(",") + "; expires="+d+"; path=/";
+
+ }, 5000); //can't capture window.onMove - long timeout gives better chance of capturing a resize, then the move
+
+ };
+ }
+
+
+ /*****************************************************************************/
+
+
+ function createFrame(){
+ if(consoleFrame){
+ return;
+ }
+ toggleConsole(true);
+ if(dojo.config.popup){
+ var containerHeight = "100%";
+ var cookieMatch = document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
+ var p = cookieMatch ? cookieMatch[1].split(",") : [2,2,320,480];
+
+ _firebugWin = openWin(p[0],p[1],p[2],p[3]); // global
+ _firebugDoc = _firebugWin.document; // global
+
+ dojo.config.debugContainerId = 'fb';
+
+ // connecting popup
+ _firebugWin.console = window.console;
+ _firebugWin.dojo = window.dojo;
+ }else{
+ _firebugDoc = document;
+ containerHeight = (dojo.config.debugHeight || 300) + "px";
+ }
+
+ var styleElement = _firebugDoc.createElement("link");
+ styleElement.href = require.toUrl("./firebug.css");
+ styleElement.rel = "stylesheet";
+ styleElement.type = "text/css";
+ var styleParent = _firebugDoc.getElementsByTagName("head");
+ if(styleParent){
+ styleParent = styleParent[0];
+ }
+ if(!styleParent){
+ styleParent = _firebugDoc.getElementsByTagName("html")[0];
+ }
+ if(has("ie")){
+ window.setTimeout(function(){ styleParent.appendChild(styleElement); }, 0);
+ }else{
+ styleParent.appendChild(styleElement);
+ }
+
+ if(dojo.config.debugContainerId){
+ consoleFrame = _firebugDoc.getElementById(dojo.config.debugContainerId);
+ }
+ if(!consoleFrame){
+ consoleFrame = _firebugDoc.createElement("div");
+ _firebugDoc.body.appendChild(consoleFrame);
+ }
+ consoleFrame.className += " firebug";
+ consoleFrame.id = "firebug";
+ consoleFrame.style.height = containerHeight;
+ consoleFrame.style.display = (frameVisible ? "block" : "none");
+
+ var buildLink = function(label, title, method, _class){
+ return '<li class="'+_class+'"><a href="javascript:void(0);" onclick="console.'+ method +'(); return false;" title="'+title+'">'+label+'</a></li>';
+ };
+ consoleFrame.innerHTML =
+ '<div id="firebugToolbar">'
+ + ' <ul id="fireBugTabs" class="tabs">'
+
+ + buildLink("Clear", "Remove All Console Logs", "clear", "")
+ + buildLink("ReCSS", "Refresh CSS without reloading page", "recss", "")
+
+ + buildLink("Console", "Show Console Logs", "openConsole", "gap")
+ + buildLink("DOM", "Show DOM Inspector", "openDomInspector", "")
+ + buildLink("Object", "Show Object Inspector", "openObjectInspector", "")
+ + ((dojo.config.popup) ? "" : buildLink("Close", "Close the console", "close", "gap"))
+
+ + ' </ul>'
+ + '</div>'
+ + '<input type="text" id="firebugCommandLine" />'
+ + '<div id="firebugLog"></div>'
+ + '<div id="objectLog" style="display:none;">Click on an object in the Log display</div>'
+ + '<div id="domInspect" style="display:none;">Hover over HTML elements in the main page. Click to hold selection.</div>';
+
+
+ consoleToolbar = _firebugDoc.getElementById("firebugToolbar");
+
+ commandLine = _firebugDoc.getElementById("firebugCommandLine");
+ addEvent(commandLine, "keydown", onCommandLineKeyDown);
+
+ addEvent(_firebugDoc, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
+
+ consoleBody = _firebugDoc.getElementById("firebugLog");
+ consoleObjectInspector = _firebugDoc.getElementById("objectLog");
+ consoleDomInspector = _firebugDoc.getElementById("domInspect");
+ fireBugTabs = _firebugDoc.getElementById("fireBugTabs");
+ layout();
+ flush();
+ }
+
+ dojo.addOnLoad(createFrame);
+
+ function clearFrame(){
+ _firebugDoc = null;
+
+ if(_firebugWin.console){
+ _firebugWin.console.clear();
+ }
+ _firebugWin = null;
+ consoleFrame = null;
+ consoleBody = null;
+ consoleObjectInspector = null;
+ consoleDomInspector = null;
+ commandLine = null;
+ messageQueue = [];
+ groupStack = [];
+ timeMap = {};
+ }
+
+
+ function evalCommandLine(){
+ var text = commandLine.value;
+ commandLine.value = "";
+
+ logRow(["> ", text], "command");
+
+ var value;
+ try{
+ value = eval(text);
+ }catch(e){
+ console.debug(e); // put exception on the console
+ }
+
+ console.log(value);
+ }
+
+ function layout(h){
+ var tHeight = 25; //consoleToolbar.offsetHeight; // tab style not ready on load - throws off layout
+ var height = h ?
+ h - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" :
+ (consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px";
+
+ consoleBody.style.top = tHeight + "px";
+ consoleBody.style.height = height;
+ consoleObjectInspector.style.height = height;
+ consoleObjectInspector.style.top = tHeight + "px";
+ consoleDomInspector.style.height = height;
+ consoleDomInspector.style.top = tHeight + "px";
+ commandLine.style.bottom = 0;
+
+ dojo.addOnWindowUnload(clearFrame);
+ }
+
+ function logRow(message, className, handler){
+ if(consoleBody){
+ writeMessage(message, className, handler);
+ }else{
+ messageQueue.push([message, className, handler]);
+ }
+ }
+
+ function flush(){
+ var queue = messageQueue;
+ messageQueue = [];
+
+ for(var i = 0; i < queue.length; ++i){
+ writeMessage(queue[i][0], queue[i][1], queue[i][2]);
+ }
+ }
+
+ function writeMessage(message, className, handler){
+ var isScrolledToBottom =
+ consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
+
+ handler = handler||writeRow;
+
+ handler(message, className);
+
+ if(isScrolledToBottom){
+ consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
+ }
+ }
+
+ function appendRow(row){
+ var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
+ container.appendChild(row);
+ }
+
+ function writeRow(message, className){
+ var row = consoleBody.ownerDocument.createElement("div");
+ row.className = "logRow" + (className ? " logRow-"+className : "");
+ row.innerHTML = message.join("");
+ appendRow(row);
+ }
+
+ function pushGroup(message, className){
+ logFormatted(message, className);
+
+ //var groupRow = consoleBody.ownerDocument.createElement("div");
+ //groupRow.className = "logGroup";
+ var groupRowBox = consoleBody.ownerDocument.createElement("div");
+ groupRowBox.className = "logGroupBox";
+ //groupRow.appendChild(groupRowBox);
+ appendRow(groupRowBox);
+ groupStack.push(groupRowBox);
+ }
+
+ function popGroup(){
+ groupStack.pop();
+ }
+
+ // ***************************************************************************
+
+ function logFormatted(objects, className){
+ var html = [];
+
+ var format = objects[0];
+ var objIndex = 0;
+
+ if(typeof(format) != "string"){
+ format = "";
+ objIndex = -1;
+ }
+
+ var parts = parseFormat(format);
+
+ for(var i = 0; i < parts.length; ++i){
+ var part = parts[i];
+ if(part && typeof part == "object"){
+ part.appender(objects[++objIndex], html);
+ }else{
+ appendText(part, html);
+ }
+ }
+
+
+ var ids = [];
+ var obs = [];
+ for(i = objIndex+1; i < objects.length; ++i){
+ appendText(" ", html);
+
+ var object = objects[i];
+ if(object === undefined || object === null ){
+ appendNull(object, html);
+
+ }else if(typeof(object) == "string"){
+ appendText(object, html);
+
+ }else if(object instanceof Date){
+ appendText(object.toString(), html);
+
+ }else if(object.nodeType == 9){
+ appendText("[ XmlDoc ]", html);
+
+ }else{
+ // Create link for object inspector
+ // need to create an ID for this link, since it is currently text
+ var id = "_a" + __consoleAnchorId__++;
+ ids.push(id);
+ // need to save the object, so the arrays line up
+ obs.push(object);
+ var str = '<a id="'+id+'" href="javascript:void(0);">'+getObjectAbbr(object)+'</a>';
+
+ appendLink( str , html);
+ }
+ }
+
+ logRow(html, className);
+
+ // Now that the row is inserted in the DOM, loop through all of the links that were just created
+ for(i=0; i<ids.length; i++){
+ var btn = _firebugDoc.getElementById(ids[i]);
+ if(!btn){ continue; }
+
+ // store the object in the dom btn for reference later
+ // avoid parsing these objects unless necessary
+ btn.obj = obs[i];
+
+ _firebugWin.console._connects.push(dojo.connect(btn, "onclick", function(){
+
+ console.openObjectInspector();
+
+ try{
+ printObject(this.obj);
+ }catch(e){
+ this.obj = e;
+ }
+ consoleObjectInspector.innerHTML = "<pre>" + printObject( this.obj ) + "</pre>";
+ }));
+ }
+ }
+
+ function parseFormat(format){
+ var parts = [];
+
+ var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+ var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+ for(var m = reg.exec(format); m; m = reg.exec(format)){
+ var type = m[8] ? m[8] : m[5];
+ var appender = type in appenderMap ? appenderMap[type] : appendObject;
+ var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+ parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+ parts.push({appender: appender, precision: precision});
+
+ format = format.substr(m.index+m[0].length);
+ }
+
+ parts.push(format);
+
+ return parts;
+ }
+
+ function escapeHTML(value){
+ function replaceChars(ch){
+ switch(ch){
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case "&":
+ return "&";
+ case "'":
+ return "'";
+ case '"':
+ return """;
+ }
+ return "?";
+ }
+ return String(value).replace(/[<>&"']/g, replaceChars);
+ }
+
+ function objectToString(object){
+ try{
+ return object+"";
+ }catch(e){
+ return null;
+ }
+ }
+
+ // ***************************************************************************
+ function appendLink(object, html){
+ // needed for object links - no HTML escaping
+ html.push( objectToString(object) );
+ }
+
+ function appendText(object, html){
+ html.push(escapeHTML(objectToString(object)));
+ }
+
+ function appendNull(object, html){
+ html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendString(object, html){
+ html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)),
+ '"</span>');
+ }
+
+ function appendInteger(object, html){
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFloat(object, html){
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFunction(object, html){
+ html.push('<span class="objectBox-function">', getObjectAbbr(object), '</span>');
+ }
+
+ function appendObject(object, html){
+ try{
+ if(object === undefined){
+ appendNull("undefined", html);
+ }else if(object === null){
+ appendNull("null", html);
+ }else if(typeof object == "string"){
+ appendString(object, html);
+ }else if(typeof object == "number"){
+ appendInteger(object, html);
+ }else if(typeof object == "function"){
+ appendFunction(object, html);
+ }else if(object.nodeType == 1){
+ appendSelector(object, html);
+ }else if(typeof object == "object"){
+ appendObjectFormatted(object, html);
+ }else{
+ appendText(object, html);
+ }
+ }catch(e){
+ /* squelch */
+ }
+ }
+
+ function appendObjectFormatted(object, html){
+ var text = objectToString(object);
+ var reObject = /\[object (.*?)\]/;
+
+ var m = reObject.exec(text);
+ html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>');
+ }
+
+ function appendSelector(object, html){
+ html.push('<span class="objectBox-selector">');
+
+ html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
+ if(object.id){
+ html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
+ }
+ if(object.className){
+ html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
+ }
+
+ html.push('</span>');
+ }
+
+ function appendNode(node, html){
+ if(node.nodeType == 1){
+ html.push(
+ '<div class="objectBox-element">',
+ '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
+
+ for(var i = 0; i < node.attributes.length; ++i){
+ var attr = node.attributes[i];
+ if(!attr.specified){ continue; }
+
+ html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(),
+ '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue),
+ '</span>"');
+ }
+
+ if(node.firstChild){
+ html.push('></div><div class="nodeChildren">');
+
+ for(var child = node.firstChild; child; child = child.nextSibling){
+ appendNode(child, html);
+ }
+
+ html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
+ node.nodeName.toLowerCase(), '></span></div>');
+ }else{
+ html.push('/></div>');
+ }
+ }else if (node.nodeType == 3){
+ html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
+ '</div>');
+ }
+ }
+
+ // ***************************************************************************
+
+ function addEvent(object, name, handler){
+ if(document.all){
+ object.attachEvent("on"+name, handler);
+ }else{
+ object.addEventListener(name, handler, false);
+ }
+ }
+
+ function removeEvent(object, name, handler){
+ if(document.all){
+ object.detachEvent("on"+name, handler);
+ }else{
+ object.removeEventListener(name, handler, false);
+ }
+ }
+
+ function cancelEvent(event){
+ if(document.all){
+ event.cancelBubble = true;
+ }else{
+ event.stopPropagation();
+ }
+ }
+
+ function onError(msg, href, lineNo){
+ var lastSlash = href.lastIndexOf("/");
+ var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
+
+ var html = [
+ '<span class="errorMessage">', msg, '</span>',
+ '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
+ ];
+
+ logRow(html, "error");
+ }
+
+
+ //After converting to div instead of iframe, now getting two keydowns right away in IE 6.
+ //Make sure there is a little bit of delay.
+ var onKeyDownTime = new Date().getTime();
+
+ function onKeyDown(event){
+ var timestamp = (new Date()).getTime();
+ if(timestamp > onKeyDownTime + 200){
+ event = dojo.fixEvent(event);
+ var keys = dojo.keys;
+ var ekc = event.keyCode;
+ onKeyDownTime = timestamp;
+ if(ekc == keys.F12){
+ toggleConsole();
+ }else if(
+ (ekc == keys.NUMPAD_ENTER || ekc == 76) &&
+ event.shiftKey &&
+ (event.metaKey || event.ctrlKey)
+ ){
+ focusCommandLine();
+ }else{
+ return;
+ }
+ cancelEvent(event);
+ }
+ }
+
+ function onCommandLineKeyDown(e){
+ var dk = dojo.keys;
+ if(e.keyCode == 13 && commandLine.value){
+ addToHistory(commandLine.value);
+ evalCommandLine();
+ }else if(e.keyCode == 27){
+ commandLine.value = "";
+ }else if(e.keyCode == dk.UP_ARROW || e.charCode == dk.UP_ARROW){
+ navigateHistory("older");
+ }else if(e.keyCode == dk.DOWN_ARROW || e.charCode == dk.DOWN_ARROW){
+ navigateHistory("newer");
+ }else if(e.keyCode == dk.HOME || e.charCode == dk.HOME){
+ historyPosition = 1;
+ navigateHistory("older");
+ }else if(e.keyCode == dk.END || e.charCode == dk.END){
+ historyPosition = 999999;
+ navigateHistory("newer");
+ }
+ }
+
+ var historyPosition = -1;
+ var historyCommandLine = null;
+
+ function addToHistory(value){
+ var history = cookie("firebug_history");
+ history = (history) ? dojo.fromJson(history) : [];
+ var pos = dojo.indexOf(history, value);
+ if (pos != -1){
+ history.splice(pos, 1);
+ }
+ history.push(value);
+ cookie("firebug_history", dojo.toJson(history), 30);
+ while(history.length && !cookie("firebug_history")){
+ history.shift();
+ cookie("firebug_history", dojo.toJson(history), 30);
+ }
+ historyCommandLine = null;
+ historyPosition = -1;
+ }
+
+ function navigateHistory(direction){
+ var history = cookie("firebug_history");
+ history = (history) ? dojo.fromJson(history) : [];
+ if(!history.length){
+ return;
+ }
+
+ if(historyCommandLine === null){
+ historyCommandLine = commandLine.value;
+ }
+
+ if(historyPosition == -1){
+ historyPosition = history.length;
+ }
+
+ if(direction == "older"){
+ --historyPosition;
+ if(historyPosition < 0){
+ historyPosition = 0;
+ }
+ }else if(direction == "newer"){
+ ++historyPosition;
+ if(historyPosition > history.length){
+ historyPosition = history.length;
+ }
+ }
+
+ if(historyPosition == history.length){
+ commandLine.value = historyCommandLine;
+ historyCommandLine = null;
+ }else{
+ commandLine.value = history[historyPosition];
+ }
+ }
+
+ function cookie(name, value){
+ var c = document.cookie;
+ if(arguments.length == 1){
+ var matches = c.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
+ return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined
+ }else{
+ var d = new Date();
+ d.setMonth(d.getMonth()+1);
+ document.cookie = name + "=" + encodeURIComponent(value) + ((d.toUtcString) ? "; expires=" + d.toUTCString() : "");
+ }
+ }
+
+ function isArray(it){
+ return it && it instanceof Array || typeof it == "array";
+ }
+
+ //***************************************************************************************************
+ // Print Object Helpers
+ function objectLength(o){
+ var cnt = 0;
+ for(var nm in o){
+ cnt++;
+ }
+ return cnt;
+ }
+
+ function printObject(o, i, txt, used){
+ // Recursively trace object, indenting to represent depth for display in object inspector
+ var ind = " \t";
+ txt = txt || "";
+ i = i || ind;
+ used = used || [];
+ var opnCls;
+
+ if(o && o.nodeType == 1){
+ var html = [];
+ appendNode(o, html);
+ return html.join("");
+ }
+
+ var br=",\n", cnt = 0, length = objectLength(o);
+
+ if(o instanceof Date){
+ return i + o.toString() + br;
+ }
+ looking:
+ for(var nm in o){
+ cnt++;
+ if(cnt==length){br = "\n";}
+ if(o[nm] === window || o[nm] === document){
+ // do nothing
+ }else if(o[nm] === null){
+ txt += i+nm + " : NULL" + br;
+ }else if(o[nm] && o[nm].nodeType){
+ if(o[nm].nodeType == 1){
+ //txt += i+nm + " : < "+o[nm].tagName+" id=\""+ o[nm].id+"\" />" + br;
+ }else if(o[nm].nodeType == 3){
+ txt += i+nm + " : [ TextNode "+o[nm].data + " ]" + br;
+ }
+
+ }else if(typeof o[nm] == "object" && (o[nm] instanceof String || o[nm] instanceof Number || o[nm] instanceof Boolean)){
+ txt += i+nm + " : " + o[nm] + "," + br;
+
+ }else if(o[nm] instanceof Date){
+ txt += i+nm + " : " + o[nm].toString() + br;
+
+ }else if(typeof(o[nm]) == "object" && o[nm]){
+ for(var j = 0, seen; seen = used[j]; j++){
+ if(o[nm] === seen){
+ txt += i+nm + " : RECURSION" + br;
+ continue looking;
+ }
+ }
+ used.push(o[nm]);
+
+ opnCls = (isArray(o[nm]))?["[","]"]:["{","}"];
+ txt += i+nm +" : " + opnCls[0] + "\n";//non-standard break, (no comma)
+ txt += printObject(o[nm], i+ind, "", used);
+ txt += i + opnCls[1] + br;
+
+ }else if(typeof o[nm] == "undefined"){
+ txt += i+nm + " : undefined" + br;
+ }else if(nm == "toString" && typeof o[nm] == "function"){
+ var toString = o[nm]();
+ if(typeof toString == "string" && toString.match(/function ?(.*?)\(/)){
+ toString = escapeHTML(getObjectAbbr(o[nm]));
+ }
+ txt += i+nm +" : " + toString + br;
+ }else{
+ txt += i+nm +" : "+ escapeHTML(getObjectAbbr(o[nm])) + br;
+ }
+ }
+ return txt;
+ }
+
+ function getObjectAbbr(obj){
+ // Gets an abbreviation of an object for display in log
+ // X items in object, including id
+ // X items in an array
+ // TODO: Firebug Sr. actually goes by char count
+ var isError = (obj instanceof Error);
+ if(obj.nodeType == 1){
+ return escapeHTML('< '+obj.tagName.toLowerCase()+' id=\"'+ obj.id+ '\" />');
+ }
+ if(obj.nodeType == 3){
+ return escapeHTML('[TextNode: "'+obj.nodeValue+'"]');
+ }
+ var nm = (obj && (obj.id || obj.name || obj.ObjectID || obj.widgetId));
+ if(!isError && nm){ return "{"+nm+"}"; }
+
+ var obCnt = 2;
+ var arCnt = 4;
+ var cnt = 0;
+
+ if(isError){
+ nm = "[ Error: "+(obj.message || obj.description || obj)+" ]";
+ }else if(isArray(obj)){
+ nm = "[" + obj.slice(0,arCnt).join(",");
+ if(obj.length > arCnt){
+ nm += " ... ("+obj.length+" items)";
+ }
+ nm += "]";
+ }else if(typeof obj == "function"){
+ nm = obj + "";
+ var reg = /function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/;
+ var m = reg.exec(nm);
+ if(m){
+ if(!m[1]){
+ m[1] = "function";
+ }
+ nm = m[1] + m[2];
+ }else{
+ nm = "function()";
+ }
+ }else if(typeof obj != "object" || typeof obj == "string"){
+ nm = obj + "";
+ }else{
+ nm = "{";
+ for(var i in obj){
+ cnt++;
+ if(cnt > obCnt){ break; }
+ nm += i+":"+escapeHTML(obj[i])+" ";
+ }
+ nm+="}";
+ }
+
+ return nm;
+ }
+
+ //*************************************************************************************
+
+ //window.onerror = onError;
+
+ addEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
+
+ if( (document.documentElement.getAttribute("debug") == "true")||
+ (dojo.config.isDebug)
+ ){
+ toggleConsole(true);
+ }
+
+ dojo.addOnWindowUnload(function(){
+ // Erase the globals and event handlers I created, to prevent spurious leak warnings
+ removeEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
+ window.onFirebugResize = null;
+ window.console = null;
+ });
+
+});
Binary file server/src/main/web-resources/_firebug/infoIcon.png has changed
Binary file server/src/main/web-resources/_firebug/tab_lft_norm.png has changed
Binary file server/src/main/web-resources/_firebug/tab_lft_over.png has changed
Binary file server/src/main/web-resources/_firebug/tab_rgt_norm.png has changed
Binary file server/src/main/web-resources/_firebug/tab_rgt_over.png has changed
Binary file server/src/main/web-resources/_firebug/warningIcon.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/applicationContext.xml Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+ <!-- Activates various annotations to be detected in bean classes -->
+ <context:annotation-config />
+
+ <!-- Configures the annotation-driven Spring MVC Controller programming model.
+ Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
+
+ <!-- Loads MongoDB configuraton -->
+ <import resource="mongo-config.xml"/>
+
+ <!--bean id="bayeuxServer" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
+ <property name="options">
+ <map>
+ <entry key="logLevel" value="3" />
+ <entry key="timeout" value="15000" />
+ </map>
+ </property>
+ </bean-->
+ <bean id="springConfigurer"
+ class="org.iri_research.renkan.coweb.SpringConfigurer"
+ factory-method="getInstance" />
+
+ <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
+ For example @Controller and @Service. Make sure to set the correct base-package-->
+ <context:component-scan base-package="org.iri_research.renkan.rest" />
+ <context:component-scan base-package="org.iri_research.renkan.coweb" />
+
+</beans>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/jsp/projectPrompt.jsp Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Project prompt</title>
+</head>
+<body>
+ ${message}
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/mongo-config.xml Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:jpa="http://www.springframework.org/schema/data/jpa"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/data/mongo
+ http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/data/jpa
+ http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
+ <!-- Default bean name is 'mongo' -->
+ <mongo:mongo host="localhost" port="27017"/>
+
+ <!-- Offers convenience methods and automatic mapping between MongoDB JSON documents and your domain classes. -->
+ <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
+ <constructor-arg ref="mongo"/>
+ <constructor-arg value="renkan"/>
+ <property name="writeResultChecking" value="EXCEPTION"/>
+ </bean>
+
+ <mongo:repositories base-package="org.iri_research.renkan" factory-class="org.iri_research.renkan.repositories.RenkanRepositoryFactoryBean" />
+
+</beans>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/spring-servlet.xml Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:mvc="http://www.springframework.org/schema/mvc"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd
+ http://www.springframework.org/schema/mvc
+ http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
+
+ <!-- **************************************************************** -->
+ <!-- RESOURCE FOLDERS CONFIGURATION -->
+ <!-- Dispatcher configuration for serving static resources -->
+ <!-- **************************************************************** -->
+ <mvc:resources location="/images/" mapping="/images/**" />
+ <mvc:resources location="/css/" mapping="/css/**" />
+
+ <!-- **************************************************************** -->
+ <!-- SPRING ANNOTATION PROCESSING -->
+ <!-- **************************************************************** -->
+ <mvc:annotation-driven />
+ <context:component-scan
+ base-package="org.iri_research.renkan.controller" />
+
+ <bean id="viewResolver"
+ class="org.springframework.web.servlet.view.UrlBasedViewResolver">
+ <property name="viewClass"
+ value="org.springframework.web.servlet.view.JstlView" />
+ <property name="prefix" value="/WEB-INF/jsp/" />
+ <property name="suffix" value=".jsp" />
+ <property name="order" value="2" />
+ </bean>
+
+ <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
+ <property name="prefix" value="/WEB-INF/templates/" />
+ <property name="suffix" value=".html" />
+ <property name="templateMode" value="HTML5" />
+ <property name="cacheable" value="false"/>
+ </bean>
+
+ <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
+ <property name="templateResolver" ref="templateResolver" />
+ </bean>
+
+ <bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
+ <property name="templateEngine" ref="templateEngine" />
+ <property name="order" value="1" />
+ <!--property name="viewNames" value="*.html,*.xhtml" /-->
+ <property name="characterEncoding" value="UTF-8"/>
+ </bean>
+
+</beans>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html lang="fr" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+ <head>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+ <title>Test de Rendu RENKAN</title>
+ <meta name="description" content="" />
+ <meta name="author" content="Institut de Recherche et d'Innovation" />
+ <script src="lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
+ <script src="lib/jquery.mousewheel.min.js" th:src="@{/static/lib/jquery.mousewheel.min.js}"></script>
+ <script src="lib/underscore-min.js" th:src="@{/static/lib/underscore-min.js}"></script>
+ <script src="lib/backbone.js" th:src="@{/static/lib/backbone.js}"></script>
+ <script src="lib/backbone-relational.js" th:src="@{/static/lib/backbone-relational.js}"></script>
+ <script src="lib/paper.js" th:src="@{/static/lib/paper.js}"></script>
+ <script src="js/main.js" th:src="@{/static/js/main.js}"></script>
+ <script src="js/i18n.js" th:src="@{/static/js/i18n.js}"></script>
+ <script src="js/models.js" th:src="@{/static/js/models.js}"></script>
+ <script src="js/corenkan-json.js" th:src="@{/static/js/corenkan-json.js}"></script>
+ <!--script src="js/random-data.js" th:src="@{/static/js/random-data.js}"></script-->
+ <script src="js/twitter-bin.js" th:src="@{/static/js/twitter-bin.js}"></script>
+ <script src="js/wikipedia-bin.js" th:src="@{/static/js/wikipedia-bin.js}"></script>
+ <script src="js/ldtjson-bin.js" th:src="@{/static/js/ldtjson-bin.js}"></script>
+ <script src="js/paper-renderer.js" th:src="@{/static/js/paper-renderer.js}"></script>
+ <script type="text/javascript" src="js/config.js" th:src="@{/static/js/config.js}"></script>
+ <script type="text/javascript" src="js/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true" th:src="@{/static/js/dojo.js}"></script>
+ <script type="text/javascript" th:inline="javascript">
+ var _proj;
+ require(["corenkan"], function(corenkan) {
+ $(function() {
+ _renkan = new Rkns.Renkan({
+ url: /*[[@{/rest/projects/}+${project.id}]]*/ "data/simple-persist.php",
+ static_url : /*[[@{/static/}]]*/ "",
+ bins: [
+ {
+ bin: Rkns.Wikipedia.Bin,
+ lang: "en",
+ search: "Digital Humanities"
+ },
+ {
+ bin: Rkns.Wikipedia.Bin,
+ lang: "ja",
+ search: "Digital Humanities"
+ },
+ {
+ bin: Rkns.Twitter.Bin,
+ search: "Digital Humanities"
+ },
+ {
+ title: "LDT Project",
+ bin: Rkns.Ldt.ProjectBin,
+ project_id: "67280b1c-ff30-11e0-a82d-00145ea49a02",
+ ldt_platform: "http://ldt.iri.centrepompidou.fr/"
+ }
+ ],
+ search: [
+ {
+ type: Rkns.Wikipedia.Search,
+ lang: "fr"
+ },
+ {
+ type: Rkns.Wikipedia.Search,
+ lang: "en"
+ },
+ {
+ type: Rkns.Wikipedia.Search,
+ lang: "ja"
+ },
+ {
+ type: Rkns.Twitter.Search
+ }
+ ],
+ });
+ corenkan.app.onStatusChange = function(status) {
+ if(status == "ready") {
+ Rkns.jsonIO(_renkan, {
+ url: /*[[@{/rest/projects/}+${project.id}]]*/ "data/simple-persist.php",
+ callback: function(_proj, _renkan) {
+ corenkan.app.setProject(_proj);
+ var anon_users = _proj.get("users").where({title: "anonymous"});
+ if(anon_users.length == 0) {
+ _proj.current_user = _proj.addUser({
+ id: Rkns.Utils.getUID("u"),
+ title: "anonymous",
+ color: "#000080",
+ });
+ }
+ else {
+ _proj.current_user = anon_users[0];
+ }
+ _renkan.current_user = _proj.current_user.id;
+ }
+ });
+ }
+ };
+ });
+ });
+ </script>
+ <link rel="stylesheet" href="css/renkan.css" th:href="@{/static/css/renkan.css}"/>
+ <style type="text/css">
+ </style>
+ </head>
+
+ <body>
+ <div id="renkan"></div>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/renkanProjectRender.html Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html lang="fr" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+ <head>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+ <title>Test de Rendu RENKAN</title>
+ <meta name="description" content="" />
+ <meta name="author" content="Institut de Recherche et d'Innovation" />
+ <script src="lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}"></script>
+ <script src="lib/jquery.mousewheel.min.js" th:src="@{/static/lib/jquery.mousewheel.min.js}"></script>
+ <script src="lib/underscore-min.js" th:src="@{/static/lib/underscore-min.js}"></script>
+ <script src="lib/backbone.js" th:src="@{/static/lib/backbone.js}"></script>
+ <script src="lib/backbone-relational.js" th:src="@{/static/lib/backbone-relational.js}"></script>
+ <script src="lib/paper.js" th:src="@{/static/lib/paper.js}"></script>
+ <script src="js/renkan-publish.js" th:src="@{/static/js/renkan-publish.js}"></script>
+ <script type="text/javascript" th:inline="javascript">
+ /*<![CDATA[*/
+ var _renkan;
+ $(function() {
+ _renkan = new Rkns.Renkan({static_url:/*[[@{/static/}]]*/ ""});
+ _renkan.addProject({
+ url: /*[[@{/rest/projects/}+${project.id}]]*/ "../metadataplayer/json/renkan.json",
+ callback: function(_proj) {
+ if (_renkan.renderer) {
+ _renkan.renderer.autoScale();
+ }
+ }
+ });
+ //_renkan.addProject({
+ // url: "../metadataplayer/json/renkan.json"
+ //});
+ _renderer = _renkan.renderProjectAt(0);
+ });
+ /*]]>*/
+ </script>
+ <link rel="stylesheet" href="css/renkan-publish.css" th:href="@{/static/css/renkan-publish.css}"/>
+ <style type="text/css">
+ </style>
+ </head>
+
+ <body>
+ <div id="renkan"></div>
+ </body>
+</html>
--- a/server/src/main/webapp/WEB-INF/web.xml Fri Dec 21 16:22:08 2012 +0100
+++ b/server/src/main/webapp/WEB-INF/web.xml Mon Dec 31 13:37:31 2012 +0100
@@ -1,8 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+<web-app
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ version="2.5">
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+ <listener>
+ <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
+ </listener>
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>/WEB-INF/applicationContext.xml</param-value>
+ </context-param>
<servlet>
<servlet-name>cometd</servlet-name>
- <servlet-class>org.cometd.server.CometdServlet</servlet-class>
+ <!--servlet-class>org.cometd.server.CometdServlet</servlet-class-->
+ <servlet-class>org.iri_research.renkan.coweb.server.RenkanCometdServlet</servlet-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>0</param-value>
@@ -14,7 +30,15 @@
<init-param>
<param-name>jsonDebug</param-name>
<param-value>false</param-value>
+ </init-param>
+ <init-param>
+ <param-name>maxSessionsPerBrowser</param-name>
+ <param-value>-1</param-value>
</init-param>
+ <!--init-param>
+ <param-name>transports</param-name>
+ <param-value>org.cometd.websocket.server.WebSocketTransport</param-value>
+ </init-param-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
@@ -36,15 +60,28 @@
</servlet-mapping>
<servlet>
<servlet-name>rest Servlet</servlet-name>
- <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+ <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.iri_research.renkan.rest</param-value>
</init-param>
+ <init-param>
+ <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
+ <param-value>true</param-value>
+ </init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest Servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
+ <servlet>
+ <servlet-name>spring</servlet-name>
+ <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>spring</servlet-name>
+ <url-pattern>/p/*</url-pattern>
+ </servlet-mapping>
</web-app>
\ No newline at end of file
Binary file server/src/main/webapp/favicon.ico has changed
--- a/server/src/main/webapp/index.html Fri Dec 21 16:22:08 2012 +0100
+++ b/server/src/main/webapp/index.html Mon Dec 31 13:37:31 2012 +0100
@@ -1,12 +1,161 @@
-<!DOCTYPE html>
+<!doctype html>
<html>
- <head>
- <meta charset="utf-8" />
- <title>My Cooperative Web Application</title>
- <script type="text/javascript" src="js/config.js"></script>
- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/dojo/1.7.0/dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
- <script data-main="main" src="js/main.js"></script>
- </head>
- <body>
- </body>
+ <title>Renkan</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
+
+ <link rel="shortcut icon" href="favicon.ico">
+
+ <style>
+ body {
+ margin: 0;
+ height: 100%;
+ color: #333;
+ font: 14px helvetica, sans-serif;
+ background: #ddd;
+ background: -webkit-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ background: -moz-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ background: -ms-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ background: -o-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ border-top: 8px solid rgba(51,51,51,.8);
+ }
+ #wrapper {
+ border-top: 1px solid #999;
+ margin-top: 160px;
+ padding: 15px;
+ background: #eee;
+ background: -webkit-linear-gradient(#fff,#ccc);
+ background: -moz-linear-gradient(#fff,#ccc);
+ background: -ms-linear-gradient(#fff,#ccc);
+ background: -o-linear-gradient(#fff,#ccc);
+ opacity: .9;
+ box-shadow: 0px 1px 8px rgba(0,0,0,0.3);
+ }
+ #inner {
+ width: 300px;
+ margin: 0 auto;
+ }
+ #button {
+ margin: 0 auto;
+ border-radius: 3px;
+ text-align: center;
+ font: 36px verdana,arial,sans-serif;
+ color: white;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.8);
+ height: 70px;
+ line-height: 70px;
+ background: #555;
+ background: -webkit-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ background: -moz-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ background: -ms-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ background: -o-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.9);
+ }
+ #button:hover {
+ cursor: pointer;
+ background: #666;
+ background: -webkit-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ background: -moz-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ background: -ms-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ background: -o-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ }
+ #button:active {
+ box-shadow: inset 0 1px 12px rgba(0,0,0,0.9);
+ background: #444;
+ }
+ #label {
+ text-align: left;
+ text-shadow: 0 1px 1px #fff;
+ margin: 16px auto 0;
+ }
+ form {
+ height: 38px;
+ background: #fff;
+ border: 1px solid #bbb;
+ border-radius: 3px;
+ position: relative;
+ }
+ button, input {
+ font-weight: bold;
+ font-size: 15px;
+ }
+ input[type="text"] {
+ border-radius: 3px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ padding: 0 45px 0 10px;
+ *padding: 0; /* IE7 hack */
+ width: 100%;
+ height: 100%;
+ outline: none;
+ border: none;
+ position: absolute;
+ }
+ button[type="submit"] {
+ position: absolute;
+ right: 0;
+ width: 45px;
+ height: 38px;
+ }
+ @media only screen and (min-device-width: 320px) and (max-device-width: 720px) {
+ body {
+ background: #bbb;
+ background: -webkit-linear-gradient(#aaa,#eee 60%) center fixed;
+ background: -moz-linear-gradient(#aaa,#eee 60%) center fixed;
+ background: -ms-linear-gradient(#aaa,#eee 60%) center fixed;
+ }
+ #wrapper {
+ margin-top: 0;
+ }
+ #inner {
+ width: 95%;
+ }
+ #label {
+ text-align: center;
+ }
+ }
+ </style>
+ <link href="static/css/index.css" rel="stylesheet">
+
+ <div id="wrapper">
+ <div id="inner">
+ <div id="button" onclick="go2Random()" class="translate">New Renkan</div>
+ <div id="label" class="translate">or create/open a Renkan with the name</div>
+ <form action="#" onsubmit="go2Name();return false;">
+ <input type="text" id="renkanname" autofocus x-webkit-speech>
+ <button type="submit">OK</button>
+ </form>
+ </div>
+ </div>
+ <script>
+
+ function go2Name()
+ {
+ var renkanname = document.getElementById("renkanname").value;
+ renkanname.length > 0 ? window.location = "p/" + renkanname : alert("Please enter a name")
+ }
+
+ function go2Random()
+ {
+ window.location = "p/" + randomRenkanName();
+ }
+
+ function randomRenkanName()
+ {
+ var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ var string_length = 10;
+ var randomstring = '';
+ for (var i = 0; i < string_length; i++)
+ {
+ var rnum = Math.floor(Math.random() * chars.length);
+ randomstring += chars.substring(rnum, rnum + 1);
+ }
+ return randomstring;
+ }
+
+ // start the custom js
+ if (typeof customStart == "function") customStart();
+ </script>
+
</html>
--- a/server/src/main/webapp/js/backbone-relational.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1687 +0,0 @@
-/**
- * Backbone-relational.js 0.6.0
- * (c) 2011 Paul Uithol
- *
- * Backbone-relational may be freely distributed under the MIT license; see the accompanying LICENSE.txt.
- * For details and documentation: https://github.com/PaulUithol/Backbone-relational.
- * Depends on Backbone (and thus on Underscore as well): https://github.com/documentcloud/backbone.
- */
-( function( undefined ) {
- "use strict";
-
- /**
- * CommonJS shim
- **/
- var _, Backbone, exports;
- if ( typeof window === 'undefined' ) {
- _ = require( 'underscore' );
- Backbone = require( 'backbone' );
- exports = module.exports = Backbone;
- }
- else {
- _ = window._;
- Backbone = window.Backbone;
- exports = window;
- }
-
- Backbone.Relational = {
- showWarnings: true
- };
-
- /**
- * Semaphore mixin; can be used as both binary and counting.
- **/
- Backbone.Semaphore = {
- _permitsAvailable: null,
- _permitsUsed: 0,
-
- acquire: function() {
- if ( this._permitsAvailable && this._permitsUsed >= this._permitsAvailable ) {
- throw new Error( 'Max permits acquired' );
- }
- else {
- this._permitsUsed++;
- }
- },
-
- release: function() {
- if ( this._permitsUsed === 0 ) {
- throw new Error( 'All permits released' );
- }
- else {
- this._permitsUsed--;
- }
- },
-
- isLocked: function() {
- return this._permitsUsed > 0;
- },
-
- setAvailablePermits: function( amount ) {
- if ( this._permitsUsed > amount ) {
- throw new Error( 'Available permits cannot be less than used permits' );
- }
- this._permitsAvailable = amount;
- }
- };
-
- /**
- * A BlockingQueue that accumulates items while blocked (via 'block'),
- * and processes them when unblocked (via 'unblock').
- * Process can also be called manually (via 'process').
- */
- Backbone.BlockingQueue = function() {
- this._queue = [];
- };
- _.extend( Backbone.BlockingQueue.prototype, Backbone.Semaphore, {
- _queue: null,
-
- add: function( func ) {
- if ( this.isBlocked() ) {
- this._queue.push( func );
- }
- else {
- func();
- }
- },
-
- process: function() {
- while ( this._queue && this._queue.length ) {
- this._queue.shift()();
- }
- },
-
- block: function() {
- this.acquire();
- },
-
- unblock: function() {
- this.release();
- if ( !this.isBlocked() ) {
- this.process();
- }
- },
-
- isBlocked: function() {
- return this.isLocked();
- }
- });
- /**
- * Global event queue. Accumulates external events ('add:<key>', 'remove:<key>' and 'update:<key>')
- * until the top-level object is fully initialized (see 'Backbone.RelationalModel').
- */
- Backbone.Relational.eventQueue = new Backbone.BlockingQueue();
-
- /**
- * Backbone.Store keeps track of all created (and destruction of) Backbone.RelationalModel.
- * Handles lookup for relations.
- */
- Backbone.Store = function() {
- this._collections = [];
- this._reverseRelations = [];
- this._subModels = [];
- this._modelScopes = [ exports ];
- };
- _.extend( Backbone.Store.prototype, Backbone.Events, {
- addModelScope: function( scope ) {
- this._modelScopes.push( scope );
- },
-
- /**
- * Add a set of subModelTypes to the store, that can be used to resolve the '_superModel'
- * for a model later in 'setupSuperModel'.
- *
- * @param {Backbone.RelationalModel} subModelTypes
- * @param {Backbone.RelationalModel} superModelType
- */
- addSubModels: function( subModelTypes, superModelType ) {
- this._subModels.push({
- 'superModelType': superModelType,
- 'subModels': subModelTypes
- });
- },
-
- /**
- * Check if the given modelType is registered as another model's subModel. If so, add it to the super model's
- * '_subModels', and set the modelType's '_superModel', '_subModelTypeName', and '_subModelTypeAttribute'.
- *
- * @param {Backbone.RelationalModel} modelType
- */
- setupSuperModel: function( modelType ) {
- _.find( this._subModels, function( subModelDef ) {
- return _.find( subModelDef.subModels, function( subModelTypeName, typeValue ) {
- var subModelType = this.getObjectByName( subModelTypeName );
-
- if ( modelType === subModelType ) {
- // Set 'modelType' as a child of the found superModel
- subModelDef.superModelType._subModels[ typeValue ] = modelType;
-
- // Set '_superModel', '_subModelTypeValue', and '_subModelTypeAttribute' on 'modelType'.
- modelType._superModel = subModelDef.superModelType;
- modelType._subModelTypeValue = typeValue;
- modelType._subModelTypeAttribute = subModelDef.superModelType.prototype.subModelTypeAttribute;
- return true;
- }
- }, this );
- }, this );
- },
-
- /**
- * Add a reverse relation. Is added to the 'relations' property on model's prototype, and to
- * existing instances of 'model' in the store as well.
- * @param {Object} relation
- * @param {Backbone.RelationalModel} relation.model
- * @param {String} relation.type
- * @param {String} relation.key
- * @param {String|Object} relation.relatedModel
- */
- addReverseRelation: function( relation ) {
- var exists = _.any( this._reverseRelations, function( rel ) {
- return _.all( relation, function( val, key ) {
- return val === rel[ key ];
- });
- });
-
- if ( !exists && relation.model && relation.type ) {
- this._reverseRelations.push( relation );
-
- var addRelation = function( model, relation ) {
- if ( !model.prototype.relations ) {
- model.prototype.relations = [];
- }
- model.prototype.relations.push( relation );
-
- _.each( model._subModels, function( subModel ) {
- addRelation( subModel, relation );
- }, this );
- };
-
- addRelation( relation.model, relation );
-
- this.retroFitRelation( relation );
- }
- },
-
- /**
- * Add a 'relation' to all existing instances of 'relation.model' in the store
- * @param {Object} relation
- */
- retroFitRelation: function( relation ) {
- var coll = this.getCollection( relation.model );
- coll.each( function( model ) {
- if ( !( model instanceof relation.model ) ) {
- return;
- }
-
- new relation.type( model, relation );
- }, this);
- },
-
- /**
- * Find the Store's collection for a certain type of model.
- * @param {Backbone.RelationalModel} model
- * @return {Backbone.Collection} A collection if found (or applicable for 'model'), or null
- */
- getCollection: function( model ) {
- if ( model instanceof Backbone.RelationalModel ) {
- model = model.constructor;
- }
-
- var rootModel = model;
- while ( rootModel._superModel ) {
- rootModel = rootModel._superModel;
- }
-
- var coll = _.detect( this._collections, function( c ) {
- return c.model === rootModel;
- });
-
- if ( !coll ) {
- coll = this._createCollection( rootModel );
- }
-
- return coll;
- },
-
- /**
- * Find a type on the global object by name. Splits name on dots.
- * @param {String} name
- * @return {Object}
- */
- getObjectByName: function( name ) {
- var parts = name.split( '.' ),
- type = null;
-
- _.find( this._modelScopes, function( scope ) {
- type = _.reduce( parts, function( memo, val ) {
- return memo[ val ];
- }, scope );
-
- if ( type && type !== scope ) {
- return true;
- }
- }, this );
-
- return type;
- },
-
- _createCollection: function( type ) {
- var coll;
-
- // If 'type' is an instance, take its constructor
- if ( type instanceof Backbone.RelationalModel ) {
- type = type.constructor;
- }
-
- // Type should inherit from Backbone.RelationalModel.
- if ( type.prototype instanceof Backbone.RelationalModel ) {
- coll = new Backbone.Collection();
- coll.model = type;
-
- this._collections.push( coll );
- }
-
- return coll;
- },
-
- /**
- * Find the attribute that is to be used as the `id` on a given object
- * @param type
- * @param {String|Number|Object|Backbone.RelationalModel} item
- * @return {String|Number}
- */
- resolveIdForItem: function( type, item ) {
- var id = _.isString( item ) || _.isNumber( item ) ? item : null;
-
- if ( id === null ) {
- if ( item instanceof Backbone.RelationalModel ) {
- id = item.id;
- }
- else if ( _.isObject( item ) ) {
- id = item[ type.prototype.idAttribute ];
- }
- }
-
- // Make all falsy values `null` (except for 0, which could be an id.. see '/issues/179')
- if ( !id && id !== 0 ) {
- id = null;
- }
-
- return id;
- },
-
- /**
- *
- * @param type
- * @param {String|Number|Object|Backbone.RelationalModel} item
- */
- find: function( type, item ) {
- var id = this.resolveIdForItem( type, item );
- var coll = this.getCollection( type );
-
- // Because the found object could be of any of the type's superModel
- // types, only return it if it's actually of the type asked for.
- if ( coll ) {
- var obj = coll.get( id );
-
- if ( obj instanceof type ) {
- return obj;
- }
- }
-
- return null;
- },
-
- /**
- * Add a 'model' to it's appropriate collection. Retain the original contents of 'model.collection'.
- * @param {Backbone.RelationalModel} model
- */
- register: function( model ) {
- var coll = this.getCollection( model );
-
- if ( coll ) {
- if ( coll.get( model ) ) {
- throw new Error( "Cannot instantiate more than one Backbone.RelationalModel with the same id per type!" );
- }
-
- var modelColl = model.collection;
- coll.add( model );
- model.bind( 'destroy', this.unregister, this );
- model.collection = modelColl;
- }
- },
-
- /**
- * Explicitly update a model's id in it's store collection
- * @param {Backbone.RelationalModel} model
- */
- update: function( model ) {
- var coll = this.getCollection( model );
- coll._onModelEvent( 'change:' + model.idAttribute, model, coll );
- },
-
- /**
- * Remove a 'model' from the store.
- * @param {Backbone.RelationalModel} model
- */
- unregister: function( model ) {
- model.unbind( 'destroy', this.unregister );
- var coll = this.getCollection( model );
- coll && coll.remove( model );
- }
- });
- Backbone.Relational.store = new Backbone.Store();
-
- /**
- * The main Relation class, from which 'HasOne' and 'HasMany' inherit. Internally, 'relational:<key>' events
- * are used to regulate addition and removal of models from relations.
- *
- * @param {Backbone.RelationalModel} instance
- * @param {Object} options
- * @param {string} options.key
- * @param {Backbone.RelationalModel.constructor} options.relatedModel
- * @param {Boolean|String} [options.includeInJSON=true] Serialize the given attribute for related model(s)' in toJSON, or just their ids.
- * @param {Boolean} [options.createModels=true] Create objects from the contents of keys if the object is not found in Backbone.store.
- * @param {Object} [options.reverseRelation] Specify a bi-directional relation. If provided, Relation will reciprocate
- * the relation to the 'relatedModel'. Required and optional properties match 'options', except that it also needs
- * {Backbone.Relation|String} type ('HasOne' or 'HasMany').
- */
- Backbone.Relation = function( instance, options ) {
- this.instance = instance;
- // Make sure 'options' is sane, and fill with defaults from subclasses and this object's prototype
- options = _.isObject( options ) ? options : {};
- this.reverseRelation = _.defaults( options.reverseRelation || {}, this.options.reverseRelation );
- this.reverseRelation.type = !_.isString( this.reverseRelation.type ) ? this.reverseRelation.type :
- Backbone[ this.reverseRelation.type ] || Backbone.Relational.store.getObjectByName( this.reverseRelation.type );
- this.model = options.model || this.instance.constructor;
- this.options = _.defaults( options, this.options, Backbone.Relation.prototype.options );
-
- this.key = this.options.key;
- this.keySource = this.options.keySource || this.key;
- this.keyDestination = this.options.keyDestination || this.keySource || this.key;
-
- // 'exports' should be the global object where 'relatedModel' can be found on if given as a string.
- this.relatedModel = this.options.relatedModel;
- if ( _.isString( this.relatedModel ) ) {
- this.relatedModel = Backbone.Relational.store.getObjectByName( this.relatedModel );
- }
-
- if ( !this.checkPreconditions() ) {
- return false;
- }
-
- if ( instance ) {
- this.keyContents = this.instance.get( this.keySource );
-
- // Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
- if ( this.key !== this.keySource ) {
- this.instance.unset( this.keySource, { silent: true } );
- }
-
- // Add this Relation to instance._relations
- this.instance._relations.push( this );
- }
-
- // Add the reverse relation on 'relatedModel' to the store's reverseRelations
- if ( !this.options.isAutoRelation && this.reverseRelation.type && this.reverseRelation.key ) {
- Backbone.Relational.store.addReverseRelation( _.defaults( {
- isAutoRelation: true,
- model: this.relatedModel,
- relatedModel: this.model,
- reverseRelation: this.options // current relation is the 'reverseRelation' for it's own reverseRelation
- },
- this.reverseRelation // Take further properties from this.reverseRelation (type, key, etc.)
- ) );
- }
-
- _.bindAll( this, '_modelRemovedFromCollection', '_relatedModelAdded', '_relatedModelRemoved' );
-
- if ( instance ) {
- this.initialize();
-
- // When a model in the store is destroyed, check if it is 'this.instance'.
- Backbone.Relational.store.getCollection( this.instance )
- .bind( 'relational:remove', this._modelRemovedFromCollection );
-
- // When 'relatedModel' are created or destroyed, check if it affects this relation.
- Backbone.Relational.store.getCollection( this.relatedModel )
- .bind( 'relational:add', this._relatedModelAdded )
- .bind( 'relational:remove', this._relatedModelRemoved );
- }
- };
- // Fix inheritance :\
- Backbone.Relation.extend = Backbone.Model.extend;
- // Set up all inheritable **Backbone.Relation** properties and methods.
- _.extend( Backbone.Relation.prototype, Backbone.Events, Backbone.Semaphore, {
- options: {
- createModels: true,
- includeInJSON: true,
- isAutoRelation: false
- },
-
- instance: null,
- key: null,
- keyContents: null,
- relatedModel: null,
- reverseRelation: null,
- related: null,
-
- _relatedModelAdded: function( model, coll, options ) {
- // Allow 'model' to set up it's relations, before calling 'tryAddRelated'
- // (which can result in a call to 'addRelated' on a relation of 'model')
- var dit = this;
- model.queue( function() {
- dit.tryAddRelated( model, options );
- });
- },
-
- _relatedModelRemoved: function( model, coll, options ) {
- this.removeRelated( model, options );
- },
-
- _modelRemovedFromCollection: function( model ) {
- if ( model === this.instance ) {
- this.destroy();
- }
- },
-
- /**
- * Check several pre-conditions.
- * @return {Boolean} True if pre-conditions are satisfied, false if they're not.
- */
- checkPreconditions: function() {
- var i = this.instance,
- k = this.key,
- m = this.model,
- rm = this.relatedModel,
- warn = Backbone.Relational.showWarnings && typeof console !== 'undefined';
-
- if ( !m || !k || !rm ) {
- warn && console.warn( 'Relation=%o; no model, key or relatedModel (%o, %o, %o)', this, m, k, rm );
- return false;
- }
- // Check if the type in 'model' inherits from Backbone.RelationalModel
- if ( !( m.prototype instanceof Backbone.RelationalModel ) ) {
- warn && console.warn( 'Relation=%o; model does not inherit from Backbone.RelationalModel (%o)', this, i );
- return false;
- }
- // Check if the type in 'relatedModel' inherits from Backbone.RelationalModel
- if ( !( rm.prototype instanceof Backbone.RelationalModel ) ) {
- warn && console.warn( 'Relation=%o; relatedModel does not inherit from Backbone.RelationalModel (%o)', this, rm );
- return false;
- }
- // Check if this is not a HasMany, and the reverse relation is HasMany as well
- if ( this instanceof Backbone.HasMany && this.reverseRelation.type === Backbone.HasMany ) {
- warn && console.warn( 'Relation=%o; relation is a HasMany, and the reverseRelation is HasMany as well.', this );
- return false;
- }
-
- // Check if we're not attempting to create a duplicate relationship
- if ( i && i._relations.length ) {
- var exists = _.any( i._relations, function( rel ) {
- var hasReverseRelation = this.reverseRelation.key && rel.reverseRelation.key;
- return rel.relatedModel === rm && rel.key === k &&
- ( !hasReverseRelation || this.reverseRelation.key === rel.reverseRelation.key );
- }, this );
-
- if ( exists ) {
- warn && console.warn( 'Relation=%o between instance=%o.%s and relatedModel=%o.%s already exists',
- this, i, k, rm, this.reverseRelation.key );
- return false;
- }
- }
-
- return true;
- },
-
- /**
- * Set the related model(s) for this relation
- * @param {Backbone.Mode|Backbone.Collection} related
- * @param {Object} [options]
- */
- setRelated: function( related, options ) {
- this.related = related;
-
- this.instance.acquire();
- this.instance.set( this.key, related, _.defaults( options || {}, { silent: true } ) );
- this.instance.release();
- },
-
- /**
- * Determine if a relation (on a different RelationalModel) is the reverse
- * relation of the current one.
- * @param {Backbone.Relation} relation
- * @return {Boolean}
- */
- _isReverseRelation: function( relation ) {
- if ( relation.instance instanceof this.relatedModel && this.reverseRelation.key === relation.key &&
- this.key === relation.reverseRelation.key ) {
- return true;
- }
- return false;
- },
-
- /**
- * Get the reverse relations (pointing back to 'this.key' on 'this.instance') for the currently related model(s).
- * @param {Backbone.RelationalModel} [model] Get the reverse relations for a specific model.
- * If not specified, 'this.related' is used.
- * @return {Backbone.Relation[]}
- */
- getReverseRelations: function( model ) {
- var reverseRelations = [];
- // Iterate over 'model', 'this.related.models' (if this.related is a Backbone.Collection), or wrap 'this.related' in an array.
- var models = !_.isUndefined( model ) ? [ model ] : this.related && ( this.related.models || [ this.related ] );
- _.each( models , function( related ) {
- _.each( related.getRelations(), function( relation ) {
- if ( this._isReverseRelation( relation ) ) {
- reverseRelations.push( relation );
- }
- }, this );
- }, this );
-
- return reverseRelations;
- },
-
- /**
- * Rename options.silent to options.silentChange, so events propagate properly.
- * (for example in HasMany, from 'addRelated'->'handleAddition')
- * @param {Object} [options]
- * @return {Object}
- */
- sanitizeOptions: function( options ) {
- options = options ? _.clone( options ) : {};
- if ( options.silent ) {
- options.silentChange = true;
- delete options.silent;
- }
- return options;
- },
-
- /**
- * Rename options.silentChange to options.silent, so events are silenced as intended in Backbone's
- * original functions.
- * @param {Object} [options]
- * @return {Object}
- */
- unsanitizeOptions: function( options ) {
- options = options ? _.clone( options ) : {};
- if ( options.silentChange ) {
- options.silent = true;
- delete options.silentChange;
- }
- return options;
- },
-
- // Cleanup. Get reverse relation, call removeRelated on each.
- destroy: function() {
- Backbone.Relational.store.getCollection( this.instance )
- .unbind( 'relational:remove', this._modelRemovedFromCollection );
-
- Backbone.Relational.store.getCollection( this.relatedModel )
- .unbind( 'relational:add', this._relatedModelAdded )
- .unbind( 'relational:remove', this._relatedModelRemoved );
-
- _.each( this.getReverseRelations(), function( relation ) {
- relation.removeRelated( this.instance );
- }, this );
- }
- });
-
- Backbone.HasOne = Backbone.Relation.extend({
- options: {
- reverseRelation: { type: 'HasMany' }
- },
-
- initialize: function() {
- _.bindAll( this, 'onChange' );
-
- this.instance.bind( 'relational:change:' + this.key, this.onChange );
-
- var model = this.findRelated( { silent: true } );
- this.setRelated( model );
-
- // Notify new 'related' object of the new relation.
- _.each( this.getReverseRelations(), function( relation ) {
- relation.addRelated( this.instance );
- }, this );
- },
-
- findRelated: function( options ) {
- var item = this.keyContents;
- var model = null;
-
- if ( item instanceof this.relatedModel ) {
- model = item;
- }
- else if ( item || item === 0 ) { // since 0 can be a valid `id` as well
- model = this.relatedModel.findOrCreate( item, { create: this.options.createModels } );
- }
-
- return model;
- },
-
- /**
- * If the key is changed, notify old & new reverse relations and initialize the new relation
- */
- onChange: function( model, attr, options ) {
- // Don't accept recursive calls to onChange (like onChange->findRelated->findOrCreate->initializeRelations->addRelated->onChange)
- if ( this.isLocked() ) {
- return;
- }
- this.acquire();
- options = this.sanitizeOptions( options );
-
- // 'options._related' is set by 'addRelated'/'removeRelated'. If it is set, the change
- // is the result of a call from a relation. If it's not, the change is the result of
- // a 'set' call on this.instance.
- var changed = _.isUndefined( options._related );
- var oldRelated = changed ? this.related : options._related;
-
- if ( changed ) {
- this.keyContents = attr;
-
- // Set new 'related'
- if ( attr instanceof this.relatedModel ) {
- this.related = attr;
- }
- else if ( attr ) {
- var related = this.findRelated( options );
- this.setRelated( related );
- }
- else {
- this.setRelated( null );
- }
- }
-
- // Notify old 'related' object of the terminated relation
- if ( oldRelated && this.related !== oldRelated ) {
- _.each( this.getReverseRelations( oldRelated ), function( relation ) {
- relation.removeRelated( this.instance, options );
- }, this );
- }
-
- // Notify new 'related' object of the new relation. Note we do re-apply even if this.related is oldRelated;
- // that can be necessary for bi-directional relations if 'this.instance' was created after 'this.related'.
- // In that case, 'this.instance' will already know 'this.related', but the reverse might not exist yet.
- _.each( this.getReverseRelations(), function( relation ) {
- relation.addRelated( this.instance, options );
- }, this);
-
- // Fire the 'update:<key>' event if 'related' was updated
- if ( !options.silentChange && this.related !== oldRelated ) {
- var dit = this;
- Backbone.Relational.eventQueue.add( function() {
- dit.instance.trigger( 'update:' + dit.key, dit.instance, dit.related, options );
- });
- }
- this.release();
- },
-
- /**
- * If a new 'this.relatedModel' appears in the 'store', try to match it to the last set 'keyContents'
- */
- tryAddRelated: function( model, options ) {
- if ( this.related ) {
- return;
- }
- options = this.sanitizeOptions( options );
-
- var item = this.keyContents;
- if ( item || item === 0 ) { // since 0 can be a valid `id` as well
- var id = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item );
- if ( !_.isNull( id ) && model.id === id ) {
- this.addRelated( model, options );
- }
- }
- },
-
- addRelated: function( model, options ) {
- if ( model !== this.related ) {
- var oldRelated = this.related || null;
- this.setRelated( model );
- this.onChange( this.instance, model, { _related: oldRelated } );
- }
- },
-
- removeRelated: function( model, options ) {
- if ( !this.related ) {
- return;
- }
-
- if ( model === this.related ) {
- var oldRelated = this.related || null;
- this.setRelated( null );
- this.onChange( this.instance, model, { _related: oldRelated } );
- }
- }
- });
-
- Backbone.HasMany = Backbone.Relation.extend({
- collectionType: null,
-
- options: {
- reverseRelation: { type: 'HasOne' },
- collectionType: Backbone.Collection,
- collectionKey: true,
- collectionOptions: {}
- },
-
- initialize: function() {
- _.bindAll( this, 'onChange', 'handleAddition', 'handleRemoval', 'handleReset' );
- this.instance.bind( 'relational:change:' + this.key, this.onChange );
-
- // Handle a custom 'collectionType'
- this.collectionType = this.options.collectionType;
- if ( _.isString( this.collectionType ) ) {
- this.collectionType = Backbone.Relational.store.getObjectByName( this.collectionType );
- }
- if ( !this.collectionType.prototype instanceof Backbone.Collection ){
- throw new Error( 'collectionType must inherit from Backbone.Collection' );
- }
-
- // Handle cases where a model/relation is created with a collection passed straight into 'attributes'
- if ( this.keyContents instanceof Backbone.Collection ) {
- this.setRelated( this._prepareCollection( this.keyContents ) );
- }
- else {
- this.setRelated( this._prepareCollection() );
- }
-
- this.findRelated( { silent: true } );
- },
-
- _getCollectionOptions: function() {
- return _.isFunction( this.options.collectionOptions ) ?
- this.options.collectionOptions( this.instance ) :
- this.options.collectionOptions;
- },
-
- /**
- * Bind events and setup collectionKeys for a collection that is to be used as the backing store for a HasMany.
- * If no 'collection' is supplied, a new collection will be created of the specified 'collectionType' option.
- * @param {Backbone.Collection} [collection]
- */
- _prepareCollection: function( collection ) {
- if ( this.related ) {
- this.related
- .unbind( 'relational:add', this.handleAddition )
- .unbind( 'relational:remove', this.handleRemoval )
- .unbind( 'relational:reset', this.handleReset )
- }
-
- if ( !collection || !( collection instanceof Backbone.Collection ) ) {
- collection = new this.collectionType( [], this._getCollectionOptions() );
- }
-
- collection.model = this.relatedModel;
-
- if ( this.options.collectionKey ) {
- var key = this.options.collectionKey === true ? this.options.reverseRelation.key : this.options.collectionKey;
-
- if ( collection[ key ] && collection[ key ] !== this.instance ) {
- if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) {
- console.warn( 'Relation=%o; collectionKey=%s already exists on collection=%o', this, key, this.options.collectionKey );
- }
- }
- else if ( key ) {
- collection[ key ] = this.instance;
- }
- }
-
- collection
- .bind( 'relational:add', this.handleAddition )
- .bind( 'relational:remove', this.handleRemoval )
- .bind( 'relational:reset', this.handleReset );
-
- return collection;
- },
-
- findRelated: function( options ) {
- if ( this.keyContents ) {
- var models = [];
-
- if ( this.keyContents instanceof Backbone.Collection ) {
- models = this.keyContents.models;
- }
- else {
- // Handle cases the an API/user supplies just an Object/id instead of an Array
- this.keyContents = _.isArray( this.keyContents ) ? this.keyContents : [ this.keyContents ];
-
- // Try to find instances of the appropriate 'relatedModel' in the store
- _.each( this.keyContents, function( item ) {
- var model = null;
- if ( item instanceof this.relatedModel ) {
- model = item;
- }
- else if ( item || item === 0 ) { // since 0 can be a valid `id` as well
- model = this.relatedModel.findOrCreate( item, { create: this.options.createModels } );
- }
-
- if ( model && !this.related.getByCid( model ) && !this.related.get( model ) ) {
- models.push( model );
- }
- }, this );
- }
-
- // Add all found 'models' in on go, so 'add' will only be called once (and thus 'sort', etc.)
- if ( models.length ) {
- options = this.unsanitizeOptions( options );
- this.related.add( models, options );
- }
- }
- },
-
- /**
- * If the key is changed, notify old & new reverse relations and initialize the new relation
- */
- onChange: function( model, attr, options ) {
- options = this.sanitizeOptions( options );
- this.keyContents = attr;
-
- // Notify old 'related' object of the terminated relation
- _.each( this.getReverseRelations(), function( relation ) {
- relation.removeRelated( this.instance, options );
- }, this );
-
- // Replace 'this.related' by 'attr' if it is a Backbone.Collection
- if ( attr instanceof Backbone.Collection ) {
- this._prepareCollection( attr );
- this.related = attr;
- }
- // Otherwise, 'attr' should be an array of related object ids.
- // Re-use the current 'this.related' if it is a Backbone.Collection, and remove any current entries.
- // Otherwise, create a new collection.
- else {
- var coll;
-
- if ( this.related instanceof Backbone.Collection ) {
- coll = this.related;
- coll.remove( coll.models );
- }
- else {
- coll = this._prepareCollection();
- }
-
- this.setRelated( coll );
- this.findRelated( options );
- }
-
- // Notify new 'related' object of the new relation
- _.each( this.getReverseRelations(), function( relation ) {
- relation.addRelated( this.instance, options );
- }, this );
-
- var dit = this;
- Backbone.Relational.eventQueue.add( function() {
- !options.silentChange && dit.instance.trigger( 'update:' + dit.key, dit.instance, dit.related, options );
- });
- },
-
- tryAddRelated: function( model, options ) {
- options = this.sanitizeOptions( options );
- if ( !this.related.getByCid( model ) && !this.related.get( model ) ) {
- // Check if this new model was specified in 'this.keyContents'
- var item = _.any( this.keyContents, function( item ) {
- var id = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item );
- return !_.isNull( id ) && id === model.id;
- }, this );
-
- if ( item ) {
- this.related.add( model, options );
- }
- }
- },
-
- /**
- * When a model is added to a 'HasMany', trigger 'add' on 'this.instance' and notify reverse relations.
- * (should be 'HasOne', must set 'this.instance' as their related).
- */
- handleAddition: function( model, coll, options ) {
- //console.debug('handleAddition called; args=%o', arguments);
- // Make sure the model is in fact a valid model before continuing.
- // (it can be invalid as a result of failing validation in Backbone.Collection._prepareModel)
- if ( !( model instanceof Backbone.Model ) ) {
- return;
- }
-
- options = this.sanitizeOptions( options );
-
- _.each( this.getReverseRelations( model ), function( relation ) {
- relation.addRelated( this.instance, options );
- }, this );
-
- // Only trigger 'add' once the newly added model is initialized (so, has it's relations set up)
- var dit = this;
- Backbone.Relational.eventQueue.add( function() {
- !options.silentChange && dit.instance.trigger( 'add:' + dit.key, model, dit.related, options );
- });
- },
-
- /**
- * When a model is removed from a 'HasMany', trigger 'remove' on 'this.instance' and notify reverse relations.
- * (should be 'HasOne', which should be nullified)
- */
- handleRemoval: function( model, coll, options ) {
- //console.debug('handleRemoval called; args=%o', arguments);
- if ( !( model instanceof Backbone.Model ) ) {
- return;
- }
-
- options = this.sanitizeOptions( options );
-
- _.each( this.getReverseRelations( model ), function( relation ) {
- relation.removeRelated( this.instance, options );
- }, this );
-
- var dit = this;
- Backbone.Relational.eventQueue.add( function() {
- !options.silentChange && dit.instance.trigger( 'remove:' + dit.key, model, dit.related, options );
- });
- },
-
- handleReset: function( coll, options ) {
- options = this.sanitizeOptions( options );
-
- var dit = this;
- Backbone.Relational.eventQueue.add( function() {
- !options.silentChange && dit.instance.trigger( 'reset:' + dit.key, dit.related, options );
- });
- },
-
- addRelated: function( model, options ) {
- var dit = this;
- options = this.unsanitizeOptions( options );
- model.queue( function() { // Queued to avoid errors for adding 'model' to the 'this.related' set twice
- if ( dit.related && !dit.related.getByCid( model ) && !dit.related.get( model ) ) {
- dit.related.add( model, options );
- }
- });
- },
-
- removeRelated: function( model, options ) {
- options = this.unsanitizeOptions( options );
- if ( this.related.getByCid( model ) || this.related.get( model ) ) {
- this.related.remove( model, options );
- }
- }
- });
-
- /**
- * A type of Backbone.Model that also maintains relations to other models and collections.
- * New events when compared to the original:
- * - 'add:<key>' (model, related collection, options)
- * - 'remove:<key>' (model, related collection, options)
- * - 'update:<key>' (model, related model or collection, options)
- */
- Backbone.RelationalModel = Backbone.Model.extend({
- relations: null, // Relation descriptions on the prototype
- _relations: null, // Relation instances
- _isInitialized: false,
- _deferProcessing: false,
- _queue: null,
-
- subModelTypeAttribute: 'type',
- subModelTypes: null,
-
- constructor: function( attributes, options ) {
- // Nasty hack, for cases like 'model.get( <HasMany key> ).add( item )'.
- // Defer 'processQueue', so that when 'Relation.createModels' is used we:
- // a) Survive 'Backbone.Collection.add'; this takes care we won't error on "can't add model to a set twice"
- // (by creating a model from properties, having the model add itself to the collection via one of
- // it's relations, then trying to add it to the collection).
- // b) Trigger 'HasMany' collection events only after the model is really fully set up.
- // Example that triggers both a and b: "p.get('jobs').add( { company: c, person: p } )".
- var dit = this;
- if ( options && options.collection ) {
- this._deferProcessing = true;
-
- var processQueue = function( model ) {
- if ( model === dit ) {
- dit._deferProcessing = false;
- dit.processQueue();
- options.collection.unbind( 'relational:add', processQueue );
- }
- };
- options.collection.bind( 'relational:add', processQueue );
-
- // So we do process the queue eventually, regardless of whether this model really gets added to 'options.collection'.
- _.defer( function() {
- processQueue( dit );
- });
- }
-
- this._queue = new Backbone.BlockingQueue();
- this._queue.block();
- Backbone.Relational.eventQueue.block();
-
- Backbone.Model.apply( this, arguments );
-
- // Try to run the global queue holding external events
- Backbone.Relational.eventQueue.unblock();
- },
-
- /**
- * Override 'trigger' to queue 'change' and 'change:*' events
- */
- trigger: function( eventName ) {
- if ( eventName.length > 5 && 'change' === eventName.substr( 0, 6 ) ) {
- var dit = this, args = arguments;
- Backbone.Relational.eventQueue.add( function() {
- Backbone.Model.prototype.trigger.apply( dit, args );
- });
- }
- else {
- Backbone.Model.prototype.trigger.apply( this, arguments );
- }
-
- return this;
- },
-
- /**
- * Initialize Relations present in this.relations; determine the type (HasOne/HasMany), then creates a new instance.
- * Invoked in the first call so 'set' (which is made from the Backbone.Model constructor).
- */
- initializeRelations: function() {
- this.acquire(); // Setting up relations often also involve calls to 'set', and we only want to enter this function once
- this._relations = [];
-
- _.each( this.relations, function( rel ) {
- var type = !_.isString( rel.type ) ? rel.type : Backbone[ rel.type ] || Backbone.Relational.store.getObjectByName( rel.type );
- if ( type && type.prototype instanceof Backbone.Relation ) {
- new type( this, rel ); // Also pushes the new Relation into _relations
- }
- else {
- Backbone.Relational.showWarnings && typeof console !== 'undefined' && console.warn( 'Relation=%o; missing or invalid type!', rel );
- }
- }, this );
-
- this._isInitialized = true;
- this.release();
- this.processQueue();
- },
-
- /**
- * When new values are set, notify this model's relations (also if options.silent is set).
- * (Relation.setRelated locks this model before calling 'set' on it to prevent loops)
- */
- updateRelations: function( options ) {
- if ( this._isInitialized && !this.isLocked() ) {
- _.each( this._relations, function( rel ) {
- // Update from data in `rel.keySource` if set, or `rel.key` otherwise
- var val = this.attributes[ rel.keySource ] || this.attributes[ rel.key ];
- if ( rel.related !== val ) {
- this.trigger( 'relational:change:' + rel.key, this, val, options || {} );
- }
- }, this );
- }
- },
-
- /**
- * Either add to the queue (if we're not initialized yet), or execute right away.
- */
- queue: function( func ) {
- this._queue.add( func );
- },
-
- /**
- * Process _queue
- */
- processQueue: function() {
- if ( this._isInitialized && !this._deferProcessing && this._queue.isBlocked() ) {
- this._queue.unblock();
- }
- },
-
- /**
- * Get a specific relation.
- * @param key {string} The relation key to look for.
- * @return {Backbone.Relation} An instance of 'Backbone.Relation', if a relation was found for 'key', or null.
- */
- getRelation: function( key ) {
- return _.detect( this._relations, function( rel ) {
- if ( rel.key === key ) {
- return true;
- }
- }, this );
- },
-
- /**
- * Get all of the created relations.
- * @return {Backbone.Relation[]}
- */
- getRelations: function() {
- return this._relations;
- },
-
- /**
- * Retrieve related objects.
- * @param key {string} The relation key to fetch models for.
- * @param [options] {Object} Options for 'Backbone.Model.fetch' and 'Backbone.sync'.
- * @param [update=false] {boolean} Whether to force a fetch from the server (updating existing models).
- * @return {jQuery.when[]} An array of request objects
- */
- fetchRelated: function( key, options, update ) {
- options || ( options = {} );
- var setUrl,
- requests = [],
- rel = this.getRelation( key ),
- keyContents = rel && rel.keyContents,
- toFetch = keyContents && _.select( _.isArray( keyContents ) ? keyContents : [ keyContents ], function( item ) {
- var id = Backbone.Relational.store.resolveIdForItem( rel.relatedModel, item );
- return !_.isNull( id ) && ( update || !Backbone.Relational.store.find( rel.relatedModel, id ) );
- }, this );
-
- if ( toFetch && toFetch.length ) {
- // Create a model for each entry in 'keyContents' that is to be fetched
- var models = _.map( toFetch, function( item ) {
- var model;
-
- if ( _.isObject( item ) ) {
- model = rel.relatedModel.build( item );
- }
- else {
- var attrs = {};
- attrs[ rel.relatedModel.prototype.idAttribute ] = item;
- model = rel.relatedModel.build( attrs );
- }
-
- return model;
- }, this );
-
- // Try if the 'collection' can provide a url to fetch a set of models in one request.
- if ( rel.related instanceof Backbone.Collection && _.isFunction( rel.related.url ) ) {
- setUrl = rel.related.url( models );
- }
-
- // An assumption is that when 'Backbone.Collection.url' is a function, it can handle building of set urls.
- // To make sure it can, test if the url we got by supplying a list of models to fetch is different from
- // the one supplied for the default fetch action (without args to 'url').
- if ( setUrl && setUrl !== rel.related.url() ) {
- var opts = _.defaults(
- {
- error: function() {
- var args = arguments;
- _.each( models, function( model ) {
- model.trigger( 'destroy', model, model.collection, options );
- options.error && options.error.apply( model, args );
- });
- },
- url: setUrl
- },
- options,
- { add: true }
- );
-
- requests = [ rel.related.fetch( opts ) ];
- }
- else {
- requests = _.map( models, function( model ) {
- var opts = _.defaults(
- {
- error: function() {
- model.trigger( 'destroy', model, model.collection, options );
- options.error && options.error.apply( model, arguments );
- }
- },
- options
- );
- return model.fetch( opts );
- }, this );
- }
- }
-
- return requests;
- },
-
- set: function( key, value, options ) {
- Backbone.Relational.eventQueue.block();
-
- // Duplicate backbone's behavior to allow separate key/value parameters, instead of a single 'attributes' object
- var attributes;
- if ( _.isObject( key ) || key == null ) {
- attributes = key;
- options = value;
- }
- else {
- attributes = {};
- attributes[ key ] = value;
- }
-
- var result = Backbone.Model.prototype.set.apply( this, arguments );
-
- // Ideal place to set up relations :)
- if ( !this._isInitialized && !this.isLocked() ) {
- this.constructor.initializeModelHierarchy();
-
- Backbone.Relational.store.register( this );
-
- this.initializeRelations();
- }
- // Update the 'idAttribute' in Backbone.store if; we don't want it to miss an 'id' update due to {silent:true}
- else if ( attributes && this.idAttribute in attributes ) {
- Backbone.Relational.store.update( this );
- }
-
- if ( attributes ) {
- this.updateRelations( options );
- }
-
- // Try to run the global queue holding external events
- Backbone.Relational.eventQueue.unblock();
-
- return result;
- },
-
- unset: function( attribute, options ) {
- Backbone.Relational.eventQueue.block();
-
- var result = Backbone.Model.prototype.unset.apply( this, arguments );
- this.updateRelations( options );
-
- // Try to run the global queue holding external events
- Backbone.Relational.eventQueue.unblock();
-
- return result;
- },
-
- clear: function( options ) {
- Backbone.Relational.eventQueue.block();
-
- var result = Backbone.Model.prototype.clear.apply( this, arguments );
- this.updateRelations( options );
-
- // Try to run the global queue holding external events
- Backbone.Relational.eventQueue.unblock();
-
- return result;
- },
-
- /**
- * Override 'change', so the change will only execute after 'set' has finised (relations are updated),
- * and 'previousAttributes' will be available when the event is fired.
- */
- change: function( options ) {
- var dit = this, args = arguments;
- Backbone.Relational.eventQueue.add( function() {
- Backbone.Model.prototype.change.apply( dit, args );
- });
- },
-
- clone: function() {
- var attributes = _.clone( this.attributes );
- if ( !_.isUndefined( attributes[ this.idAttribute ] ) ) {
- attributes[ this.idAttribute ] = null;
- }
-
- _.each( this.getRelations(), function( rel ) {
- delete attributes[ rel.key ];
- });
-
- return new this.constructor( attributes );
- },
-
- /**
- * Convert relations to JSON, omits them when required
- */
- toJSON: function() {
- // If this Model has already been fully serialized in this branch once, return to avoid loops
- if ( this.isLocked() ) {
- return this.id;
- }
-
- this.acquire();
- var json = Backbone.Model.prototype.toJSON.call( this );
-
- if ( this.constructor._superModel && !( this.constructor._subModelTypeAttribute in json ) ) {
- json[ this.constructor._subModelTypeAttribute ] = this.constructor._subModelTypeValue;
- }
-
- _.each( this._relations, function( rel ) {
- var value = json[ rel.key ];
-
- if ( rel.options.includeInJSON === true) {
- if ( value && _.isFunction( value.toJSON ) ) {
- json[ rel.keyDestination ] = value.toJSON();
- }
- else {
- json[ rel.keyDestination ] = null;
- }
- }
- else if ( _.isString( rel.options.includeInJSON ) ) {
- if ( value instanceof Backbone.Collection ) {
- json[ rel.keyDestination ] = value.pluck( rel.options.includeInJSON );
- }
- else if ( value instanceof Backbone.Model ) {
- json[ rel.keyDestination ] = value.get( rel.options.includeInJSON );
- }
- else {
- json[ rel.keyDestination ] = null;
- }
- }
- else if ( _.isArray( rel.options.includeInJSON ) ) {
- if ( value instanceof Backbone.Collection ) {
- var valueSub = [];
- value.each( function( model ) {
- var curJson = {};
- _.each( rel.options.includeInJSON, function( key ) {
- curJson[ key ] = model.get( key );
- });
- valueSub.push( curJson );
- });
- json[ rel.keyDestination ] = valueSub;
- }
- else if ( value instanceof Backbone.Model ) {
- var valueSub = {};
- _.each( rel.options.includeInJSON, function( key ) {
- valueSub[ key ] = value.get( key );
- });
- json[ rel.keyDestination ] = valueSub;
- }
- else {
- json[ rel.keyDestination ] = null;
- }
- }
- else {
- delete json[ rel.key ];
- }
-
- if ( rel.keyDestination !== rel.key ) {
- delete json[ rel.key ];
- }
- });
-
- this.release();
- return json;
- }
- },
- {
- setup: function( superModel ) {
- // We don't want to share a relations array with a parent, as this will cause problems with
- // reverse relations.
- this.prototype.relations = ( this.prototype.relations || [] ).slice( 0 );
-
- this._subModels = {};
- this._superModel = null;
-
- // If this model has 'subModelTypes' itself, remember them in the store
- if ( this.prototype.hasOwnProperty( 'subModelTypes' ) ) {
- Backbone.Relational.store.addSubModels( this.prototype.subModelTypes, this );
- }
- // The 'subModelTypes' property should not be inherited, so reset it.
- else {
- this.prototype.subModelTypes = null;
- }
-
- // Initialize all reverseRelations that belong to this new model.
- _.each( this.prototype.relations, function( rel ) {
- if ( !rel.model ) {
- rel.model = this;
- }
-
- if ( rel.reverseRelation && rel.model === this ) {
- var preInitialize = true;
- if ( _.isString( rel.relatedModel ) ) {
- /**
- * The related model might not be defined for two reasons
- * 1. it never gets defined, e.g. a typo
- * 2. it is related to itself
- * In neither of these cases do we need to pre-initialize reverse relations.
- */
- var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel );
- preInitialize = relatedModel && ( relatedModel.prototype instanceof Backbone.RelationalModel );
- }
-
- var type = !_.isString( rel.type ) ? rel.type : Backbone[ rel.type ] || Backbone.Relational.store.getObjectByName( rel.type );
- if ( preInitialize && type && type.prototype instanceof Backbone.Relation ) {
- new type( null, rel );
- }
- }
- }, this );
-
- return this;
- },
-
- /**
- * Create a 'Backbone.Model' instance based on 'attributes'.
- * @param {Object} attributes
- * @param {Object} [options]
- * @return {Backbone.Model}
- */
- build: function( attributes, options ) {
- var model = this;
-
- // 'build' is a possible entrypoint; it's possible no model hierarchy has been determined yet.
- this.initializeModelHierarchy();
-
- // Determine what type of (sub)model should be built if applicable.
- // Lookup the proper subModelType in 'this._subModels'.
- if ( this._subModels && this.prototype.subModelTypeAttribute in attributes ) {
- var subModelTypeAttribute = attributes[ this.prototype.subModelTypeAttribute ];
- var subModelType = this._subModels[ subModelTypeAttribute ];
- if ( subModelType ) {
- model = subModelType;
- }
- }
-
- return new model( attributes, options );
- },
-
- initializeModelHierarchy: function() {
- // If we're here for the first time, try to determine if this modelType has a 'superModel'.
- if ( _.isUndefined( this._superModel ) || _.isNull( this._superModel ) ) {
- Backbone.Relational.store.setupSuperModel( this );
-
- // If a superModel has been found, copy relations from the _superModel if they haven't been
- // inherited automatically (due to a redefinition of 'relations').
- // Otherwise, make sure we don't get here again for this type by making '_superModel' false so we fail
- // the isUndefined/isNull check next time.
- if ( this._superModel ) {
- //
- if ( this._superModel.prototype.relations ) {
- var supermodelRelationsExist = _.any( this.prototype.relations, function( rel ) {
- return rel.model && rel.model !== this;
- }, this );
-
- if ( !supermodelRelationsExist ) {
- this.prototype.relations = this._superModel.prototype.relations.concat( this.prototype.relations );
- }
- }
- }
- else {
- this._superModel = false;
- }
- }
-
- // If we came here through 'build' for a model that has 'subModelTypes', and not all of them have been resolved yet, try to resolve each.
- if ( this.prototype.subModelTypes && _.keys( this.prototype.subModelTypes ).length !== _.keys( this._subModels ).length ) {
- _.each( this.prototype.subModelTypes, function( subModelTypeName ) {
- var subModelType = Backbone.Relational.store.getObjectByName( subModelTypeName );
- subModelType && subModelType.initializeModelHierarchy();
- });
- }
- },
-
- /**
- * Find an instance of `this` type in 'Backbone.Relational.store'.
- * - If `attributes` is a string or a number, `findOrCreate` will just query the `store` and return a model if found.
- * - If `attributes` is an object, the model will be updated with `attributes` if found.
- * Otherwise, a new model is created with `attributes` (unless `options.create` is explicitly set to `false`).
- * @param {Object|String|Number} attributes Either a model's id, or the attributes used to create or update a model.
- * @param {Object} [options]
- * @param {Boolean} [options.create=true]
- * @return {Backbone.RelationalModel}
- */
- findOrCreate: function( attributes, options ) {
- // Try to find an instance of 'this' model type in the store
- var model = Backbone.Relational.store.find( this, attributes );
-
- // If we found an instance, update it with the data in 'item'; if not, create an instance
- // (unless 'options.create' is false).
- if ( _.isObject( attributes ) ) {
- if ( model ) {
- model.set( model.parse ? model.parse( attributes ) : attributes, options );
- }
- else if ( !options || ( options && options.create !== false ) ) {
- model = this.build( attributes, options );
- }
- }
-
- return model;
- }
- });
- _.extend( Backbone.RelationalModel.prototype, Backbone.Semaphore );
-
- /**
- * Override Backbone.Collection._prepareModel, so objects will be built using the correct type
- * if the collection.model has subModels.
- */
- Backbone.Collection.prototype.__prepareModel = Backbone.Collection.prototype._prepareModel;
- Backbone.Collection.prototype._prepareModel = function ( model, options ) {
- options || (options = {});
- if ( !( model instanceof Backbone.Model ) ) {
- var attrs = model;
- options.collection = this;
-
- if ( typeof this.model.findOrCreate !== 'undefined' ) {
- model = this.model.findOrCreate( attrs, options );
- }
- else {
- model = new this.model( attrs, options );
- }
-
- if ( !model._validate( model.attributes, options ) ) {
- model = false;
- }
- }
- else if ( !model.collection ) {
- model.collection = this;
- }
-
- return model;
- }
-
- /**
- * Override Backbone.Collection.add, so objects fetched from the server multiple times will
- * update the existing Model. Also, trigger 'relational:add'.
- */
- var add = Backbone.Collection.prototype.__add = Backbone.Collection.prototype.add;
- Backbone.Collection.prototype.add = function( models, options ) {
- options || (options = {});
- if ( !_.isArray( models ) ) {
- models = [ models ];
- }
-
- var modelsToAdd = [];
-
- //console.debug( 'calling add on coll=%o; model=%o, options=%o', this, models, options );
- _.each( models, function( model ) {
- if ( !( model instanceof Backbone.Model ) ) {
- // `_prepareModel` attempts to find `model` in Backbone.store through `findOrCreate`,
- // and sets the new properties on it if is found. Otherwise, a new model is instantiated.
- model = Backbone.Collection.prototype._prepareModel.call( this, model, options );
- }
-
- if ( model instanceof Backbone.Model && !this.get( model ) && !this.getByCid( model ) ) {
- modelsToAdd.push( model );
- }
- }, this );
-
-
- // Add 'models' in a single batch, so the original add will only be called once (and thus 'sort', etc).
- if ( modelsToAdd.length ) {
- add.call( this, modelsToAdd, options );
-
- _.each( modelsToAdd, function( model ) {
- this.trigger( 'relational:add', model, this, options );
- }, this );
- }
-
- return this;
- };
-
- /**
- * Override 'Backbone.Collection.remove' to trigger 'relational:remove'.
- */
- var remove = Backbone.Collection.prototype.__remove = Backbone.Collection.prototype.remove;
- Backbone.Collection.prototype.remove = function( models, options ) {
- options || (options = {});
- if ( !_.isArray( models ) ) {
- models = [ models ];
- }
- else {
- models = models.slice( 0 );
- }
-
- //console.debug('calling remove on coll=%o; models=%o, options=%o', this, models, options );
- _.each( models, function( model ) {
- model = this.getByCid( model ) || this.get( model );
-
- if ( model instanceof Backbone.Model ) {
- remove.call( this, model, options );
- this.trigger('relational:remove', model, this, options);
- }
- }, this );
-
- return this;
- };
-
- /**
- * Override 'Backbone.Collection.reset' to trigger 'relational:reset'.
- */
- var reset = Backbone.Collection.prototype.__reset = Backbone.Collection.prototype.reset;
- Backbone.Collection.prototype.reset = function( models, options ) {
- reset.call( this, models, options );
- this.trigger( 'relational:reset', this, options );
-
- return this;
- };
-
- /**
- * Override 'Backbone.Collection.sort' to trigger 'relational:reset'.
- */
- var sort = Backbone.Collection.prototype.__sort = Backbone.Collection.prototype.sort;
- Backbone.Collection.prototype.sort = function( options ) {
- sort.call( this, options );
- this.trigger( 'relational:reset', this, options );
-
- return this;
- };
-
- /**
- * Override 'Backbone.Collection.trigger' so 'add', 'remove' and 'reset' events are queued until relations
- * are ready.
- */
- var trigger = Backbone.Collection.prototype.__trigger = Backbone.Collection.prototype.trigger;
- Backbone.Collection.prototype.trigger = function( eventName ) {
- if ( eventName === 'add' || eventName === 'remove' || eventName === 'reset' ) {
- var dit = this, args = arguments;
-
- if (eventName === 'add') {
- args = _.toArray(args);
- // the fourth argument in case of a regular add is the option object.
- // we need to clone it, as it could be modified while we wait on the eventQueue to be unblocked
- if (_.isObject(args[3])) {
- args[3] = _.clone(args[3]);
- }
- }
-
- Backbone.Relational.eventQueue.add( function() {
- trigger.apply( dit, args );
- });
- }
- else {
- trigger.apply( this, arguments );
- }
-
- return this;
- };
-
- // Override .extend() to automatically call .setup()
- Backbone.RelationalModel.extend = function( protoProps, classProps ) {
- var child = Backbone.Model.extend.apply( this, arguments );
-
- child.setup( this );
-
- return child;
- };
-})();
--- a/server/src/main/webapp/js/backbone.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1431 +0,0 @@
-// Backbone.js 0.9.2
-
-// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
-// Backbone may be freely distributed under the MIT license.
-// For all details and documentation:
-// http://backbonejs.org
-
-(function(){
-
- // Initial Setup
- // -------------
-
- // Save a reference to the global object (`window` in the browser, `global`
- // on the server).
- var root = this;
-
- // Save the previous value of the `Backbone` variable, so that it can be
- // restored later on, if `noConflict` is used.
- var previousBackbone = root.Backbone;
-
- // Create a local reference to slice/splice.
- var slice = Array.prototype.slice;
- var splice = Array.prototype.splice;
-
- // The top-level namespace. All public Backbone classes and modules will
- // be attached to this. Exported for both CommonJS and the browser.
- var Backbone;
- if (typeof exports !== 'undefined') {
- Backbone = exports;
- } else {
- Backbone = root.Backbone = {};
- }
-
- // Current version of the library. Keep in sync with `package.json`.
- Backbone.VERSION = '0.9.2';
-
- // Require Underscore, if we're on the server, and it's not already present.
- var _ = root._;
- if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
-
- // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
- var $ = root.jQuery || root.Zepto || root.ender;
-
- // Set the JavaScript library that will be used for DOM manipulation and
- // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery,
- // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an
- // alternate JavaScript library (or a mock library for testing your views
- // outside of a browser).
- Backbone.setDomLibrary = function(lib) {
- $ = lib;
- };
-
- // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
- // to its previous owner. Returns a reference to this Backbone object.
- Backbone.noConflict = function() {
- root.Backbone = previousBackbone;
- return this;
- };
-
- // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
- // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
- // set a `X-Http-Method-Override` header.
- Backbone.emulateHTTP = false;
-
- // Turn on `emulateJSON` to support legacy servers that can't deal with direct
- // `application/json` requests ... will encode the body as
- // `application/x-www-form-urlencoded` instead and will send the model in a
- // form param named `model`.
- Backbone.emulateJSON = false;
-
- // Backbone.Events
- // -----------------
-
- // Regular expression used to split event strings
- var eventSplitter = /\s+/;
-
- // A module that can be mixed in to *any object* in order to provide it with
- // custom events. You may bind with `on` or remove with `off` callback functions
- // to an event; trigger`-ing an event fires all callbacks in succession.
- //
- // var object = {};
- // _.extend(object, Backbone.Events);
- // object.on('expand', function(){ alert('expanded'); });
- // object.trigger('expand');
- //
- var Events = Backbone.Events = {
-
- // Bind one or more space separated events, `events`, to a `callback`
- // function. Passing `"all"` will bind the callback to all events fired.
- on: function(events, callback, context) {
-
- var calls, event, node, tail, list;
- if (!callback) return this;
- events = events.split(eventSplitter);
- calls = this._callbacks || (this._callbacks = {});
-
- // Create an immutable callback list, allowing traversal during
- // modification. The tail is an empty object that will always be used
- // as the next node.
- while (event = events.shift()) {
- list = calls[event];
- node = list ? list.tail : {};
- node.next = tail = {};
- node.context = context;
- node.callback = callback;
- calls[event] = {tail: tail, next: list ? list.next : node};
- }
-
- return this;
- },
-
- // Remove one or many callbacks. If `context` is null, removes all callbacks
- // with that function. If `callback` is null, removes all callbacks for the
- // event. If `events` is null, removes all bound callbacks for all events.
- off: function(events, callback, context) {
- var event, calls, node, tail, cb, ctx;
-
- // No events, or removing *all* events.
- if (!(calls = this._callbacks)) return;
- if (!(events || callback || context)) {
- delete this._callbacks;
- return this;
- }
-
- // Loop through the listed events and contexts, splicing them out of the
- // linked list of callbacks if appropriate.
- events = events ? events.split(eventSplitter) : _.keys(calls);
- while (event = events.shift()) {
- node = calls[event];
- delete calls[event];
- if (!node || !(callback || context)) continue;
- // Create a new list, omitting the indicated callbacks.
- tail = node.tail;
- while ((node = node.next) !== tail) {
- cb = node.callback;
- ctx = node.context;
- if ((callback && cb !== callback) || (context && ctx !== context)) {
- this.on(event, cb, ctx);
- }
- }
- }
-
- return this;
- },
-
- // Trigger one or many events, firing all bound callbacks. Callbacks are
- // passed the same arguments as `trigger` is, apart from the event name
- // (unless you're listening on `"all"`, which will cause your callback to
- // receive the true name of the event as the first argument).
- trigger: function(events) {
- var event, node, calls, tail, args, all, rest;
- if (!(calls = this._callbacks)) return this;
- all = calls.all;
- events = events.split(eventSplitter);
- rest = slice.call(arguments, 1);
-
- // For each event, walk through the linked list of callbacks twice,
- // first to trigger the event, then to trigger any `"all"` callbacks.
- while (event = events.shift()) {
- if (node = calls[event]) {
- tail = node.tail;
- while ((node = node.next) !== tail) {
- node.callback.apply(node.context || this, rest);
- }
- }
- if (node = all) {
- tail = node.tail;
- args = [event].concat(rest);
- while ((node = node.next) !== tail) {
- node.callback.apply(node.context || this, args);
- }
- }
- }
-
- return this;
- }
-
- };
-
- // Aliases for backwards compatibility.
- Events.bind = Events.on;
- Events.unbind = Events.off;
-
- // Backbone.Model
- // --------------
-
- // Create a new model, with defined attributes. A client id (`cid`)
- // is automatically generated and assigned for you.
- var Model = Backbone.Model = function(attributes, options) {
- var defaults;
- attributes || (attributes = {});
- if (options && options.parse) attributes = this.parse(attributes);
- if (defaults = getValue(this, 'defaults')) {
- attributes = _.extend({}, defaults, attributes);
- }
- if (options && options.collection) this.collection = options.collection;
- this.attributes = {};
- this._escapedAttributes = {};
- this.cid = _.uniqueId('c');
- this.changed = {};
- this._silent = {};
- this._pending = {};
- this.set(attributes, {silent: true});
- // Reset change tracking.
- this.changed = {};
- this._silent = {};
- this._pending = {};
- this._previousAttributes = _.clone(this.attributes);
- this.initialize.apply(this, arguments);
- };
-
- // Attach all inheritable methods to the Model prototype.
- _.extend(Model.prototype, Events, {
-
- // A hash of attributes whose current and previous value differ.
- changed: null,
-
- // A hash of attributes that have silently changed since the last time
- // `change` was called. Will become pending attributes on the next call.
- _silent: null,
-
- // A hash of attributes that have changed since the last `'change'` event
- // began.
- _pending: null,
-
- // The default name for the JSON `id` attribute is `"id"`. MongoDB and
- // CouchDB users may want to set this to `"_id"`.
- idAttribute: 'id',
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Return a copy of the model's `attributes` object.
- toJSON: function(options) {
- return _.clone(this.attributes);
- },
-
- // Get the value of an attribute.
- get: function(attr) {
- return this.attributes[attr];
- },
-
- // Get the HTML-escaped value of an attribute.
- escape: function(attr) {
- var html;
- if (html = this._escapedAttributes[attr]) return html;
- var val = this.get(attr);
- return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val);
- },
-
- // Returns `true` if the attribute contains a value that is not null
- // or undefined.
- has: function(attr) {
- return this.get(attr) != null;
- },
-
- // Set a hash of model attributes on the object, firing `"change"` unless
- // you choose to silence it.
- set: function(key, value, options) {
- var attrs, attr, val;
-
- // Handle both `"key", value` and `{key: value}` -style arguments.
- if (_.isObject(key) || key == null) {
- attrs = key;
- options = value;
- } else {
- attrs = {};
- attrs[key] = value;
- }
-
- // Extract attributes and options.
- options || (options = {});
- if (!attrs) return this;
- if (attrs instanceof Model) attrs = attrs.attributes;
- if (options.unset) for (attr in attrs) attrs[attr] = void 0;
-
- // Run validation.
- if (!this._validate(attrs, options)) return false;
-
- // Check for changes of `id`.
- if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
-
- var changes = options.changes = {};
- var now = this.attributes;
- var escaped = this._escapedAttributes;
- var prev = this._previousAttributes || {};
-
- // For each `set` attribute...
- for (attr in attrs) {
- val = attrs[attr];
-
- // If the new and current value differ, record the change.
- if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
- delete escaped[attr];
- (options.silent ? this._silent : changes)[attr] = true;
- }
-
- // Update or delete the current value.
- options.unset ? delete now[attr] : now[attr] = val;
-
- // If the new and previous value differ, record the change. If not,
- // then remove changes for this attribute.
- if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
- this.changed[attr] = val;
- if (!options.silent) this._pending[attr] = true;
- } else {
- delete this.changed[attr];
- delete this._pending[attr];
- }
- }
-
- // Fire the `"change"` events.
- if (!options.silent) this.change(options);
- return this;
- },
-
- // Remove an attribute from the model, firing `"change"` unless you choose
- // to silence it. `unset` is a noop if the attribute doesn't exist.
- unset: function(attr, options) {
- (options || (options = {})).unset = true;
- return this.set(attr, null, options);
- },
-
- // Clear all attributes on the model, firing `"change"` unless you choose
- // to silence it.
- clear: function(options) {
- (options || (options = {})).unset = true;
- return this.set(_.clone(this.attributes), options);
- },
-
- // Fetch the model from the server. If the server's representation of the
- // model differs from its current attributes, they will be overriden,
- // triggering a `"change"` event.
- fetch: function(options) {
- options = options ? _.clone(options) : {};
- var model = this;
- var success = options.success;
- options.success = function(resp, status, xhr) {
- if (!model.set(model.parse(resp, xhr), options)) return false;
- if (success) success(model, resp);
- };
- options.error = Backbone.wrapError(options.error, model, options);
- return (this.sync || Backbone.sync).call(this, 'read', this, options);
- },
-
- // Set a hash of model attributes, and sync the model to the server.
- // If the server returns an attributes hash that differs, the model's
- // state will be `set` again.
- save: function(key, value, options) {
- var attrs, current;
-
- // Handle both `("key", value)` and `({key: value})` -style calls.
- if (_.isObject(key) || key == null) {
- attrs = key;
- options = value;
- } else {
- attrs = {};
- attrs[key] = value;
- }
- options = options ? _.clone(options) : {};
-
- // If we're "wait"-ing to set changed attributes, validate early.
- if (options.wait) {
- if (!this._validate(attrs, options)) return false;
- current = _.clone(this.attributes);
- }
-
- // Regular saves `set` attributes before persisting to the server.
- var silentOptions = _.extend({}, options, {silent: true});
- if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
- return false;
- }
-
- // After a successful server-side save, the client is (optionally)
- // updated with the server-side state.
- var model = this;
- var success = options.success;
- options.success = function(resp, status, xhr) {
- var serverAttrs = model.parse(resp, xhr);
- if (options.wait) {
- delete options.wait;
- serverAttrs = _.extend(attrs || {}, serverAttrs);
- }
- if (!model.set(serverAttrs, options)) return false;
- if (success) {
- success(model, resp);
- } else {
- model.trigger('sync', model, resp, options);
- }
- };
-
- // Finish configuring and sending the Ajax request.
- options.error = Backbone.wrapError(options.error, model, options);
- var method = this.isNew() ? 'create' : 'update';
- var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
- if (options.wait) this.set(current, silentOptions);
- return xhr;
- },
-
- // Destroy this model on the server if it was already persisted.
- // Optimistically removes the model from its collection, if it has one.
- // If `wait: true` is passed, waits for the server to respond before removal.
- destroy: function(options) {
- options = options ? _.clone(options) : {};
- var model = this;
- var success = options.success;
-
- var triggerDestroy = function() {
- model.trigger('destroy', model, model.collection, options);
- };
-
- if (this.isNew()) {
- triggerDestroy();
- return false;
- }
-
- options.success = function(resp) {
- if (options.wait) triggerDestroy();
- if (success) {
- success(model, resp);
- } else {
- model.trigger('sync', model, resp, options);
- }
- };
-
- options.error = Backbone.wrapError(options.error, model, options);
- var xhr = (this.sync || Backbone.sync).call(this, 'delete', this, options);
- if (!options.wait) triggerDestroy();
- return xhr;
- },
-
- // Default URL for the model's representation on the server -- if you're
- // using Backbone's restful methods, override this to change the endpoint
- // that will be called.
- url: function() {
- var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
- if (this.isNew()) return base;
- return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
- },
-
- // **parse** converts a response into the hash of attributes to be `set` on
- // the model. The default implementation is just to pass the response along.
- parse: function(resp, xhr) {
- return resp;
- },
-
- // Create a new model with identical attributes to this one.
- clone: function() {
- return new this.constructor(this.attributes);
- },
-
- // A model is new if it has never been saved to the server, and lacks an id.
- isNew: function() {
- return this.id == null;
- },
-
- // Call this method to manually fire a `"change"` event for this model and
- // a `"change:attribute"` event for each changed attribute.
- // Calling this will cause all objects observing the model to update.
- change: function(options) {
- options || (options = {});
- var changing = this._changing;
- this._changing = true;
-
- // Silent changes become pending changes.
- for (var attr in this._silent) this._pending[attr] = true;
-
- // Silent changes are triggered.
- var changes = _.extend({}, options.changes, this._silent);
- this._silent = {};
- for (var attr in changes) {
- this.trigger('change:' + attr, this, this.get(attr), options);
- }
- if (changing) return this;
-
- // Continue firing `"change"` events while there are pending changes.
- while (!_.isEmpty(this._pending)) {
- this._pending = {};
- this.trigger('change', this, options);
- // Pending and silent changes still remain.
- for (var attr in this.changed) {
- if (this._pending[attr] || this._silent[attr]) continue;
- delete this.changed[attr];
- }
- this._previousAttributes = _.clone(this.attributes);
- }
-
- this._changing = false;
- return this;
- },
-
- // Determine if the model has changed since the last `"change"` event.
- // If you specify an attribute name, determine if that attribute has changed.
- hasChanged: function(attr) {
- if (!arguments.length) return !_.isEmpty(this.changed);
- return _.has(this.changed, attr);
- },
-
- // Return an object containing all the attributes that have changed, or
- // false if there are no changed attributes. Useful for determining what
- // parts of a view need to be updated and/or what attributes need to be
- // persisted to the server. Unset attributes will be set to undefined.
- // You can also pass an attributes object to diff against the model,
- // determining if there *would be* a change.
- changedAttributes: function(diff) {
- if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
- var val, changed = false, old = this._previousAttributes;
- for (var attr in diff) {
- if (_.isEqual(old[attr], (val = diff[attr]))) continue;
- (changed || (changed = {}))[attr] = val;
- }
- return changed;
- },
-
- // Get the previous value of an attribute, recorded at the time the last
- // `"change"` event was fired.
- previous: function(attr) {
- if (!arguments.length || !this._previousAttributes) return null;
- return this._previousAttributes[attr];
- },
-
- // Get all of the attributes of the model at the time of the previous
- // `"change"` event.
- previousAttributes: function() {
- return _.clone(this._previousAttributes);
- },
-
- // Check if the model is currently in a valid state. It's only possible to
- // get into an *invalid* state if you're using silent changes.
- isValid: function() {
- return !this.validate(this.attributes);
- },
-
- // Run validation against the next complete set of model attributes,
- // returning `true` if all is well. If a specific `error` callback has
- // been passed, call that instead of firing the general `"error"` event.
- _validate: function(attrs, options) {
- if (options.silent || !this.validate) return true;
- attrs = _.extend({}, this.attributes, attrs);
- var error = this.validate(attrs, options);
- if (!error) return true;
- if (options && options.error) {
- options.error(this, error, options);
- } else {
- this.trigger('error', this, error, options);
- }
- return false;
- }
-
- });
-
- // Backbone.Collection
- // -------------------
-
- // Provides a standard collection class for our sets of models, ordered
- // or unordered. If a `comparator` is specified, the Collection will maintain
- // its models in sort order, as they're added and removed.
- var Collection = Backbone.Collection = function(models, options) {
- options || (options = {});
- if (options.model) this.model = options.model;
- if (options.comparator) this.comparator = options.comparator;
- this._reset();
- this.initialize.apply(this, arguments);
- if (models) this.reset(models, {silent: true, parse: options.parse});
- };
-
- // Define the Collection's inheritable methods.
- _.extend(Collection.prototype, Events, {
-
- // The default model for a collection is just a **Backbone.Model**.
- // This should be overridden in most cases.
- model: Model,
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // The JSON representation of a Collection is an array of the
- // models' attributes.
- toJSON: function(options) {
- return this.map(function(model){ return model.toJSON(options); });
- },
-
- // Add a model, or list of models to the set. Pass **silent** to avoid
- // firing the `add` event for every new model.
- add: function(models, options) {
- var i, index, length, model, cid, id, cids = {}, ids = {}, dups = [];
- options || (options = {});
- models = _.isArray(models) ? models.slice() : [models];
-
- // Begin by turning bare objects into model references, and preventing
- // invalid models or duplicate models from being added.
- for (i = 0, length = models.length; i < length; i++) {
- if (!(model = models[i] = this._prepareModel(models[i], options))) {
- throw new Error("Can't add an invalid model to a collection");
- }
- cid = model.cid;
- id = model.id;
- if (cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) {
- dups.push(i);
- continue;
- }
- cids[cid] = ids[id] = model;
- }
-
- // Remove duplicates.
- i = dups.length;
- while (i--) {
- models.splice(dups[i], 1);
- }
-
- // Listen to added models' events, and index models for lookup by
- // `id` and by `cid`.
- for (i = 0, length = models.length; i < length; i++) {
- (model = models[i]).on('all', this._onModelEvent, this);
- this._byCid[model.cid] = model;
- if (model.id != null) this._byId[model.id] = model;
- }
-
- // Insert models into the collection, re-sorting if needed, and triggering
- // `add` events unless silenced.
- this.length += length;
- index = options.at != null ? options.at : this.models.length;
- splice.apply(this.models, [index, 0].concat(models));
- if (this.comparator) this.sort({silent: true});
- if (options.silent) return this;
- for (i = 0, length = this.models.length; i < length; i++) {
- if (!cids[(model = this.models[i]).cid]) continue;
- options.index = i;
- model.trigger('add', model, this, options);
- }
- return this;
- },
-
- // Remove a model, or a list of models from the set. Pass silent to avoid
- // firing the `remove` event for every model removed.
- remove: function(models, options) {
- var i, l, index, model;
- options || (options = {});
- models = _.isArray(models) ? models.slice() : [models];
- for (i = 0, l = models.length; i < l; i++) {
- model = this.getByCid(models[i]) || this.get(models[i]);
- if (!model) continue;
- delete this._byId[model.id];
- delete this._byCid[model.cid];
- index = this.indexOf(model);
- this.models.splice(index, 1);
- this.length--;
- if (!options.silent) {
- options.index = index;
- model.trigger('remove', model, this, options);
- }
- this._removeReference(model);
- }
- return this;
- },
-
- // Add a model to the end of the collection.
- push: function(model, options) {
- model = this._prepareModel(model, options);
- this.add(model, options);
- return model;
- },
-
- // Remove a model from the end of the collection.
- pop: function(options) {
- var model = this.at(this.length - 1);
- this.remove(model, options);
- return model;
- },
-
- // Add a model to the beginning of the collection.
- unshift: function(model, options) {
- model = this._prepareModel(model, options);
- this.add(model, _.extend({at: 0}, options));
- return model;
- },
-
- // Remove a model from the beginning of the collection.
- shift: function(options) {
- var model = this.at(0);
- this.remove(model, options);
- return model;
- },
-
- // Get a model from the set by id.
- get: function(id) {
- if (id == null) return void 0;
- return this._byId[id.id != null ? id.id : id];
- },
-
- // Get a model from the set by client id.
- getByCid: function(cid) {
- return cid && this._byCid[cid.cid || cid];
- },
-
- // Get the model at the given index.
- at: function(index) {
- return this.models[index];
- },
-
- // Return models with matching attributes. Useful for simple cases of `filter`.
- where: function(attrs) {
- if (_.isEmpty(attrs)) return [];
- return this.filter(function(model) {
- for (var key in attrs) {
- if (attrs[key] !== model.get(key)) return false;
- }
- return true;
- });
- },
-
- // Force the collection to re-sort itself. You don't need to call this under
- // normal circumstances, as the set will maintain sort order as each item
- // is added.
- sort: function(options) {
- options || (options = {});
- if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
- var boundComparator = _.bind(this.comparator, this);
- if (this.comparator.length == 1) {
- this.models = this.sortBy(boundComparator);
- } else {
- this.models.sort(boundComparator);
- }
- if (!options.silent) this.trigger('reset', this, options);
- return this;
- },
-
- // Pluck an attribute from each model in the collection.
- pluck: function(attr) {
- return _.map(this.models, function(model){ return model.get(attr); });
- },
-
- // When you have more items than you want to add or remove individually,
- // you can reset the entire set with a new list of models, without firing
- // any `add` or `remove` events. Fires `reset` when finished.
- reset: function(models, options) {
- models || (models = []);
- options || (options = {});
- for (var i = 0, l = this.models.length; i < l; i++) {
- this._removeReference(this.models[i]);
- }
- this._reset();
- this.add(models, _.extend({silent: true}, options));
- if (!options.silent) this.trigger('reset', this, options);
- return this;
- },
-
- // Fetch the default set of models for this collection, resetting the
- // collection when they arrive. If `add: true` is passed, appends the
- // models to the collection instead of resetting.
- fetch: function(options) {
- options = options ? _.clone(options) : {};
- if (options.parse === undefined) options.parse = true;
- var collection = this;
- var success = options.success;
- options.success = function(resp, status, xhr) {
- collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
- if (success) success(collection, resp);
- };
- options.error = Backbone.wrapError(options.error, collection, options);
- return (this.sync || Backbone.sync).call(this, 'read', this, options);
- },
-
- // Create a new instance of a model in this collection. Add the model to the
- // collection immediately, unless `wait: true` is passed, in which case we
- // wait for the server to agree.
- create: function(model, options) {
- var coll = this;
- options = options ? _.clone(options) : {};
- model = this._prepareModel(model, options);
- if (!model) return false;
- if (!options.wait) coll.add(model, options);
- var success = options.success;
- options.success = function(nextModel, resp, xhr) {
- if (options.wait) coll.add(nextModel, options);
- if (success) {
- success(nextModel, resp);
- } else {
- nextModel.trigger('sync', model, resp, options);
- }
- };
- model.save(null, options);
- return model;
- },
-
- // **parse** converts a response into a list of models to be added to the
- // collection. The default implementation is just to pass it through.
- parse: function(resp, xhr) {
- return resp;
- },
-
- // Proxy to _'s chain. Can't be proxied the same way the rest of the
- // underscore methods are proxied because it relies on the underscore
- // constructor.
- chain: function () {
- return _(this.models).chain();
- },
-
- // Reset all internal state. Called when the collection is reset.
- _reset: function(options) {
- this.length = 0;
- this.models = [];
- this._byId = {};
- this._byCid = {};
- },
-
- // Prepare a model or hash of attributes to be added to this collection.
- _prepareModel: function(model, options) {
- options || (options = {});
- if (!(model instanceof Model)) {
- var attrs = model;
- options.collection = this;
- model = new this.model(attrs, options);
- if (!model._validate(model.attributes, options)) model = false;
- } else if (!model.collection) {
- model.collection = this;
- }
- return model;
- },
-
- // Internal method to remove a model's ties to a collection.
- _removeReference: function(model) {
- if (this == model.collection) {
- delete model.collection;
- }
- model.off('all', this._onModelEvent, this);
- },
-
- // Internal method called every time a model in the set fires an event.
- // Sets need to update their indexes when models change ids. All other
- // events simply proxy through. "add" and "remove" events that originate
- // in other collections are ignored.
- _onModelEvent: function(event, model, collection, options) {
- if ((event == 'add' || event == 'remove') && collection != this) return;
- if (event == 'destroy') {
- this.remove(model, options);
- }
- if (model && event === 'change:' + model.idAttribute) {
- delete this._byId[model.previous(model.idAttribute)];
- this._byId[model.id] = model;
- }
- this.trigger.apply(this, arguments);
- }
-
- });
-
- // Underscore methods that we want to implement on the Collection.
- var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find',
- 'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any',
- 'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex',
- 'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf',
- 'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy'];
-
- // Mix in each Underscore method as a proxy to `Collection#models`.
- _.each(methods, function(method) {
- Collection.prototype[method] = function() {
- return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
- };
- });
-
- // Backbone.Router
- // -------------------
-
- // Routers map faux-URLs to actions, and fire events when routes are
- // matched. Creating a new one sets its `routes` hash, if not set statically.
- var Router = Backbone.Router = function(options) {
- options || (options = {});
- if (options.routes) this.routes = options.routes;
- this._bindRoutes();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regular expressions for matching named param parts and splatted
- // parts of route strings.
- var namedParam = /:\w+/g;
- var splatParam = /\*\w+/g;
- var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
-
- // Set up all inheritable **Backbone.Router** properties and methods.
- _.extend(Router.prototype, Events, {
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Manually bind a single named route to a callback. For example:
- //
- // this.route('search/:query/p:num', 'search', function(query, num) {
- // ...
- // });
- //
- route: function(route, name, callback) {
- Backbone.history || (Backbone.history = new History);
- if (!_.isRegExp(route)) route = this._routeToRegExp(route);
- if (!callback) callback = this[name];
- Backbone.history.route(route, _.bind(function(fragment) {
- var args = this._extractParameters(route, fragment);
- callback && callback.apply(this, args);
- this.trigger.apply(this, ['route:' + name].concat(args));
- Backbone.history.trigger('route', this, name, args);
- }, this));
- return this;
- },
-
- // Simple proxy to `Backbone.history` to save a fragment into the history.
- navigate: function(fragment, options) {
- Backbone.history.navigate(fragment, options);
- },
-
- // Bind all defined routes to `Backbone.history`. We have to reverse the
- // order of the routes here to support behavior where the most general
- // routes can be defined at the bottom of the route map.
- _bindRoutes: function() {
- if (!this.routes) return;
- var routes = [];
- for (var route in this.routes) {
- routes.unshift([route, this.routes[route]]);
- }
- for (var i = 0, l = routes.length; i < l; i++) {
- this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
- }
- },
-
- // Convert a route string into a regular expression, suitable for matching
- // against the current location hash.
- _routeToRegExp: function(route) {
- route = route.replace(escapeRegExp, '\\$&')
- .replace(namedParam, '([^\/]+)')
- .replace(splatParam, '(.*?)');
- return new RegExp('^' + route + '$');
- },
-
- // Given a route, and a URL fragment that it matches, return the array of
- // extracted parameters.
- _extractParameters: function(route, fragment) {
- return route.exec(fragment).slice(1);
- }
-
- });
-
- // Backbone.History
- // ----------------
-
- // Handles cross-browser history management, based on URL fragments. If the
- // browser does not support `onhashchange`, falls back to polling.
- var History = Backbone.History = function() {
- this.handlers = [];
- _.bindAll(this, 'checkUrl');
- };
-
- // Cached regex for cleaning leading hashes and slashes .
- var routeStripper = /^[#\/]/;
-
- // Cached regex for detecting MSIE.
- var isExplorer = /msie [\w.]+/;
-
- // Has the history handling already been started?
- History.started = false;
-
- // Set up all inheritable **Backbone.History** properties and methods.
- _.extend(History.prototype, Events, {
-
- // The default interval to poll for hash changes, if necessary, is
- // twenty times a second.
- interval: 50,
-
- // Gets the true hash value. Cannot use location.hash directly due to bug
- // in Firefox where location.hash will always be decoded.
- getHash: function(windowOverride) {
- var loc = windowOverride ? windowOverride.location : window.location;
- var match = loc.href.match(/#(.*)$/);
- return match ? match[1] : '';
- },
-
- // Get the cross-browser normalized URL fragment, either from the URL,
- // the hash, or the override.
- getFragment: function(fragment, forcePushState) {
- if (fragment == null) {
- if (this._hasPushState || forcePushState) {
- fragment = window.location.pathname;
- var search = window.location.search;
- if (search) fragment += search;
- } else {
- fragment = this.getHash();
- }
- }
- if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
- return fragment.replace(routeStripper, '');
- },
-
- // Start the hash change handling, returning `true` if the current URL matches
- // an existing route, and `false` otherwise.
- start: function(options) {
- if (History.started) throw new Error("Backbone.history has already been started");
- History.started = true;
-
- // Figure out the initial configuration. Do we need an iframe?
- // Is pushState desired ... is it available?
- this.options = _.extend({}, {root: '/'}, this.options, options);
- this._wantsHashChange = this.options.hashChange !== false;
- this._wantsPushState = !!this.options.pushState;
- this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState);
- var fragment = this.getFragment();
- var docMode = document.documentMode;
- var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
-
- if (oldIE) {
- this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
- this.navigate(fragment);
- }
-
- // Depending on whether we're using pushState or hashes, and whether
- // 'onhashchange' is supported, determine how we check the URL state.
- if (this._hasPushState) {
- $(window).bind('popstate', this.checkUrl);
- } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
- $(window).bind('hashchange', this.checkUrl);
- } else if (this._wantsHashChange) {
- this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
- }
-
- // Determine if we need to change the base url, for a pushState link
- // opened by a non-pushState browser.
- this.fragment = fragment;
- var loc = window.location;
- var atRoot = loc.pathname == this.options.root;
-
- // If we've started off with a route from a `pushState`-enabled browser,
- // but we're currently in a browser that doesn't support it...
- if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
- this.fragment = this.getFragment(null, true);
- window.location.replace(this.options.root + '#' + this.fragment);
- // Return immediately as browser will do redirect to new url
- return true;
-
- // Or if we've started out with a hash-based route, but we're currently
- // in a browser where it could be `pushState`-based instead...
- } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
- this.fragment = this.getHash().replace(routeStripper, '');
- window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
- }
-
- if (!this.options.silent) {
- return this.loadUrl();
- }
- },
-
- // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
- // but possibly useful for unit testing Routers.
- stop: function() {
- $(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
- clearInterval(this._checkUrlInterval);
- History.started = false;
- },
-
- // Add a route to be tested when the fragment changes. Routes added later
- // may override previous routes.
- route: function(route, callback) {
- this.handlers.unshift({route: route, callback: callback});
- },
-
- // Checks the current URL to see if it has changed, and if it has,
- // calls `loadUrl`, normalizing across the hidden iframe.
- checkUrl: function(e) {
- var current = this.getFragment();
- if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe));
- if (current == this.fragment) return false;
- if (this.iframe) this.navigate(current);
- this.loadUrl() || this.loadUrl(this.getHash());
- },
-
- // Attempt to load the current URL fragment. If a route succeeds with a
- // match, returns `true`. If no defined routes matches the fragment,
- // returns `false`.
- loadUrl: function(fragmentOverride) {
- var fragment = this.fragment = this.getFragment(fragmentOverride);
- var matched = _.any(this.handlers, function(handler) {
- if (handler.route.test(fragment)) {
- handler.callback(fragment);
- return true;
- }
- });
- return matched;
- },
-
- // Save a fragment into the hash history, or replace the URL state if the
- // 'replace' option is passed. You are responsible for properly URL-encoding
- // the fragment in advance.
- //
- // The options object can contain `trigger: true` if you wish to have the
- // route callback be fired (not usually desirable), or `replace: true`, if
- // you wish to modify the current URL without adding an entry to the history.
- navigate: function(fragment, options) {
- if (!History.started) return false;
- if (!options || options === true) options = {trigger: options};
- var frag = (fragment || '').replace(routeStripper, '');
- if (this.fragment == frag) return;
-
- // If pushState is available, we use it to set the fragment as a real URL.
- if (this._hasPushState) {
- if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
- this.fragment = frag;
- window.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, frag);
-
- // If hash changes haven't been explicitly disabled, update the hash
- // fragment to store history.
- } else if (this._wantsHashChange) {
- this.fragment = frag;
- this._updateHash(window.location, frag, options.replace);
- if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) {
- // Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.
- // When replace is true, we don't want this.
- if(!options.replace) this.iframe.document.open().close();
- this._updateHash(this.iframe.location, frag, options.replace);
- }
-
- // If you've told us that you explicitly don't want fallback hashchange-
- // based history, then `navigate` becomes a page refresh.
- } else {
- window.location.assign(this.options.root + fragment);
- }
- if (options.trigger) this.loadUrl(fragment);
- },
-
- // Update the hash location, either replacing the current entry, or adding
- // a new one to the browser history.
- _updateHash: function(location, fragment, replace) {
- if (replace) {
- location.replace(location.toString().replace(/(javascript:|#).*$/, '') + '#' + fragment);
- } else {
- location.hash = fragment;
- }
- }
- });
-
- // Backbone.View
- // -------------
-
- // Creating a Backbone.View creates its initial element outside of the DOM,
- // if an existing element is not provided...
- var View = Backbone.View = function(options) {
- this.cid = _.uniqueId('view');
- this._configure(options || {});
- this._ensureElement();
- this.initialize.apply(this, arguments);
- this.delegateEvents();
- };
-
- // Cached regex to split keys for `delegate`.
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
-
- // List of view options to be merged as properties.
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
-
- // Set up all inheritable **Backbone.View** properties and methods.
- _.extend(View.prototype, Events, {
-
- // The default `tagName` of a View's element is `"div"`.
- tagName: 'div',
-
- // jQuery delegate for element lookup, scoped to DOM elements within the
- // current view. This should be prefered to global lookups where possible.
- $: function(selector) {
- return this.$el.find(selector);
- },
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // **render** is the core function that your view should override, in order
- // to populate its element (`this.el`), with the appropriate HTML. The
- // convention is for **render** to always return `this`.
- render: function() {
- return this;
- },
-
- // Remove this view from the DOM. Note that the view isn't present in the
- // DOM by default, so calling this method may be a no-op.
- remove: function() {
- this.$el.remove();
- return this;
- },
-
- // For small amounts of DOM Elements, where a full-blown template isn't
- // needed, use **make** to manufacture elements, one at a time.
- //
- // var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
- //
- make: function(tagName, attributes, content) {
- var el = document.createElement(tagName);
- if (attributes) $(el).attr(attributes);
- if (content) $(el).html(content);
- return el;
- },
-
- // Change the view's element (`this.el` property), including event
- // re-delegation.
- setElement: function(element, delegate) {
- if (this.$el) this.undelegateEvents();
- this.$el = (element instanceof $) ? element : $(element);
- this.el = this.$el[0];
- if (delegate !== false) this.delegateEvents();
- return this;
- },
-
- // Set callbacks, where `this.events` is a hash of
- //
- // *{"event selector": "callback"}*
- //
- // {
- // 'mousedown .title': 'edit',
- // 'click .button': 'save'
- // 'click .open': function(e) { ... }
- // }
- //
- // pairs. Callbacks will be bound to the view, with `this` set properly.
- // Uses event delegation for efficiency.
- // Omitting the selector binds the event to `this.el`.
- // This only works for delegate-able events: not `focus`, `blur`, and
- // not `change`, `submit`, and `reset` in Internet Explorer.
- delegateEvents: function(events) {
- if (!(events || (events = getValue(this, 'events')))) return;
- this.undelegateEvents();
- for (var key in events) {
- var method = events[key];
- if (!_.isFunction(method)) method = this[events[key]];
- if (!method) throw new Error('Method "' + events[key] + '" does not exist');
- var match = key.match(delegateEventSplitter);
- var eventName = match[1], selector = match[2];
- method = _.bind(method, this);
- eventName += '.delegateEvents' + this.cid;
- if (selector === '') {
- this.$el.bind(eventName, method);
- } else {
- this.$el.delegate(selector, eventName, method);
- }
- }
- },
-
- // Clears all callbacks previously bound to the view with `delegateEvents`.
- // You usually don't need to use this, but may wish to if you have multiple
- // Backbone views attached to the same DOM element.
- undelegateEvents: function() {
- this.$el.unbind('.delegateEvents' + this.cid);
- },
-
- // Performs the initial configuration of a View with a set of options.
- // Keys with special meaning *(model, collection, id, className)*, are
- // attached directly to the view.
- _configure: function(options) {
- if (this.options) options = _.extend({}, this.options, options);
- for (var i = 0, l = viewOptions.length; i < l; i++) {
- var attr = viewOptions[i];
- if (options[attr]) this[attr] = options[attr];
- }
- this.options = options;
- },
-
- // Ensure that the View has a DOM element to render into.
- // If `this.el` is a string, pass it through `$()`, take the first
- // matching element, and re-assign it to `el`. Otherwise, create
- // an element from the `id`, `className` and `tagName` properties.
- _ensureElement: function() {
- if (!this.el) {
- var attrs = getValue(this, 'attributes') || {};
- if (this.id) attrs.id = this.id;
- if (this.className) attrs['class'] = this.className;
- this.setElement(this.make(this.tagName, attrs), false);
- } else {
- this.setElement(this.el, false);
- }
- }
-
- });
-
- // The self-propagating extend function that Backbone classes use.
- var extend = function (protoProps, classProps) {
- var child = inherits(this, protoProps, classProps);
- child.extend = this.extend;
- return child;
- };
-
- // Set up inheritance for the model, collection, and view.
- Model.extend = Collection.extend = Router.extend = View.extend = extend;
-
- // Backbone.sync
- // -------------
-
- // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
- var methodMap = {
- 'create': 'POST',
- 'update': 'PUT',
- 'delete': 'DELETE',
- 'read': 'GET'
- };
-
- // Override this function to change the manner in which Backbone persists
- // models to the server. You will be passed the type of request, and the
- // model in question. By default, makes a RESTful Ajax request
- // to the model's `url()`. Some possible customizations could be:
- //
- // * Use `setTimeout` to batch rapid-fire updates into a single request.
- // * Send up the models as XML instead of JSON.
- // * Persist models via WebSockets instead of Ajax.
- //
- // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
- // as `POST`, with a `_method` parameter containing the true HTTP method,
- // as well as all requests with the body as `application/x-www-form-urlencoded`
- // instead of `application/json` with the model in a param named `model`.
- // Useful when interfacing with server-side languages like **PHP** that make
- // it difficult to read the body of `PUT` requests.
- Backbone.sync = function(method, model, options) {
- var type = methodMap[method];
-
- // Default options, unless specified.
- options || (options = {});
-
- // Default JSON-request options.
- var params = {type: type, dataType: 'json'};
-
- // Ensure that we have a URL.
- if (!options.url) {
- params.url = getValue(model, 'url') || urlError();
- }
-
- // Ensure that we have the appropriate request data.
- if (!options.data && model && (method == 'create' || method == 'update')) {
- params.contentType = 'application/json';
- params.data = JSON.stringify(model.toJSON());
- }
-
- // For older servers, emulate JSON by encoding the request into an HTML-form.
- if (Backbone.emulateJSON) {
- params.contentType = 'application/x-www-form-urlencoded';
- params.data = params.data ? {model: params.data} : {};
- }
-
- // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
- // And an `X-HTTP-Method-Override` header.
- if (Backbone.emulateHTTP) {
- if (type === 'PUT' || type === 'DELETE') {
- if (Backbone.emulateJSON) params.data._method = type;
- params.type = 'POST';
- params.beforeSend = function(xhr) {
- xhr.setRequestHeader('X-HTTP-Method-Override', type);
- };
- }
- }
-
- // Don't process data on a non-GET request.
- if (params.type !== 'GET' && !Backbone.emulateJSON) {
- params.processData = false;
- }
-
- // Make the request, allowing the user to override any Ajax options.
- return $.ajax(_.extend(params, options));
- };
-
- // Wrap an optional error callback with a fallback error event.
- Backbone.wrapError = function(onError, originalModel, options) {
- return function(model, resp) {
- resp = model === originalModel ? resp : model;
- if (onError) {
- onError(originalModel, resp, options);
- } else {
- originalModel.trigger('error', originalModel, resp, options);
- }
- };
- };
-
- // Helpers
- // -------
-
- // Shared empty constructor function to aid in prototype-chain creation.
- var ctor = function(){};
-
- // Helper function to correctly set up the prototype chain, for subclasses.
- // Similar to `goog.inherits`, but uses a hash of prototype properties and
- // class properties to be extended.
- var inherits = function(parent, protoProps, staticProps) {
- var child;
-
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent's constructor.
- if (protoProps && protoProps.hasOwnProperty('constructor')) {
- child = protoProps.constructor;
- } else {
- child = function(){ parent.apply(this, arguments); };
- }
-
- // Inherit class (static) properties from parent.
- _.extend(child, parent);
-
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function.
- ctor.prototype = parent.prototype;
- child.prototype = new ctor();
-
- // Add prototype properties (instance properties) to the subclass,
- // if supplied.
- if (protoProps) _.extend(child.prototype, protoProps);
-
- // Add static properties to the constructor function, if supplied.
- if (staticProps) _.extend(child, staticProps);
-
- // Correctly set child's `prototype.constructor`.
- child.prototype.constructor = child;
-
- // Set a convenience property in case the parent's prototype is needed later.
- child.__super__ = parent.prototype;
-
- return child;
- };
-
- // Helper function to get a value from a Backbone object as a property
- // or as a function.
- var getValue = function(object, prop) {
- if (!(object && object[prop])) return null;
- return _.isFunction(object[prop]) ? object[prop]() : object[prop];
- };
-
- // Throw an error when a URL is needed, and none is supplied.
- var urlError = function() {
- throw new Error('A "url" property or function must be specified');
- };
-
-}).call(this);
--- a/server/src/main/webapp/js/config.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-//
-// Config file. Split out from the app for ease of overlaying a new config
-// without affecting the app controller.
-//
-// Copyright (c) The Dojo Foundation 2011. All Rights Reserved.
-//
-var dojoConfig = {
- baseUrl: '/renkan',
- async:true,
- paths : {
- coweb : 'lib/coweb',
- cowebx: 'lib/cowebx',
- org : 'lib/org'
- },
-/* packages:[{
- name: 'dojo',
- location:'http://vhost1629.developer.ihost.com/dojotoolkit/1.7.0/dojo',
- main:'main'
- },
- {
- name: 'dijit',
- location:'http://vhost1629.developer.ihost.com/dojotoolkit/1.7.0/dijit',
- main:'main'
- },
- {
- name: 'dojox',
- location:'http://vhost1629.developer.ihost.com/dojotoolkit/1.7.0/dojox',
- main:'main'
- }]*/
-};
-
--- a/server/src/main/webapp/js/dojo.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-/*
- Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
-*/
-
-/*
- This is an optimized version of Dojo, built for deployment and not for
- development. To get sources and documentation, please visit:
-
- http://dojotoolkit.org
-*/
-
-//>>built
-(function(_1,_2){var _3=function(){},_4=function(it){for(var p in it){return 0;}return 1;},_5={}.toString,_6=function(it){return _5.call(it)=="[object Function]";},_7=function(it){return _5.call(it)=="[object String]";},_8=function(it){return _5.call(it)=="[object Array]";},_9=function(_a,_b){if(_a){for(var i=0;i<_a.length;){_b(_a[i++]);}}},_c=function(_d,_e){for(var p in _e){_d[p]=_e[p];}return _d;},_f=function(_10,_11){return _c(new Error(_10),{src:"dojoLoader",info:_11});},_12=1,uid=function(){return "_"+_12++;},req=function(_13,_14,_15){return _16(_13,_14,_15,0,req);},_17=this,doc=_17.document,_18=doc&&doc.createElement("DiV"),has=req.has=function(_19){return _6(_1a[_19])?(_1a[_19]=_1a[_19](_17,doc,_18)):_1a[_19];},_1a=has.cache=_2.hasCache;has.add=function(_1b,_1c,now,_1d){(_1a[_1b]===undefined||_1d)&&(_1a[_1b]=_1c);return now&&has(_1b);};0&&has.add("host-node",_1.has&&"host-node" in _1.has?_1.has["host-node"]:(typeof process=="object"&&process.versions&&process.versions.node&&process.versions.v8));if(0){require("./_base/configNode.js").config(_2);_2.loaderPatch.nodeRequire=require;}0&&has.add("host-rhino",_1.has&&"host-rhino" in _1.has?_1.has["host-rhino"]:(typeof load=="function"&&(typeof Packages=="function"||typeof Packages=="object")));if(0){for(var _1e=_1.baseUrl||".",arg,_1f=this.arguments,i=0;i<_1f.length;){arg=(_1f[i++]+"").split("=");if(arg[0]=="baseUrl"){_1e=arg[1];break;}}load(_1e+"/_base/configRhino.js");rhinoDojoConfig(_2,_1e,_1f);}for(var p in _1.has){has.add(p,_1.has[p],0,1);}var _20=1,_21=2,_22=3,_23=4,_24=5;if(0){_20="requested";_21="arrived";_22="not-a-module";_23="executing";_24="executed";}var _25=0,_26="sync",xd="xd",_27=[],_28=0,_29=_3,_2a=_3,_2b;if(1){req.isXdUrl=_3;req.initSyncLoader=function(_2c,_2d,_2e){if(!_28){_28=_2c;_29=_2d;_2a=_2e;}return {sync:_26,requested:_20,arrived:_21,nonmodule:_22,executing:_23,executed:_24,syncExecStack:_27,modules:_2f,execQ:_30,getModule:_31,injectModule:_32,setArrived:_33,signal:_34,finishExec:_35,execModule:_36,dojoRequirePlugin:_28,getLegacyMode:function(){return _25;},guardCheckComplete:_37};};if(1){var _38=location.protocol,_39=location.host;req.isXdUrl=function(url){if(/^\./.test(url)){return false;}if(/^\/\//.test(url)){return true;}var _3a=url.match(/^([^\/\:]+\:)\/+([^\/]+)/);return _3a&&(_3a[1]!=_38||(_39&&_3a[2]!=_39));};1||has.add("dojo-xhr-factory",1);has.add("dojo-force-activex-xhr",1&&!doc.addEventListener&&window.location.protocol=="file:");has.add("native-xhr",typeof XMLHttpRequest!="undefined");if(has("native-xhr")&&!has("dojo-force-activex-xhr")){_2b=function(){return new XMLHttpRequest();};}else{for(var _3b=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],_3c,i=0;i<3;){try{_3c=_3b[i++];if(new ActiveXObject(_3c)){break;}}catch(e){}}_2b=function(){return new ActiveXObject(_3c);};}req.getXhr=_2b;has.add("dojo-gettext-api",1);req.getText=function(url,_3d,_3e){var xhr=_2b();xhr.open("GET",_3f(url),false);xhr.send(null);if(xhr.status==200||(!location.host&&!xhr.status)){if(_3e){_3e(xhr.responseText,_3d);}}else{throw _f("xhrFailed",xhr.status);}return xhr.responseText;};}}else{req.async=1;}var _40=new Function("return eval(arguments[0]);");req.eval=function(_41,_42){return _40(_41+"\r\n////@ sourceURL="+_42);};var _43={},_44="error",_34=req.signal=function(_45,_46){var _47=_43[_45];_9(_47&&_47.slice(0),function(_48){_48.apply(null,_8(_46)?_46:[_46]);});},on=req.on=function(_49,_4a){var _4b=_43[_49]||(_43[_49]=[]);_4b.push(_4a);return {remove:function(){for(var i=0;i<_4b.length;i++){if(_4b[i]===_4a){_4b.splice(i,1);return;}}}};};var _4c=[],_4d={},_4e=[],_4f={},map=req.map={},_50=[],_2f={},_51="",_52={},_53="url:",_54={},_55={};if(1){var _56=function(_57){var p,_58,_59,now,m;for(p in _54){_58=_54[p];_59=p.match(/^url\:(.+)/);if(_59){_52[_53+_5a(_59[1],_57)]=_58;}else{if(p=="*now"){now=_58;}else{if(p!="*noref"){m=_5b(p,_57);_52[m.mid]=_52[_53+m.url]=_58;}}}}if(now){now(_5c(_57));}_54={};},_5d=function(s){return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(c){return "\\"+c;});},_5e=function(map,_5f){_5f.splice(0,_5f.length);for(var p in map){_5f.push([p,map[p],new RegExp("^"+_5d(p)+"(/|$)"),p.length]);}_5f.sort(function(lhs,rhs){return rhs[3]-lhs[3];});return _5f;},_60=function(_61){var _62=_61.name;if(!_62){_62=_61;_61={name:_62};}_61=_c({main:"main"},_61);_61.location=_61.location?_61.location:_62;if(_61.packageMap){map[_62]=_61.packageMap;}if(!_61.main.indexOf("./")){_61.main=_61.main.substring(2);}_4f[_62]=_61;},_63=function(_64,_65,_66){for(var p in _64){if(p=="waitSeconds"){req.waitms=(_64[p]||0)*1000;}if(p=="cacheBust"){_51=_64[p]?(_7(_64[p])?_64[p]:(new Date()).getTime()+""):"";}if(p=="baseUrl"||p=="combo"){req[p]=_64[p];}if(1&&p=="async"){var _67=_64[p];req.legacyMode=_25=(_7(_67)&&/sync|legacyAsync/.test(_67)?_67:(!_67?_26:false));req.async=!_25;}if(_64[p]!==_1a){req.rawConfig[p]=_64[p];p!="has"&&has.add("config-"+p,_64[p],0,_65);}}if(!req.baseUrl){req.baseUrl="./";}if(!/\/$/.test(req.baseUrl)){req.baseUrl+="/";}for(p in _64.has){has.add(p,_64.has[p],0,_65);}_9(_64.packages,_60);for(_1e in _64.packagePaths){_9(_64.packagePaths[_1e],function(_68){var _69=_1e+"/"+_68;if(_7(_68)){_68={name:_68};}_68.location=_69;_60(_68);});}_5e(_c(map,_64.map),_50);_9(_50,function(_6a){_6a[1]=_5e(_6a[1],[]);if(_6a[0]=="*"){_50.star=_6a[1];}});_5e(_c(_4d,_64.paths),_4e);_9(_64.aliases,function(_6b){if(_7(_6b[0])){_6b[0]=new RegExp("^"+_5d(_6b[0])+"$");}_4c.push(_6b);});for(p in _64.config){var _6c=_31(p,_66);_6c.config=_c(_6c.config||{},_64.config[p]);}if(_64.cache){_56();_54=_64.cache;if(_64.cache["*noref"]){_56();}}_34("config",[_64,req.rawConfig]);};if(has("dojo-cdn")||1){var _6d=doc.getElementsByTagName("script"),i=0,_6e,_6f,src,_70;while(i<_6d.length){_6e=_6d[i++];if((src=_6e.getAttribute("src"))&&(_70=src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){_6f=_70[3]||"";_2.baseUrl=_2.baseUrl||_6f;src=(_6e.getAttribute("data-dojo-config")||_6e.getAttribute("djConfig"));if(src){_55=req.eval("({ "+src+" })","data-dojo-config");}if(0){var _71=_6e.getAttribute("data-main");if(_71){_55.deps=_55.deps||[_71];}}break;}}}if(0){try{if(window.parent!=window&&window.parent.require){var doh=window.parent.require("doh");doh&&_c(_55,doh.testConfig);}}catch(e){}}req.rawConfig={};_63(_2,1);if(has("dojo-cdn")){_4f.dojo.location=_6f;if(_6f){_6f+="/";}_4f.dijit.location=_6f+"../dijit/";_4f.dojox.location=_6f+"../dojox/";}_63(_1,1);_63(_55,1);}else{_4d=_2.paths;_4e=_2.pathsMapProg;_4f=_2.packs;_4c=_2.aliases;_50=_2.mapProgs;_2f=_2.modules;_52=_2.cache;_51=_2.cacheBust;req.rawConfig=_2;}if(0){req.combo=req.combo||{add:_3};var _72=0,_73=[],_74=null;}var _75=function(_76){_37(function(){_9(_76.deps,_32);if(0&&_72&&!_74){_74=setTimeout(function(){_72=0;_74=null;req.combo.done(function(_77,url){var _78=function(){_79(0,_77);_7a();};_73.push(_77);_7b=_77;req.injectUrl(url,_78,_77);_7b=0;},req);},0);}});},_16=function(a1,a2,a3,_7c,_7d){var _7e,_7f;if(_7(a1)){_7e=_31(a1,_7c,true);if(_7e&&_7e.executed){return _7e.result;}throw _f("undefinedModule",a1);}if(!_8(a1)){_63(a1,0,_7c);a1=a2;a2=a3;}if(_8(a1)){if(!a1.length){a2&&a2();}else{_7f="require*"+uid();for(var mid,_80=[],i=0;i<a1.length;){mid=a1[i++];_80.push(_31(mid,_7c));}_7e=_c(_81("",_7f,0,""),{injected:_21,deps:_80,def:a2||_3,require:_7c?_7c.require:req,gc:1});_2f[_7e.mid]=_7e;_75(_7e);var _82=_83&&_25!=_26;_37(function(){_36(_7e,_82);});if(!_7e.executed){_30.push(_7e);}_7a();}}return _7d;},_5c=function(_84){if(!_84){return req;}var _85=_84.require;if(!_85){_85=function(a1,a2,a3){return _16(a1,a2,a3,_84,_85);};_84.require=_c(_85,req);_85.module=_84;_85.toUrl=function(_86){return _5a(_86,_84);};_85.toAbsMid=function(mid){return _b3(mid,_84);};if(0){_85.undef=function(mid){req.undef(mid,_84);};}if(1){_85.syncLoadNls=function(mid){var _87=_5b(mid,_84),_88=_2f[_87.mid];if(!_88||!_88.executed){_89=_52[_87.mid]||_52[_53+_87.url];if(_89){_8a(_89);_88=_2f[_87.mid];}}return _88&&_88.executed&&_88.result;};}}return _85;},_30=[],_8b=[],_8c={},_8d=function(_8e){_8e.injected=_20;_8c[_8e.mid]=1;if(_8e.url){_8c[_8e.url]=_8e.pack||1;}_8f();},_33=function(_90){_90.injected=_21;delete _8c[_90.mid];if(_90.url){delete _8c[_90.url];}if(_4(_8c)){_91();1&&_25==xd&&(_25=_26);}},_92=req.idle=function(){return !_8b.length&&_4(_8c)&&!_30.length&&!_83;},_93=function(_94,map){if(map){for(var i=0;i<map.length;i++){if(map[i][2].test(_94)){return map[i];}}}return 0;},_95=function(_96){var _97=[],_98,_99;_96=_96.replace(/\\/g,"/").split("/");while(_96.length){_98=_96.shift();if(_98==".."&&_97.length&&_99!=".."){_97.pop();_99=_97[_97.length-1];}else{if(_98!="."){_97.push(_99=_98);}}}return _97.join("/");},_81=function(pid,mid,_9a,url){if(1){var xd=req.isXdUrl(url);return {pid:pid,mid:mid,pack:_9a,url:url,executed:0,def:0,isXd:xd,isAmd:!!(xd||(_4f[pid]&&_4f[pid].isAmd))};}else{return {pid:pid,mid:mid,pack:_9a,url:url,executed:0,def:0};}},_9b=function(mid,_9c,_9d,_9e,_9f,_a0,_a1,_a2){var pid,_a3,_a4,_a5,_a6,url,_a7,_a8,_a9;_a9=mid;_a8=/^\./.test(mid);if(/(^\/)|(\:)|(\.js$)/.test(mid)||(_a8&&!_9c)){return _81(0,mid,0,mid);}else{mid=_95(_a8?(_9c.mid+"/../"+mid):mid);if(/^\./.test(mid)){throw _f("irrationalPath",mid);}if(_9c){_a6=_93(_9c.mid,_a0);}_a6=_a6||_a0.star;_a6=_a6&&_93(mid,_a6[1]);if(_a6){mid=_a6[1]+mid.substring(_a6[3]);}_70=mid.match(/^([^\/]+)(\/(.+))?$/);pid=_70?_70[1]:"";if((_a3=_9d[pid])){mid=pid+"/"+(_a4=(_70[3]||_a3.main));}else{pid="";}var _aa=0,_ab=0;_9(_4c,function(_ac){var _ad=mid.match(_ac[0]);if(_ad&&_ad.length>_aa){_ab=_6(_ac[1])?mid.replace(_ac[0],_ac[1]):_ac[1];}});if(_ab){return _9b(_ab,0,_9d,_9e,_9f,_a0,_a1,_a2);}_a7=_9e[mid];if(_a7){return _a2?_81(_a7.pid,_a7.mid,_a7.pack,_a7.url):_9e[mid];}}_a6=_93(mid,_a1);if(_a6){url=_a6[1]+mid.substring(_a6[3]);}else{if(pid){url=_a3.location+"/"+_a4;}else{if(has("config-tlmSiblingOfDojo")){url="../"+mid;}else{url=mid;}}}if(!(/(^\/)|(\:)/.test(url))){url=_9f+url;}url+=".js";return _81(pid,mid,_a3,_95(url));},_5b=function(mid,_ae){return _9b(mid,_ae,_4f,_2f,req.baseUrl,_50,_4e);},_af=function(_b0,_b1,_b2){return _b0.normalize?_b0.normalize(_b1,function(mid){return _b3(mid,_b2);}):_b3(_b1,_b2);},_b4=0,_31=function(mid,_b5,_b6){var _b7,_b8,_b9,_ba;_b7=mid.match(/^(.+?)\!(.*)$/);if(_b7){_b8=_31(_b7[1],_b5,_b6);if(1&&_25==_26&&!_b8.executed){_32(_b8);if(_b8.injected===_21&&!_b8.executed){_37(function(){_36(_b8);});}if(_b8.executed){_bb(_b8);}else{_30.unshift(_b8);}}if(_b8.executed===_24&&!_b8.load){_bb(_b8);}if(_b8.load){_b9=_af(_b8,_b7[2],_b5);mid=(_b8.mid+"!"+(_b8.dynamic?++_b4+"!":"")+_b9);}else{_b9=_b7[2];mid=_b8.mid+"!"+(++_b4)+"!waitingForPlugin";}_ba={plugin:_b8,mid:mid,req:_5c(_b5),prid:_b9};}else{_ba=_5b(mid,_b5);}return _2f[_ba.mid]||(!_b6&&(_2f[_ba.mid]=_ba));},_b3=req.toAbsMid=function(mid,_bc){return _5b(mid,_bc).mid;},_5a=req.toUrl=function(_bd,_be){var _bf=_5b(_bd+"/x",_be),url=_bf.url;return _3f(_bf.pid===0?_bd:url.substring(0,url.length-5));},_c0={injected:_21,executed:_24,def:_22,result:_22},_c1=function(mid){return _2f[mid]=_c({mid:mid},_c0);},_c2=_c1("require"),_c3=_c1("exports"),_c4=_c1("module"),_c5=function(_c6,_c7){req.trace("loader-run-factory",[_c6.mid]);var _c8=_c6.def,_c9;1&&_27.unshift(_c6);if(has("config-dojo-loader-catches")){try{_c9=_6(_c8)?_c8.apply(null,_c7):_c8;}catch(e){_34(_44,_c6.result=_f("factoryThrew",[_c6,e]));}}else{_c9=_6(_c8)?_c8.apply(null,_c7):_c8;}_c6.result=_c9===undefined&&_c6.cjs?_c6.cjs.exports:_c9;1&&_27.shift(_c6);},_ca={},_cb=0,_bb=function(_cc){var _cd=_cc.result;_cc.dynamic=_cd.dynamic;_cc.normalize=_cd.normalize;_cc.load=_cd.load;return _cc;},_ce=function(_cf){var map={};_9(_cf.loadQ,function(_d0){var _d1=_af(_cf,_d0.prid,_d0.req.module),mid=_cf.dynamic?_d0.mid.replace(/waitingForPlugin$/,_d1):(_cf.mid+"!"+_d1),_d2=_c(_c({},_d0),{mid:mid,prid:_d1,injected:0});if(!_2f[mid]){_e4(_2f[mid]=_d2);}map[_d0.mid]=_2f[mid];_33(_d0);delete _2f[_d0.mid];});_cf.loadQ=0;var _d3=function(_d4){for(var _d5,_d6=_d4.deps||[],i=0;i<_d6.length;i++){_d5=map[_d6[i].mid];if(_d5){_d6[i]=_d5;}}};for(var p in _2f){_d3(_2f[p]);}_9(_30,_d3);},_35=function(_d7){req.trace("loader-finish-exec",[_d7.mid]);_d7.executed=_24;_d7.defOrder=_cb++;1&&_9(_d7.provides,function(cb){cb();});if(_d7.loadQ){_bb(_d7);_ce(_d7);}for(i=0;i<_30.length;){if(_30[i]===_d7){_30.splice(i,1);}else{i++;}}if(/^require\*/.test(_d7.mid)){delete _2f[_d7.mid];}},_d8=[],_36=function(_d9,_da){if(_d9.executed===_23){req.trace("loader-circular-dependency",[_d8.concat(_d9.mid).join("->")]);return (!_d9.def||_da)?_ca:(_d9.cjs&&_d9.cjs.exports);}if(!_d9.executed){if(!_d9.def){return _ca;}var mid=_d9.mid,_db=_d9.deps||[],arg,_dc,_dd=[],i=0;if(0){_d8.push(mid);req.trace("loader-exec-module",["exec",_d8.length,mid]);}_d9.executed=_23;while(i<_db.length){arg=_db[i++];_dc=((arg===_c2)?_5c(_d9):((arg===_c3)?_d9.cjs.exports:((arg===_c4)?_d9.cjs:_36(arg,_da))));if(_dc===_ca){_d9.executed=0;req.trace("loader-exec-module",["abort",mid]);0&&_d8.pop();return _ca;}_dd.push(_dc);}_c5(_d9,_dd);_35(_d9);0&&_d8.pop();}return _d9.result;},_83=0,_37=function(_de){try{_83++;_de();}finally{_83--;}if(_92()){_34("idle",[]);}},_7a=function(){if(_83){return;}_37(function(){_29();for(var _df,_e0,i=0;i<_30.length;){_df=_cb;_e0=_30[i];_36(_e0);if(_df!=_cb){_29();i=0;}else{i++;}}});};if(0){req.undef=function(_e1,_e2){var _e3=_31(_e1,_e2);_33(_e3);delete _2f[_e3.mid];};}if(1){if(has("dojo-loader-eval-hint-url")===undefined){has.add("dojo-loader-eval-hint-url",1);}var _3f=function(url){url+="";return url+(_51?((/\?/.test(url)?"&":"?")+_51):"");},_e4=function(_e5){var _e6=_e5.plugin;if(_e6.executed===_24&&!_e6.load){_bb(_e6);}var _e7=function(def){_e5.result=def;_33(_e5);_35(_e5);_7a();};if(_e6.load){_e6.load(_e5.prid,_e5.req,_e7);}else{if(_e6.loadQ){_e6.loadQ.push(_e5);}else{_e6.loadQ=[_e5];_30.unshift(_e6);_32(_e6);}}},_89=0,_7b=0,_e8=0,_8a=function(_e9,_ea){if(has("config-stripStrict")){_e9=_e9.replace(/"use strict"/g,"");}_e8=1;if(has("config-dojo-loader-catches")){try{if(_e9===_89){_89.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}catch(e){_34(_44,_f("evalModuleThrew",_ea));}}else{if(_e9===_89){_89.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}_e8=0;},_32=function(_eb){var mid=_eb.mid,url=_eb.url;if(_eb.executed||_eb.injected||_8c[mid]||(_eb.url&&((_eb.pack&&_8c[_eb.url]===_eb.pack)||_8c[_eb.url]==1))){return;}_8d(_eb);if(0){var _ec=0;if(_eb.plugin&&_eb.plugin.isCombo){req.combo.add(_eb.plugin.mid,_eb.prid,0,req);_ec=1;}else{if(!_eb.plugin){_ec=req.combo.add(0,_eb.mid,_eb.url,req);}}if(_ec){_72=1;return;}}if(_eb.plugin){_e4(_eb);return;}var _ed=function(){_79(_eb);if(_eb.injected!==_21){_33(_eb);_c(_eb,_c0);req.trace("loader-define-nonmodule",[_eb.url]);}if(1&&_25){!_27.length&&_7a();}else{_7a();}};_89=_52[mid]||_52[_53+_eb.url];if(_89){req.trace("loader-inject",["cache",_eb.mid,url]);_8a(_89,_eb);_ed();return;}if(1&&_25){if(_eb.isXd){_25==_26&&(_25=xd);}else{if(_eb.isAmd&&_25!=_26){}else{var _ee=function(_ef){if(_25==_26){_27.unshift(_eb);_8a(_ef,_eb);_27.shift();_79(_eb);if(!_eb.cjs){_33(_eb);_35(_eb);}if(_eb.finish){var _f0=mid+"*finish",_f1=_eb.finish;delete _eb.finish;def(_f0,["dojo",("dojo/require!"+_f1.join(",")).replace(/\./g,"/")],function(_f2){_9(_f1,function(mid){_f2.require(mid);});});_30.unshift(_31(_f0));}_ed();}else{_ef=_2a(_eb,_ef);if(_ef){_8a(_ef,_eb);_ed();}else{_7b=_eb;req.injectUrl(_3f(url),_ed,_eb);_7b=0;}}};req.trace("loader-inject",["xhr",_eb.mid,url,_25!=_26]);if(has("config-dojo-loader-catches")){try{req.getText(url,_25!=_26,_ee);}catch(e){_34(_44,_f("xhrInjectFailed",[_eb,e]));}}else{req.getText(url,_25!=_26,_ee);}return;}}}req.trace("loader-inject",["script",_eb.mid,url]);_7b=_eb;req.injectUrl(_3f(url),_ed,_eb);_7b=0;},_f3=function(_f4,_f5,def){req.trace("loader-define-module",[_f4.mid,_f5]);if(0&&_f4.plugin&&_f4.plugin.isCombo){_f4.result=_6(def)?def():def;_33(_f4);_35(_f4);return _f4;}var mid=_f4.mid;if(_f4.injected===_21){_34(_44,_f("multipleDefine",_f4));return _f4;}_c(_f4,{deps:_f5,def:def,cjs:{id:_f4.mid,uri:_f4.url,exports:(_f4.result={}),setExports:function(_f6){_f4.cjs.exports=_f6;},config:function(){return _f4.config;}}});for(var i=0;i<_f5.length;i++){_f5[i]=_31(_f5[i],_f4);}if(1&&_25&&!_8c[mid]){_75(_f4);_30.push(_f4);_7a();}_33(_f4);if(!_6(def)&&!_f5.length){_f4.result=def;_35(_f4);}return _f4;},_79=function(_f7,_f8){var _f9=[],_fa,_fb;while(_8b.length){_fb=_8b.shift();_f8&&(_fb[0]=_f8.shift());_fa=(_fb[0]&&_31(_fb[0]))||_f7;_f9.push([_fa,_fb[1],_fb[2]]);}_56(_f7);_9(_f9,function(_fc){_75(_f3.apply(null,_fc));});};}var _fd=0,_91=_3,_8f=_3;if(1){_91=function(){_fd&&clearTimeout(_fd);_fd=0;},_8f=function(){_91();if(req.waitms){_fd=window.setTimeout(function(){_91();_34(_44,_f("timeout",_8c));},req.waitms);}};}if(1){has.add("ie-event-behavior",!!doc.attachEvent&&(typeof opera==="undefined"||opera.toString()!="[object Opera]"));}if(1&&(1||1)){var _fe=function(_ff,_100,_101,_102){if(!has("ie-event-behavior")){_ff.addEventListener(_100,_102,false);return function(){_ff.removeEventListener(_100,_102,false);};}else{_ff.attachEvent(_101,_102);return function(){_ff.detachEvent(_101,_102);};}},_103=_fe(window,"load","onload",function(){req.pageLoaded=1;doc.readyState!="complete"&&(doc.readyState="complete");_103();});if(1){var _104=doc.getElementsByTagName("script")[0],_105=_104.parentNode;req.injectUrl=function(url,_106,_107){var node=_107.node=doc.createElement("script"),_108=function(e){e=e||window.event;var node=e.target||e.srcElement;if(e.type==="load"||/complete|loaded/.test(node.readyState)){_109();_10a();_106&&_106();}},_109=_fe(node,"load","onreadystatechange",_108),_10a=_fe(node,"error","onerror",function(e){_109();_10a();_34(_44,_f("scriptError",[url,e]));});node.type="text/javascript";node.charset="utf-8";node.src=url;_105.insertBefore(node,_104);return node;};}}if(1){req.log=function(){try{for(var i=0;i<arguments.length;i++){}}catch(e){}};}else{req.log=_3;}if(0){var _10b=req.trace=function(_10c,args){if(_10b.on&&_10b.group[_10c]){_34("trace",[_10c,args]);for(var arg,dump=[],text="trace:"+_10c+(args.length?(":"+args[0]):""),i=1;i<args.length;){arg=args[i++];if(_7(arg)){text+=", "+arg;}else{dump.push(arg);}}req.log(text);dump.length&&dump.push(".");req.log.apply(req,dump);}};_c(_10b,{on:1,group:{},set:function(_10d,_10e){if(_7(_10d)){_10b.group[_10d]=_10e;}else{_c(_10b.group,_10d);}}});_10b.set(_c(_c(_c({},_2.trace),_1.trace),_55.trace));on("config",function(_10f){_10f.trace&&_10b.set(_10f.trace);});}else{req.trace=_3;}var def=function(mid,_110,_111){var _112=arguments.length,_113=["require","exports","module"],args=[0,mid,_110];if(_112==1){args=[0,(_6(mid)?_113:[]),mid];}else{if(_112==2&&_7(mid)){args=[mid,(_6(_110)?_113:[]),_110];}else{if(_112==3){args=[mid,_110,_111];}}}if(0&&args[1]===_113){args[2].toString().replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,"").replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g,function(_114,dep){args[1].push(dep);});}req.trace("loader-define",args.slice(0,2));var _115=args[0]&&_31(args[0]),_116;if(_115&&!_8c[_115.mid]){_75(_f3(_115,args[1],args[2]));}else{if(!has("ie-event-behavior")||!1||_e8){_8b.push(args);}else{_115=_115||_7b;if(!_115){for(mid in _8c){_116=_2f[mid];if(_116&&_116.node&&_116.node.readyState==="interactive"){_115=_116;break;}}if(0&&!_115){for(var i=0;i<_73.length;i++){_115=_73[i];if(_115.node&&_115.node.readyState==="interactive"){break;}_115=0;}}}if(0&&_8(_115)){_75(_f3(_31(_115.shift()),args[1],args[2]));if(!_115.length){_73.splice(i,1);}}else{if(_115){_56(_115);_75(_f3(_115,args[1],args[2]));}else{_34(_44,_f("ieDefineFailed",args[0]));}}_7a();}}};def.amd={vendor:"dojotoolkit.org"};if(0){req.def=def;}_c(_c(req,_2.loaderPatch),_1.loaderPatch);on(_44,function(arg){try{console.error(arg);if(arg instanceof Error){for(var p in arg){}}}catch(e){}});_c(req,{uid:uid,cache:_52,packs:_4f});if(0){_c(req,{paths:_4d,aliases:_4c,modules:_2f,legacyMode:_25,execQ:_30,defQ:_8b,waiting:_8c,packs:_4f,mapProgs:_50,pathsMapProg:_4e,listenerQueues:_43,computeMapProg:_5e,runMapProg:_93,compactPath:_95,getModuleInfo:_9b});}if(_17.define){if(1){_34(_44,_f("defineAlreadyDefined",0));}return;}else{_17.define=def;_17.require=req;if(0){require=req;}}if(0&&req.combo&&req.combo.plugins){var _117=req.combo.plugins,_118;for(_118 in _117){_c(_c(_31(_118),_117[_118]),{isCombo:1,executed:"executed",load:1});}}if(1){var _119=_55.deps||_1.deps||_2.deps,_11a=_55.callback||_1.callback||_2.callback;req.boot=(_119||_11a)?[_119||[],_11a]:0;}if(!1){!req.async&&req(["dojo"]);req.boot&&req.apply(null,req.boot);}})(this.dojoConfig||this.djConfig||this.require||{},{async:0,hasCache:{"config-selectorEngine":"acme","config-tlmSiblingOfDojo":1,"dojo-built":1,"dojo-loader":1,dom:1,"host-browser":1},packages:[{location:"../dijit",name:"dijit"},{location:"../dojox",name:"dojox"},{location:".",name:"dojo"}]});require({cache:{"dojo/_base/fx":function(){define(["./kernel","./config","./lang","../Evented","./Color","./connect","./sniff","../dom","../dom-style"],function(dojo,_11b,lang,_11c,_11d,_11e,has,dom,_11f){var _120=lang.mixin;var _121={};var _122=_121._Line=function(_123,end){this.start=_123;this.end=end;};_122.prototype.getValue=function(n){return ((this.end-this.start)*n)+this.start;};var _124=_121.Animation=function(args){_120(this,args);if(lang.isArray(this.curve)){this.curve=new _122(this.curve[0],this.curve[1]);}};_124.prototype=new _11c();lang.extend(_124,{duration:350,repeat:0,rate:20,_percent:0,_startRepeatCount:0,_getStep:function(){var _125=this._percent,_126=this.easing;return _126?_126(_125):_125;},_fire:function(evt,args){var a=args||[];if(this[evt]){if(_11b.debugAtAllCosts){this[evt].apply(this,a);}else{try{this[evt].apply(this,a);}catch(e){console.error("exception in animation handler for:",evt);console.error(e);}}}return this;},play:function(_127,_128){var _129=this;if(_129._delayTimer){_129._clearTimer();}if(_128){_129._stopTimer();_129._active=_129._paused=false;_129._percent=0;}else{if(_129._active&&!_129._paused){return _129;}}_129._fire("beforeBegin",[_129.node]);var de=_127||_129.delay,_12a=lang.hitch(_129,"_play",_128);if(de>0){_129._delayTimer=setTimeout(_12a,de);return _129;}_12a();return _129;},_play:function(_12b){var _12c=this;if(_12c._delayTimer){_12c._clearTimer();}_12c._startTime=new Date().valueOf();if(_12c._paused){_12c._startTime-=_12c.duration*_12c._percent;}_12c._active=true;_12c._paused=false;var _12d=_12c.curve.getValue(_12c._getStep());if(!_12c._percent){if(!_12c._startRepeatCount){_12c._startRepeatCount=_12c.repeat;}_12c._fire("onBegin",[_12d]);}_12c._fire("onPlay",[_12d]);_12c._cycle();return _12c;},pause:function(){var _12e=this;if(_12e._delayTimer){_12e._clearTimer();}_12e._stopTimer();if(!_12e._active){return _12e;}_12e._paused=true;_12e._fire("onPause",[_12e.curve.getValue(_12e._getStep())]);return _12e;},gotoPercent:function(_12f,_130){var _131=this;_131._stopTimer();_131._active=_131._paused=true;_131._percent=_12f;if(_130){_131.play();}return _131;},stop:function(_132){var _133=this;if(_133._delayTimer){_133._clearTimer();}if(!_133._timer){return _133;}_133._stopTimer();if(_132){_133._percent=1;}_133._fire("onStop",[_133.curve.getValue(_133._getStep())]);_133._active=_133._paused=false;return _133;},status:function(){if(this._active){return this._paused?"paused":"playing";}return "stopped";},_cycle:function(){var _134=this;if(_134._active){var curr=new Date().valueOf();var step=_134.duration===0?1:(curr-_134._startTime)/(_134.duration);if(step>=1){step=1;}_134._percent=step;if(_134.easing){step=_134.easing(step);}_134._fire("onAnimate",[_134.curve.getValue(step)]);if(_134._percent<1){_134._startTimer();}else{_134._active=false;if(_134.repeat>0){_134.repeat--;_134.play(null,true);}else{if(_134.repeat==-1){_134.play(null,true);}else{if(_134._startRepeatCount){_134.repeat=_134._startRepeatCount;_134._startRepeatCount=0;}}}_134._percent=0;_134._fire("onEnd",[_134.node]);!_134.repeat&&_134._stopTimer();}}return _134;},_clearTimer:function(){clearTimeout(this._delayTimer);delete this._delayTimer;}});var ctr=0,_135=null,_136={run:function(){}};lang.extend(_124,{_startTimer:function(){if(!this._timer){this._timer=_11e.connect(_136,"run",this,"_cycle");ctr++;}if(!_135){_135=setInterval(lang.hitch(_136,"run"),this.rate);}},_stopTimer:function(){if(this._timer){_11e.disconnect(this._timer);this._timer=null;ctr--;}if(ctr<=0){clearInterval(_135);_135=null;ctr=0;}}});var _137=has("ie")?function(node){var ns=node.style;if(!ns.width.length&&_11f.get(node,"width")=="auto"){ns.width="auto";}}:function(){};_121._fade=function(args){args.node=dom.byId(args.node);var _138=_120({properties:{}},args),_139=(_138.properties.opacity={});_139.start=!("start" in _138)?function(){return +_11f.get(_138.node,"opacity")||0;}:_138.start;_139.end=_138.end;var anim=_121.animateProperty(_138);_11e.connect(anim,"beforeBegin",lang.partial(_137,_138.node));return anim;};_121.fadeIn=function(args){return _121._fade(_120({end:1},args));};_121.fadeOut=function(args){return _121._fade(_120({end:0},args));};_121._defaultEasing=function(n){return 0.5+((Math.sin((n+1.5)*Math.PI))/2);};var _13a=function(_13b){this._properties=_13b;for(var p in _13b){var prop=_13b[p];if(prop.start instanceof _11d){prop.tempColor=new _11d();}}};_13a.prototype.getValue=function(r){var ret={};for(var p in this._properties){var prop=this._properties[p],_13c=prop.start;if(_13c instanceof _11d){ret[p]=_11d.blendColors(_13c,prop.end,r,prop.tempColor).toCss();}else{if(!lang.isArray(_13c)){ret[p]=((prop.end-_13c)*r)+_13c+(p!="opacity"?prop.units||"px":0);}}}return ret;};_121.animateProperty=function(args){var n=args.node=dom.byId(args.node);if(!args.easing){args.easing=dojo._defaultEasing;}var anim=new _124(args);_11e.connect(anim,"beforeBegin",anim,function(){var pm={};for(var p in this.properties){if(p=="width"||p=="height"){this.node.display="block";}var prop=this.properties[p];if(lang.isFunction(prop)){prop=prop(n);}prop=pm[p]=_120({},(lang.isObject(prop)?prop:{end:prop}));if(lang.isFunction(prop.start)){prop.start=prop.start(n);}if(lang.isFunction(prop.end)){prop.end=prop.end(n);}var _13d=(p.toLowerCase().indexOf("color")>=0);function _13e(node,p){var v={height:node.offsetHeight,width:node.offsetWidth}[p];if(v!==undefined){return v;}v=_11f.get(node,p);return (p=="opacity")?+v:(_13d?v:parseFloat(v));};if(!("end" in prop)){prop.end=_13e(n,p);}else{if(!("start" in prop)){prop.start=_13e(n,p);}}if(_13d){prop.start=new _11d(prop.start);prop.end=new _11d(prop.end);}else{prop.start=(p=="opacity")?+prop.start:parseFloat(prop.start);}}this.curve=new _13a(pm);});_11e.connect(anim,"onAnimate",lang.hitch(_11f,"set",anim.node));return anim;};_121.anim=function(node,_13f,_140,_141,_142,_143){return _121.animateProperty({node:node,duration:_140||_124.prototype.duration,properties:_13f,easing:_141,onEnd:_142}).play(_143||0);};if(1){_120(dojo,_121);dojo._Animation=_124;}return _121;});},"dojo/dom-form":function(){define(["./_base/lang","./dom","./io-query","./json"],function(lang,dom,ioq,json){function _144(obj,name,_145){if(_145===null){return;}var val=obj[name];if(typeof val=="string"){obj[name]=[val,_145];}else{if(lang.isArray(val)){val.push(_145);}else{obj[name]=_145;}}};var _146="file|submit|image|reset|button";var form={fieldToObject:function fieldToObject(_147){var ret=null;_147=dom.byId(_147);if(_147){var _148=_147.name,type=(_147.type||"").toLowerCase();if(_148&&type&&!_147.disabled){if(type=="radio"||type=="checkbox"){if(_147.checked){ret=_147.value;}}else{if(_147.multiple){ret=[];var _149=[_147.firstChild];while(_149.length){for(var node=_149.pop();node;node=node.nextSibling){if(node.nodeType==1&&node.tagName.toLowerCase()=="option"){if(node.selected){ret.push(node.value);}}else{if(node.nextSibling){_149.push(node.nextSibling);}if(node.firstChild){_149.push(node.firstChild);}break;}}}}else{ret=_147.value;}}}}return ret;},toObject:function formToObject(_14a){var ret={},_14b=dom.byId(_14a).elements;for(var i=0,l=_14b.length;i<l;++i){var item=_14b[i],_14c=item.name,type=(item.type||"").toLowerCase();if(_14c&&type&&_146.indexOf(type)<0&&!item.disabled){_144(ret,_14c,form.fieldToObject(item));if(type=="image"){ret[_14c+".x"]=ret[_14c+".y"]=ret[_14c].x=ret[_14c].y=0;}}}return ret;},toQuery:function formToQuery(_14d){return ioq.objectToQuery(form.toObject(_14d));},toJson:function formToJson(_14e,_14f){return json.stringify(form.toObject(_14e),null,_14f?4:0);}};return form;});},"dojo/i18n":function(){define(["./_base/kernel","require","./has","./_base/array","./_base/config","./_base/lang","./_base/xhr","./json","module"],function(dojo,_150,has,_151,_152,lang,xhr,json,_153){has.add("dojo-preload-i18n-Api",1);1||has.add("dojo-v1x-i18n-Api",1);var _154=dojo.i18n={},_155=/(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,_156=function(root,_157,_158,_159){for(var _15a=[_158+_159],_15b=_157.split("-"),_15c="",i=0;i<_15b.length;i++){_15c+=(_15c?"-":"")+_15b[i];if(!root||root[_15c]){_15a.push(_158+_15c+"/"+_159);}}return _15a;},_15d={},_15e=function(_15f,_160,_161){_161=_161?_161.toLowerCase():dojo.locale;_15f=_15f.replace(/\./g,"/");_160=_160.replace(/\./g,"/");return (/root/i.test(_161))?(_15f+"/nls/"+_160):(_15f+"/nls/"+_161+"/"+_160);},_162=dojo.getL10nName=function(_163,_164,_165){return _163=_153.id+"!"+_15e(_163,_164,_165);},_166=function(_167,_168,_169,_16a,_16b,load){_167([_168],function(root){var _16c=lang.clone(root.root),_16d=_156(!root._v1x&&root,_16b,_169,_16a);_167(_16d,function(){for(var i=1;i<_16d.length;i++){_16c=lang.mixin(lang.clone(_16c),arguments[i]);}var _16e=_168+"/"+_16b;_15d[_16e]=_16c;load();});});},_16f=function(id,_170){return /^\./.test(id)?_170(id):id;},_171=function(_172){var list=_152.extraLocale||[];list=lang.isArray(list)?list:[list];list.push(_172);return list;},load=function(id,_173,load){if(has("dojo-preload-i18n-Api")){var _174=id.split("*"),_175=_174[1]=="preload";if(_175){if(!_15d[id]){_15d[id]=1;_176(_174[2],json.parse(_174[3]),1,_173);}load(1);}if(_175||_177(id,_173,load)){return;}}var _178=_155.exec(id),_179=_178[1]+"/",_17a=_178[5]||_178[4],_17b=_179+_17a,_17c=(_178[5]&&_178[4]),_17d=_17c||dojo.locale,_17e=_17b+"/"+_17d,_17f=_17c?[_17d]:_171(_17d),_180=_17f.length,_181=function(){if(!--_180){load(lang.delegate(_15d[_17e]));}};_151.forEach(_17f,function(_182){var _183=_17b+"/"+_182;if(has("dojo-preload-i18n-Api")){_184(_183);}if(!_15d[_183]){_166(_173,_17b,_179,_17a,_182,_181);}else{_181();}});};if(has("dojo-unit-tests")){var _185=_154.unitTests=[];}if(has("dojo-preload-i18n-Api")||1){var _186=_154.normalizeLocale=function(_187){var _188=_187?_187.toLowerCase():dojo.locale;return _188=="root"?"ROOT":_188;},isXd=function(mid,_189){return (1&&1)?_189.isXdUrl(_150.toUrl(mid+".js")):true;},_18a=0,_18b=[],_176=_154._preloadLocalizations=function(_18c,_18d,_18e,_18f){_18f=_18f||_150;function _190(mid,_191){if(isXd(mid,_18f)||_18e){_18f([mid],_191);}else{_19b([mid],_191,_18f);}};function _192(_193,func){var _194=_193.split("-");while(_194.length){if(func(_194.join("-"))){return;}_194.pop();}func("ROOT");};function _195(_196){_196=_186(_196);_192(_196,function(loc){if(_151.indexOf(_18d,loc)>=0){var mid=_18c.replace(/\./g,"/")+"_"+loc;_18a++;_190(mid,function(_197){for(var p in _197){_15d[_150.toAbsMid(p)+"/"+loc]=_197[p];}--_18a;while(!_18a&&_18b.length){load.apply(null,_18b.shift());}});return true;}return false;});};_195();_151.forEach(dojo.config.extraLocale,_195);},_177=function(id,_198,load){if(_18a){_18b.push([id,_198,load]);}return _18a;},_184=function(){};}if(1){var _199={},_19a=new Function("__bundle","__checkForLegacyModules","__mid","__amdValue","var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;},"+"\t require = function(){define.called = 1;};"+"try{"+"define.called = 0;"+"eval(__bundle);"+"if(define.called==1)"+"return __amdValue;"+"if((__checkForLegacyModules = __checkForLegacyModules(__mid)))"+"return __checkForLegacyModules;"+"}catch(e){}"+"try{"+"return eval('('+__bundle+')');"+"}catch(e){"+"return e;"+"}"),_19b=function(deps,_19c,_19d){var _19e=[];_151.forEach(deps,function(mid){var url=_19d.toUrl(mid+".js");function load(text){var _19f=_19a(text,_184,mid,_199);if(_19f===_199){_19e.push(_15d[url]=_199.result);}else{if(_19f instanceof Error){console.error("failed to evaluate i18n bundle; url="+url,_19f);_19f={};}_19e.push(_15d[url]=(/nls\/[^\/]+\/[^\/]+$/.test(url)?_19f:{root:_19f,_v1x:1}));}};if(_15d[url]){_19e.push(_15d[url]);}else{var _1a0=_19d.syncLoadNls(mid);if(_1a0){_19e.push(_1a0);}else{if(!xhr){try{_19d.getText(url,true,load);}catch(e){_19e.push(_15d[url]={});}}else{xhr.get({url:url,sync:true,load:load,error:function(){_19e.push(_15d[url]={});}});}}}});_19c&&_19c.apply(null,_19e);};_184=function(_1a1){for(var _1a2,_1a3=_1a1.split("/"),_1a4=dojo.global[_1a3[0]],i=1;_1a4&&i<_1a3.length-1;_1a4=_1a4[_1a3[i++]]){}if(_1a4){_1a2=_1a4[_1a3[i]];if(!_1a2){_1a2=_1a4[_1a3[i].replace(/-/g,"_")];}if(_1a2){_15d[_1a1]=_1a2;}}return _1a2;};_154.getLocalization=function(_1a5,_1a6,_1a7){var _1a8,_1a9=_15e(_1a5,_1a6,_1a7);load(_1a9,(!isXd(_1a9,_150)?function(deps,_1aa){_19b(deps,_1aa,_150);}:_150),function(_1ab){_1a8=_1ab;});return _1a8;};if(has("dojo-unit-tests")){_185.push(function(doh){doh.register("tests.i18n.unit",function(t){var _1ac;_1ac=_19a("{prop:1}",_184,"nonsense",_199);t.is({prop:1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("({prop:1})",_184,"nonsense",_199);t.is({prop:1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("{'prop-x':1}",_184,"nonsense",_199);t.is({"prop-x":1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("({'prop-x':1})",_184,"nonsense",_199);t.is({"prop-x":1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("define({'prop-x':1})",_184,"nonsense",_199);t.is(_199,_1ac);t.is({"prop-x":1},_199.result);_1ac=_19a("define('some/module', {'prop-x':1})",_184,"nonsense",_199);t.is(_199,_1ac);t.is({"prop-x":1},_199.result);_1ac=_19a("this is total nonsense and should throw an error",_184,"nonsense",_199);t.is(_1ac instanceof Error,true);});});}}return lang.mixin(_154,{dynamic:true,normalize:_16f,load:load,cache:_15d});});},"dojo/promise/tracer":function(){define(["../_base/lang","./Promise","../Evented"],function(lang,_1ad,_1ae){"use strict";var _1af=new _1ae;var emit=_1af.emit;_1af.emit=null;function _1b0(args){setTimeout(function(){emit.apply(_1af,args);},0);};_1ad.prototype.trace=function(){var args=lang._toArray(arguments);this.then(function(_1b1){_1b0(["resolved",_1b1].concat(args));},function(_1b2){_1b0(["rejected",_1b2].concat(args));},function(_1b3){_1b0(["progress",_1b3].concat(args));});return this;};_1ad.prototype.traceRejected=function(){var args=lang._toArray(arguments);this.otherwise(function(_1b4){_1b0(["rejected",_1b4].concat(args));});return this;};return _1af;});},"dojo/errors/RequestError":function(){define(["./create"],function(_1b5){return _1b5("RequestError",function(_1b6,_1b7){this.response=_1b7;});});},"dojo/_base/html":function(){define("dojo/_base/html",["./kernel","../dom","../dom-style","../dom-attr","../dom-prop","../dom-class","../dom-construct","../dom-geometry"],function(dojo,dom,_1b8,attr,prop,cls,ctr,geom){dojo.byId=dom.byId;dojo.isDescendant=dom.isDescendant;dojo.setSelectable=dom.setSelectable;dojo.getAttr=attr.get;dojo.setAttr=attr.set;dojo.hasAttr=attr.has;dojo.removeAttr=attr.remove;dojo.getNodeProp=attr.getNodeProp;dojo.attr=function(node,name,_1b9){if(arguments.length==2){return attr[typeof name=="string"?"get":"set"](node,name);}return attr.set(node,name,_1b9);};dojo.hasClass=cls.contains;dojo.addClass=cls.add;dojo.removeClass=cls.remove;dojo.toggleClass=cls.toggle;dojo.replaceClass=cls.replace;dojo._toDom=dojo.toDom=ctr.toDom;dojo.place=ctr.place;dojo.create=ctr.create;dojo.empty=function(node){ctr.empty(node);};dojo._destroyElement=dojo.destroy=function(node){ctr.destroy(node);};dojo._getPadExtents=dojo.getPadExtents=geom.getPadExtents;dojo._getBorderExtents=dojo.getBorderExtents=geom.getBorderExtents;dojo._getPadBorderExtents=dojo.getPadBorderExtents=geom.getPadBorderExtents;dojo._getMarginExtents=dojo.getMarginExtents=geom.getMarginExtents;dojo._getMarginSize=dojo.getMarginSize=geom.getMarginSize;dojo._getMarginBox=dojo.getMarginBox=geom.getMarginBox;dojo.setMarginBox=geom.setMarginBox;dojo._getContentBox=dojo.getContentBox=geom.getContentBox;dojo.setContentSize=geom.setContentSize;dojo._isBodyLtr=dojo.isBodyLtr=geom.isBodyLtr;dojo._docScroll=dojo.docScroll=geom.docScroll;dojo._getIeDocumentElementOffset=dojo.getIeDocumentElementOffset=geom.getIeDocumentElementOffset;dojo._fixIeBiDiScrollLeft=dojo.fixIeBiDiScrollLeft=geom.fixIeBiDiScrollLeft;dojo.position=geom.position;dojo.marginBox=function marginBox(node,box){return box?geom.setMarginBox(node,box):geom.getMarginBox(node);};dojo.contentBox=function contentBox(node,box){return box?geom.setContentSize(node,box):geom.getContentBox(node);};dojo.coords=function(node,_1ba){dojo.deprecated("dojo.coords()","Use dojo.position() or dojo.marginBox().");node=dom.byId(node);var s=_1b8.getComputedStyle(node),mb=geom.getMarginBox(node,s);var abs=geom.position(node,_1ba);mb.x=abs.x;mb.y=abs.y;return mb;};dojo.getProp=prop.get;dojo.setProp=prop.set;dojo.prop=function(node,name,_1bb){if(arguments.length==2){return prop[typeof name=="string"?"get":"set"](node,name);}return prop.set(node,name,_1bb);};dojo.getStyle=_1b8.get;dojo.setStyle=_1b8.set;dojo.getComputedStyle=_1b8.getComputedStyle;dojo.__toPixelValue=dojo.toPixelValue=_1b8.toPixelValue;dojo.style=function(node,name,_1bc){switch(arguments.length){case 1:return _1b8.get(node);case 2:return _1b8[typeof name=="string"?"get":"set"](node,name);}return _1b8.set(node,name,_1bc);};return dojo;});},"dojo/_base/kernel":function(){define(["../has","./config","require","module"],function(has,_1bd,_1be,_1bf){var i,p,_1c0={},_1c1={},dojo={config:_1bd,global:this,dijit:_1c0,dojox:_1c1};var _1c2={dojo:["dojo",dojo],dijit:["dijit",_1c0],dojox:["dojox",_1c1]},_1c3=(_1be.map&&_1be.map[_1bf.id.match(/[^\/]+/)[0]]),item;for(p in _1c3){if(_1c2[p]){_1c2[p][0]=_1c3[p];}else{_1c2[p]=[_1c3[p],{}];}}for(p in _1c2){item=_1c2[p];item[1]._scopeName=item[0];if(!_1bd.noGlobals){this[item[0]]=item[1];}}dojo.scopeMap=_1c2;dojo.baseUrl=dojo.config.baseUrl=_1be.baseUrl;dojo.isAsync=!1||_1be.async;dojo.locale=_1bd.locale;var rev="$Rev: 29458 $".match(/\d+/);dojo.version={major:1,minor:8,patch:0,flag:"",revision:rev?+rev[0]:NaN,toString:function(){var v=dojo.version;return v.major+"."+v.minor+"."+v.patch+v.flag+" ("+v.revision+")";}};1||has.add("extend-dojo",1);(Function("d","d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);if(0){dojo.exit=function(_1c4){quit(_1c4);};}else{dojo.exit=function(){};}1||has.add("dojo-guarantee-console",1);if(1){typeof console!="undefined"||(console={});var cn=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","profile","profileEnd","time","timeEnd","trace","warn","log"];var tn;i=0;while((tn=cn[i++])){if(!console[tn]){(function(){var tcn=tn+"";console[tcn]=("log" in console)?function(){var a=Array.apply({},arguments);a.unshift(tcn+":");console["log"](a.join(" "));}:function(){};console[tcn]._fake=true;})();}}}has.add("dojo-debug-messages",!!_1bd.isDebug);dojo.deprecated=dojo.experimental=function(){};if(has("dojo-debug-messages")){dojo.deprecated=function(_1c5,_1c6,_1c7){var _1c8="DEPRECATED: "+_1c5;if(_1c6){_1c8+=" "+_1c6;}if(_1c7){_1c8+=" -- will be removed in version: "+_1c7;}console.warn(_1c8);};dojo.experimental=function(_1c9,_1ca){var _1cb="EXPERIMENTAL: "+_1c9+" -- APIs subject to change without notice.";if(_1ca){_1cb+=" "+_1ca;}console.warn(_1cb);};}1||has.add("dojo-modulePaths",1);if(1){if(_1bd.modulePaths){dojo.deprecated("dojo.modulePaths","use paths configuration");var _1cc={};for(p in _1bd.modulePaths){_1cc[p.replace(/\./g,"/")]=_1bd.modulePaths[p];}_1be({paths:_1cc});}}1||has.add("dojo-moduleUrl",1);if(1){dojo.moduleUrl=function(_1cd,url){dojo.deprecated("dojo.moduleUrl()","use require.toUrl","2.0");var _1ce=null;if(_1cd){_1ce=_1be.toUrl(_1cd.replace(/\./g,"/")+(url?("/"+url):"")+"/*.*").replace(/\/\*\.\*/,"")+(url?"":"/");}return _1ce;};}dojo._hasResource={};return dojo;});},"dojo/io-query":function(){define(["./_base/lang"],function(lang){var _1cf={};return {objectToQuery:function objectToQuery(map){var enc=encodeURIComponent,_1d0=[];for(var name in map){var _1d1=map[name];if(_1d1!=_1cf[name]){var _1d2=enc(name)+"=";if(lang.isArray(_1d1)){for(var i=0,l=_1d1.length;i<l;++i){_1d0.push(_1d2+enc(_1d1[i]));}}else{_1d0.push(_1d2+enc(_1d1));}}}return _1d0.join("&");},queryToObject:function queryToObject(str){var dec=decodeURIComponent,qp=str.split("&"),ret={},name,val;for(var i=0,l=qp.length,item;i<l;++i){item=qp[i];if(item.length){var s=item.indexOf("=");if(s<0){name=dec(item);val="";}else{name=dec(item.slice(0,s));val=dec(item.slice(s+1));}if(typeof ret[name]=="string"){ret[name]=[ret[name]];}if(lang.isArray(ret[name])){ret[name].push(val);}else{ret[name]=val;}}}return ret;}};});},"dojo/_base/Deferred":function(){define(["./kernel","../Deferred","../promise/Promise","../errors/CancelError","../has","./lang","../when"],function(dojo,_1d3,_1d4,_1d5,has,lang,when){var _1d6=function(){};var _1d7=Object.freeze||function(){};var _1d8=dojo.Deferred=function(_1d9){var _1da,_1db,_1dc,head,_1dd;var _1de=(this.promise=new _1d4());function _1df(_1e0){if(_1db){throw new Error("This deferred has already been resolved");}_1da=_1e0;_1db=true;_1e1();};function _1e1(){var _1e2;while(!_1e2&&_1dd){var _1e3=_1dd;_1dd=_1dd.next;if((_1e2=(_1e3.progress==_1d6))){_1db=false;}var func=(_1dc?_1e3.error:_1e3.resolved);if(has("config-useDeferredInstrumentation")){if(_1dc&&_1d3.instrumentRejected){_1d3.instrumentRejected(_1da,!!func);}}if(func){try{var _1e4=func(_1da);if(_1e4&&typeof _1e4.then==="function"){_1e4.then(lang.hitch(_1e3.deferred,"resolve"),lang.hitch(_1e3.deferred,"reject"),lang.hitch(_1e3.deferred,"progress"));continue;}var _1e5=_1e2&&_1e4===undefined;if(_1e2&&!_1e5){_1dc=_1e4 instanceof Error;}_1e3.deferred[_1e5&&_1dc?"reject":"resolve"](_1e5?_1da:_1e4);}catch(e){_1e3.deferred.reject(e);}}else{if(_1dc){_1e3.deferred.reject(_1da);}else{_1e3.deferred.resolve(_1da);}}}};this.resolve=this.callback=function(_1e6){this.fired=0;this.results=[_1e6,null];_1df(_1e6);};this.reject=this.errback=function(_1e7){_1dc=true;this.fired=1;if(has("config-useDeferredInstrumentation")){if(_1d3.instrumentRejected){_1d3.instrumentRejected(_1e7,!!_1dd);}}_1df(_1e7);this.results=[null,_1e7];};this.progress=function(_1e8){var _1e9=_1dd;while(_1e9){var _1ea=_1e9.progress;_1ea&&_1ea(_1e8);_1e9=_1e9.next;}};this.addCallbacks=function(_1eb,_1ec){this.then(_1eb,_1ec,_1d6);return this;};_1de.then=this.then=function(_1ed,_1ee,_1ef){var _1f0=_1ef==_1d6?this:new _1d8(_1de.cancel);var _1f1={resolved:_1ed,error:_1ee,progress:_1ef,deferred:_1f0};if(_1dd){head=head.next=_1f1;}else{_1dd=head=_1f1;}if(_1db){_1e1();}return _1f0.promise;};var _1f2=this;_1de.cancel=this.cancel=function(){if(!_1db){var _1f3=_1d9&&_1d9(_1f2);if(!_1db){if(!(_1f3 instanceof Error)){_1f3=new _1d5(_1f3);}_1f3.log=false;_1f2.reject(_1f3);}}};_1d7(_1de);};lang.extend(_1d8,{addCallback:function(_1f4){return this.addCallbacks(lang.hitch.apply(dojo,arguments));},addErrback:function(_1f5){return this.addCallbacks(null,lang.hitch.apply(dojo,arguments));},addBoth:function(_1f6){var _1f7=lang.hitch.apply(dojo,arguments);return this.addCallbacks(_1f7,_1f7);},fired:-1});_1d8.when=dojo.when=when;return _1d8;});},"dojo/NodeList-dom":function(){define(["./_base/kernel","./query","./_base/array","./_base/lang","./dom-class","./dom-construct","./dom-geometry","./dom-attr","./dom-style"],function(dojo,_1f8,_1f9,lang,_1fa,_1fb,_1fc,_1fd,_1fe){var _1ff=function(a){return a.length==1&&(typeof a[0]=="string");};var _200=function(node){var p=node.parentNode;if(p){p.removeChild(node);}};var _201=_1f8.NodeList,awc=_201._adaptWithCondition,aafe=_201._adaptAsForEach,aam=_201._adaptAsMap;function _202(_203){return function(node,name,_204){if(arguments.length==2){return _203[typeof name=="string"?"get":"set"](node,name);}return _203.set(node,name,_204);};};lang.extend(_201,{_normalize:function(_205,_206){var _207=_205.parse===true;if(typeof _205.template=="string"){var _208=_205.templateFunc||(dojo.string&&dojo.string.substitute);_205=_208?_208(_205.template,_205):_205;}var type=(typeof _205);if(type=="string"||type=="number"){_205=_1fb.toDom(_205,(_206&&_206.ownerDocument));if(_205.nodeType==11){_205=lang._toArray(_205.childNodes);}else{_205=[_205];}}else{if(!lang.isArrayLike(_205)){_205=[_205];}else{if(!lang.isArray(_205)){_205=lang._toArray(_205);}}}if(_207){_205._runParse=true;}return _205;},_cloneNode:function(node){return node.cloneNode(true);},_place:function(ary,_209,_20a,_20b){if(_209.nodeType!=1&&_20a=="only"){return;}var _20c=_209,_20d;var _20e=ary.length;for(var i=_20e-1;i>=0;i--){var node=(_20b?this._cloneNode(ary[i]):ary[i]);if(ary._runParse&&dojo.parser&&dojo.parser.parse){if(!_20d){_20d=_20c.ownerDocument.createElement("div");}_20d.appendChild(node);dojo.parser.parse(_20d);node=_20d.firstChild;while(_20d.firstChild){_20d.removeChild(_20d.firstChild);}}if(i==_20e-1){_1fb.place(node,_20c,_20a);}else{_20c.parentNode.insertBefore(node,_20c);}_20c=node;}},position:aam(_1fc.position),attr:awc(_202(_1fd),_1ff),style:awc(_202(_1fe),_1ff),addClass:aafe(_1fa.add),removeClass:aafe(_1fa.remove),toggleClass:aafe(_1fa.toggle),replaceClass:aafe(_1fa.replace),empty:aafe(_1fb.empty),removeAttr:aafe(_1fd.remove),marginBox:aam(_1fc.getMarginBox),place:function(_20f,_210){var item=_1f8(_20f)[0];return this.forEach(function(node){_1fb.place(node,item,_210);});},orphan:function(_211){return (_211?_1f8._filterResult(this,_211):this).forEach(_200);},adopt:function(_212,_213){return _1f8(_212).place(this[0],_213)._stash(this);},query:function(_214){if(!_214){return this;}var ret=new _201;this.map(function(node){_1f8(_214,node).forEach(function(_215){if(_215!==undefined){ret.push(_215);}});});return ret._stash(this);},filter:function(_216){var a=arguments,_217=this,_218=0;if(typeof _216=="string"){_217=_1f8._filterResult(this,a[0]);if(a.length==1){return _217._stash(this);}_218=1;}return this._wrap(_1f9.filter(_217,a[_218],a[_218+1]),this);},addContent:function(_219,_21a){_219=this._normalize(_219,this[0]);for(var i=0,node;(node=this[i]);i++){this._place(_219,node,_21a,i>0);}return this;}});return _201;});},"dojo/query":function(){define(["./_base/kernel","./has","./dom","./on","./_base/array","./_base/lang","./selector/_loader","./selector/_loader!default"],function(dojo,has,dom,on,_21b,lang,_21c,_21d){"use strict";has.add("array-extensible",function(){return lang.delegate([],{length:1}).length==1&&!has("bug-for-in-skips-shadowed");});var ap=Array.prototype,aps=ap.slice,apc=ap.concat,_21e=_21b.forEach;var tnl=function(a,_21f,_220){var _221=new (_220||this._NodeListCtor||nl)(a);return _21f?_221._stash(_21f):_221;};var _222=function(f,a,o){a=[0].concat(aps.call(a,0));o=o||dojo.global;return function(node){a[0]=node;return f.apply(o,a);};};var _223=function(f,o){return function(){this.forEach(_222(f,arguments,o));return this;};};var _224=function(f,o){return function(){return this.map(_222(f,arguments,o));};};var _225=function(f,o){return function(){return this.filter(_222(f,arguments,o));};};var _226=function(f,g,o){return function(){var a=arguments,body=_222(f,a,o);if(g.call(o||dojo.global,a)){return this.map(body);}this.forEach(body);return this;};};var _227=function(_228){var _229=this instanceof nl&&has("array-extensible");if(typeof _228=="number"){_228=Array(_228);}var _22a=(_228&&"length" in _228)?_228:arguments;if(_229||!_22a.sort){var _22b=_229?this:[],l=_22b.length=_22a.length;for(var i=0;i<l;i++){_22b[i]=_22a[i];}if(_229){return _22b;}_22a=_22b;}lang._mixin(_22a,nlp);_22a._NodeListCtor=function(_22c){return nl(_22c);};return _22a;};var nl=_227,nlp=nl.prototype=has("array-extensible")?[]:{};nl._wrap=nlp._wrap=tnl;nl._adaptAsMap=_224;nl._adaptAsForEach=_223;nl._adaptAsFilter=_225;nl._adaptWithCondition=_226;_21e(["slice","splice"],function(name){var f=ap[name];nlp[name]=function(){return this._wrap(f.apply(this,arguments),name=="slice"?this:null);};});_21e(["indexOf","lastIndexOf","every","some"],function(name){var f=_21b[name];nlp[name]=function(){return f.apply(dojo,[this].concat(aps.call(arguments,0)));};});lang.extend(_227,{constructor:nl,_NodeListCtor:nl,toString:function(){return this.join(",");},_stash:function(_22d){this._parent=_22d;return this;},on:function(_22e,_22f){var _230=this.map(function(node){return on(node,_22e,_22f);});_230.remove=function(){for(var i=0;i<_230.length;i++){_230[i].remove();}};return _230;},end:function(){if(this._parent){return this._parent;}else{return new this._NodeListCtor(0);}},concat:function(item){var t=aps.call(this,0),m=_21b.map(arguments,function(a){return aps.call(a,0);});return this._wrap(apc.apply(t,m),this);},map:function(func,obj){return this._wrap(_21b.map(this,func,obj),this);},forEach:function(_231,_232){_21e(this,_231,_232);return this;},filter:function(_233){var a=arguments,_234=this,_235=0;if(typeof _233=="string"){_234=_236._filterResult(this,a[0]);if(a.length==1){return _234._stash(this);}_235=1;}return this._wrap(_21b.filter(_234,a[_235],a[_235+1]),this);},instantiate:function(_237,_238){var c=lang.isFunction(_237)?_237:lang.getObject(_237);_238=_238||{};return this.forEach(function(node){new c(_238,node);});},at:function(){var t=new this._NodeListCtor(0);_21e(arguments,function(i){if(i<0){i=this.length+i;}if(this[i]){t.push(this[i]);}},this);return t._stash(this);}});function _239(_23a,_23b){var _23c=function(_23d,root){if(typeof root=="string"){root=dom.byId(root);if(!root){return new _23b([]);}}var _23e=typeof _23d=="string"?_23a(_23d,root):_23d?_23d.orphan?_23d:[_23d]:[];if(_23e.orphan){return _23e;}return new _23b(_23e);};_23c.matches=_23a.match||function(node,_23f,root){return _23c.filter([node],_23f,root).length>0;};_23c.filter=_23a.filter||function(_240,_241,root){return _23c(_241,root).filter(function(node){return _21b.indexOf(_240,node)>-1;});};if(typeof _23a!="function"){var _242=_23a.search;_23a=function(_243,root){return _242(root||document,_243);};}return _23c;};var _236=_239(_21d,_227);dojo.query=_239(_21d,function(_244){return _227(_244);});_236.load=function(id,_245,_246){_21c.load(id,_245,function(_247){_246(_239(_247,_227));});};dojo._filterQueryResult=_236._filterResult=function(_248,_249,root){return new _227(_236.filter(_248,_249,root));};dojo.NodeList=_236.NodeList=_227;return _236;});},"dojo/has":function(){define(["require","module"],function(_24a,_24b){var has=_24a.has||function(){};if(!1){var _24c=typeof window!="undefined"&&typeof location!="undefined"&&typeof document!="undefined"&&window.location==location&&window.document==document,_24d=this,doc=_24c&&document,_24e=doc&&doc.createElement("DiV"),_24f=(_24b.config&&_24b.config())||{};has=function(name){return typeof _24f[name]=="function"?(_24f[name]=_24f[name](_24d,doc,_24e)):_24f[name];};has.cache=_24f;has.add=function(name,test,now,_250){(typeof _24f[name]=="undefined"||_250)&&(_24f[name]=test);return now&&has(name);};1||has.add("host-browser",_24c);1||has.add("dom",_24c);1||has.add("dojo-dom-ready-api",1);1||has.add("dojo-sniff",1);}if(1){has.add("dom-addeventlistener",!!document.addEventListener);has.add("touch","ontouchstart" in document);has.add("device-width",screen.availWidth||innerWidth);var form=document.createElement("form");has.add("dom-attributes-explicit",form.attributes.length==0);has.add("dom-attributes-specified-flag",form.attributes.length>0&&form.attributes.length<40);}has.clearElement=function(_251){_251.innerHTML="";return _251;};has.normalize=function(id,_252){var _253=id.match(/[\?:]|[^:\?]*/g),i=0,get=function(skip){var term=_253[i++];if(term==":"){return 0;}else{if(_253[i++]=="?"){if(!skip&&has(term)){return get();}else{get(true);return get(skip);}}return term||0;}};id=get();return id&&_252(id);};has.load=function(id,_254,_255){if(id){_254([id],_255);}else{_255();}};return has;});},"dojo/_base/loader":function(){define(["./kernel","../has","require","module","./json","./lang","./array"],function(dojo,has,_256,_257,json,lang,_258){if(!1){console.error("cannot load the Dojo v1.x loader with a foreign loader");return 0;}1||has.add("dojo-fast-sync-require",1);var _259=function(id){return {src:_257.id,id:id};},_25a=function(name){return name.replace(/\./g,"/");},_25b=/\/\/>>built/,_25c=[],_25d=[],_25e=function(mid,_25f,_260){_25c.push(_260);_258.forEach(mid.split(","),function(mid){var _261=_262(mid,_25f.module);_25d.push(_261);_263(_261);});_264();},_264=(1?function(){var _265,mid;for(mid in _266){_265=_266[mid];if(_265.noReqPluginCheck===undefined){_265.noReqPluginCheck=/loadInit\!/.test(mid)||/require\!/.test(mid)?1:0;}if(!_265.executed&&!_265.noReqPluginCheck&&_265.injected==_267){return;}}_268(function(){var _269=_25c;_25c=[];_258.forEach(_269,function(cb){cb(1);});});}:(function(){var _26a,_26b=function(m){_26a[m.mid]=1;for(var t,_26c,deps=m.deps||[],i=0;i<deps.length;i++){_26c=deps[i];if(!(t=_26a[_26c.mid])){if(t===0||!_26b(_26c)){_26a[m.mid]=0;return false;}}}return true;};return function(){var _26d,mid;_26a={};for(mid in _266){_26d=_266[mid];if(_26d.executed||_26d.noReqPluginCheck){_26a[mid]=1;}else{if(_26d.noReqPluginCheck!==0){_26d.noReqPluginCheck=/loadInit\!/.test(mid)||/require\!/.test(mid)?1:0;}if(_26d.noReqPluginCheck){_26a[mid]=1;}else{if(_26d.injected!==_299){_26a[mid]=0;}}}}for(var t,i=0,end=_25d.length;i<end;i++){_26d=_25d[i];if(!(t=_26a[_26d.mid])){if(t===0||!_26b(_26d)){return;}}}_268(function(){var _26e=_25c;_25c=[];_258.forEach(_26e,function(cb){cb(1);});});};})()),_26f=function(mid,_270,_271){_270([mid],function(_272){_270(_272.names,function(){for(var _273="",args=[],i=0;i<arguments.length;i++){_273+="var "+_272.names[i]+"= arguments["+i+"]; ";args.push(arguments[i]);}eval(_273);var _274=_270.module,_275=[],_276,_277={provide:function(_278){_278=_25a(_278);var _279=_262(_278,_274);if(_279!==_274){_29f(_279);}},require:function(_27a,_27b){_27a=_25a(_27a);_27b&&(_262(_27a,_274).result=_29a);_275.push(_27a);},requireLocalization:function(_27c,_27d,_27e){if(!_276){_276=["dojo/i18n"];}_27e=(_27e||dojo.locale).toLowerCase();_27c=_25a(_27c)+"/nls/"+(/root/i.test(_27e)?"":_27e+"/")+_25a(_27d);if(_262(_27c,_274).isXd){_276.push("dojo/i18n!"+_27c);}},loadInit:function(f){f();}},hold={},p;try{for(p in _277){hold[p]=dojo[p];dojo[p]=_277[p];}_272.def.apply(null,args);}catch(e){_27f("error",[_259("failedDojoLoadInit"),e]);}finally{for(p in _277){dojo[p]=hold[p];}}if(_276){_275=_275.concat(_276);}if(_275.length){_25e(_275.join(","),_270,_271);}else{_271();}});});},_280=function(text,_281,_282){var _283=/\(|\)/g,_284=1,_285;_283.lastIndex=_281;while((_285=_283.exec(text))){if(_285[0]==")"){_284-=1;}else{_284+=1;}if(_284==0){break;}}if(_284!=0){throw "unmatched paren around character "+_283.lastIndex+" in: "+text;}return [dojo.trim(text.substring(_282,_283.lastIndex))+";\n",_283.lastIndex];},_286=/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,_287=/(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,_288=/(^|\s)(require|define)\s*\(/m,_289=function(text,_28a){var _28b,_28c,_28d,_28e,_28f=[],_290=[],_291=[];_28a=_28a||text.replace(_286,function(_292){_287.lastIndex=_288.lastIndex=0;return (_287.test(_292)||_288.test(_292))?"":_292;});while((_28b=_287.exec(_28a))){_28c=_287.lastIndex;_28d=_28c-_28b[0].length;_28e=_280(_28a,_28c,_28d);if(_28b[2]=="loadInit"){_28f.push(_28e[0]);}else{_290.push(_28e[0]);}_287.lastIndex=_28e[1];}_291=_28f.concat(_290);if(_291.length||!_288.test(_28a)){return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g,"\n0 && dojo.loadInit("),_291.join(""),_291];}else{return 0;}},_293=function(_294,text){var _295,id,_296=[],_297=[];if(_25b.test(text)||!(_295=_289(text))){return 0;}id=_294.mid+"-*loadInit";for(var p in _262("dojo",_294).result.scopeMap){_296.push(p);_297.push("\""+p+"\"");}return "// xdomain rewrite of "+_294.mid+"\n"+"define('"+id+"',{\n"+"\tnames:"+dojo.toJson(_296)+",\n"+"\tdef:function("+_296.join(",")+"){"+_295[1]+"}"+"});\n\n"+"define("+dojo.toJson(_296.concat(["dojo/loadInit!"+id]))+", function("+_296.join(",")+"){\n"+_295[0]+"});";},_298=_256.initSyncLoader(_25e,_264,_293),sync=_298.sync,_267=_298.requested,_299=_298.arrived,_29a=_298.nonmodule,_29b=_298.executing,_29c=_298.executed,_29d=_298.syncExecStack,_266=_298.modules,_29e=_298.execQ,_262=_298.getModule,_263=_298.injectModule,_29f=_298.setArrived,_27f=_298.signal,_2a0=_298.finishExec,_2a1=_298.execModule,_2a2=_298.getLegacyMode,_268=_298.guardCheckComplete;_25e=_298.dojoRequirePlugin;dojo.provide=function(mid){var _2a3=_29d[0],_2a4=lang.mixin(_262(_25a(mid),_256.module),{executed:_29b,result:lang.getObject(mid,true)});_29f(_2a4);if(_2a3){(_2a3.provides||(_2a3.provides=[])).push(function(){_2a4.result=lang.getObject(mid);delete _2a4.provides;_2a4.executed!==_29c&&_2a0(_2a4);});}return _2a4.result;};has.add("config-publishRequireResult",1,0,0);dojo.require=function(_2a5,_2a6){function _2a7(mid,_2a8){var _2a9=_262(_25a(mid),_256.module);if(_29d.length&&_29d[0].finish){_29d[0].finish.push(mid);return undefined;}if(_2a9.executed){return _2a9.result;}_2a8&&(_2a9.result=_29a);var _2aa=_2a2();_263(_2a9);_2aa=_2a2();if(_2a9.executed!==_29c&&_2a9.injected===_299){_298.guardCheckComplete(function(){_2a1(_2a9);});}if(_2a9.executed){return _2a9.result;}if(_2aa==sync){if(_2a9.cjs){_29e.unshift(_2a9);}else{_29d.length&&(_29d[0].finish=[mid]);}}else{_29e.push(_2a9);}return undefined;};var _2ab=_2a7(_2a5,_2a6);if(has("config-publishRequireResult")&&!lang.exists(_2a5)&&_2ab!==undefined){lang.setObject(_2a5,_2ab);}return _2ab;};dojo.loadInit=function(f){f();};dojo.registerModulePath=function(_2ac,_2ad){var _2ae={};_2ae[_2ac.replace(/\./g,"/")]=_2ad;_256({paths:_2ae});};dojo.platformRequire=function(_2af){var _2b0=(_2af.common||[]).concat(_2af[dojo._name]||_2af["default"]||[]),temp;while(_2b0.length){if(lang.isArray(temp=_2b0.shift())){dojo.require.apply(dojo,temp);}else{dojo.require(temp);}}};dojo.requireIf=dojo.requireAfterIf=function(_2b1,_2b2,_2b3){if(_2b1){dojo.require(_2b2,_2b3);}};dojo.requireLocalization=function(_2b4,_2b5,_2b6){_256(["../i18n"],function(i18n){i18n.getLocalization(_2b4,_2b5,_2b6);});};return {extractLegacyApiApplications:_289,require:_25e,loadInit:_26f};});},"dojo/json":function(){define(["./has"],function(has){"use strict";var _2b7=typeof JSON!="undefined";has.add("json-parse",_2b7);has.add("json-stringify",_2b7&&JSON.stringify({a:0},function(k,v){return v||1;})=="{\"a\":1}");if(has("json-stringify")){return JSON;}else{var _2b8=function(str){return ("\""+str.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");};return {parse:has("json-parse")?JSON.parse:function(str,_2b9){if(_2b9&&!/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){throw new SyntaxError("Invalid characters in JSON");}return eval("("+str+")");},stringify:function(_2ba,_2bb,_2bc){var _2bd;if(typeof _2bb=="string"){_2bc=_2bb;_2bb=null;}function _2be(it,_2bf,key){if(_2bb){it=_2bb(key,it);}var val,_2c0=typeof it;if(_2c0=="number"){return isFinite(it)?it+"":"null";}if(_2c0=="boolean"){return it+"";}if(it===null){return "null";}if(typeof it=="string"){return _2b8(it);}if(_2c0=="function"||_2c0=="undefined"){return _2bd;}if(typeof it.toJSON=="function"){return _2be(it.toJSON(key),_2bf,key);}if(it instanceof Date){return "\"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z\"".replace(/\{(\w+)(\+)?\}/g,function(t,prop,plus){var num=it["getUTC"+prop]()+(plus?1:0);return num<10?"0"+num:num;});}if(it.valueOf()!==it){return _2be(it.valueOf(),_2bf,key);}var _2c1=_2bc?(_2bf+_2bc):"";var sep=_2bc?" ":"";var _2c2=_2bc?"\n":"";if(it instanceof Array){var itl=it.length,res=[];for(key=0;key<itl;key++){var obj=it[key];val=_2be(obj,_2c1,key);if(typeof val!="string"){val="null";}res.push(_2c2+_2c1+val);}return "["+res.join(",")+_2c2+_2bf+"]";}var _2c3=[];for(key in it){var _2c4;if(it.hasOwnProperty(key)){if(typeof key=="number"){_2c4="\""+key+"\"";}else{if(typeof key=="string"){_2c4=_2b8(key);}else{continue;}}val=_2be(it[key],_2c1,key);if(typeof val!="string"){continue;}_2c3.push(_2c2+_2c1+_2c4+":"+sep+val);}}return "{"+_2c3.join(",")+_2c2+_2bf+"}";};return _2be(_2ba,"","");}};}});},"dojo/_base/declare":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var mix=lang.mixin,op=Object.prototype,opts=op.toString,xtor=new Function,_2c5=0,_2c6="constructor";function err(msg,cls){throw new Error("declare"+(cls?" "+cls:"")+": "+msg);};function _2c7(_2c8,_2c9){var _2ca=[],_2cb=[{cls:0,refs:[]}],_2cc={},_2cd=1,l=_2c8.length,i=0,j,lin,base,top,_2ce,rec,name,refs;for(;i<l;++i){base=_2c8[i];if(!base){err("mixin #"+i+" is unknown. Did you use dojo.require to pull it in?",_2c9);}else{if(opts.call(base)!="[object Function]"){err("mixin #"+i+" is not a callable constructor.",_2c9);}}lin=base._meta?base._meta.bases:[base];top=0;for(j=lin.length-1;j>=0;--j){_2ce=lin[j].prototype;if(!_2ce.hasOwnProperty("declaredClass")){_2ce.declaredClass="uniqName_"+(_2c5++);}name=_2ce.declaredClass;if(!_2cc.hasOwnProperty(name)){_2cc[name]={count:0,refs:[],cls:lin[j]};++_2cd;}rec=_2cc[name];if(top&&top!==rec){rec.refs.push(top);++top.count;}top=rec;}++top.count;_2cb[0].refs.push(top);}while(_2cb.length){top=_2cb.pop();_2ca.push(top.cls);--_2cd;while(refs=top.refs,refs.length==1){top=refs[0];if(!top||--top.count){top=0;break;}_2ca.push(top.cls);--_2cd;}if(top){for(i=0,l=refs.length;i<l;++i){top=refs[i];if(!--top.count){_2cb.push(top);}}}}if(_2cd){err("can't build consistent linearization",_2c9);}base=_2c8[0];_2ca[0]=base?base._meta&&base===_2ca[_2ca.length-base._meta.bases.length]?base._meta.bases.length:1:0;return _2ca;};function _2cf(args,a,f){var name,_2d0,_2d1,_2d2,meta,base,_2d3,opf,pos,_2d4=this._inherited=this._inherited||{};if(typeof args=="string"){name=args;args=a;a=f;}f=0;_2d2=args.callee;name=name||_2d2.nom;if(!name){err("can't deduce a name to call inherited()",this.declaredClass);}meta=this.constructor._meta;_2d1=meta.bases;pos=_2d4.p;if(name!=_2c6){if(_2d4.c!==_2d2){pos=0;base=_2d1[0];meta=base._meta;if(meta.hidden[name]!==_2d2){_2d0=meta.chains;if(_2d0&&typeof _2d0[name]=="string"){err("calling chained method with inherited: "+name,this.declaredClass);}do{meta=base._meta;_2d3=base.prototype;if(meta&&(_2d3[name]===_2d2&&_2d3.hasOwnProperty(name)||meta.hidden[name]===_2d2)){break;}}while(base=_2d1[++pos]);pos=base?pos:-1;}}base=_2d1[++pos];if(base){_2d3=base.prototype;if(base._meta&&_2d3.hasOwnProperty(name)){f=_2d3[name];}else{opf=op[name];do{_2d3=base.prototype;f=_2d3[name];if(f&&(base._meta?_2d3.hasOwnProperty(name):f!==opf)){break;}}while(base=_2d1[++pos]);}}f=base&&f||op[name];}else{if(_2d4.c!==_2d2){pos=0;meta=_2d1[0]._meta;if(meta&&meta.ctor!==_2d2){_2d0=meta.chains;if(!_2d0||_2d0.constructor!=="manual"){err("calling chained constructor with inherited",this.declaredClass);}while(base=_2d1[++pos]){meta=base._meta;if(meta&&meta.ctor===_2d2){break;}}pos=base?pos:-1;}}while(base=_2d1[++pos]){meta=base._meta;f=meta?meta.ctor:base;if(f){break;}}f=base&&f;}_2d4.c=f;_2d4.p=pos;if(f){return a===true?f:f.apply(this,a||args);}};function _2d5(name,args){if(typeof name=="string"){return this.__inherited(name,args,true);}return this.__inherited(name,true);};function _2d6(args,a1,a2){var f=this.getInherited(args,a1);if(f){return f.apply(this,a2||a1||args);}};var _2d7=dojo.config.isDebug?_2d6:_2cf;function _2d8(cls){var _2d9=this.constructor._meta.bases;for(var i=0,l=_2d9.length;i<l;++i){if(_2d9[i]===cls){return true;}}return this instanceof cls;};function _2da(_2db,_2dc){for(var name in _2dc){if(name!=_2c6&&_2dc.hasOwnProperty(name)){_2db[name]=_2dc[name];}}if(has("bug-for-in-skips-shadowed")){for(var _2dd=lang._extraNames,i=_2dd.length;i;){name=_2dd[--i];if(name!=_2c6&&_2dc.hasOwnProperty(name)){_2db[name]=_2dc[name];}}}};function _2de(_2df,_2e0){var name,t;for(name in _2e0){t=_2e0[name];if((t!==op[name]||!(name in op))&&name!=_2c6){if(opts.call(t)=="[object Function]"){t.nom=name;}_2df[name]=t;}}if(has("bug-for-in-skips-shadowed")){for(var _2e1=lang._extraNames,i=_2e1.length;i;){name=_2e1[--i];t=_2e0[name];if((t!==op[name]||!(name in op))&&name!=_2c6){if(opts.call(t)=="[object Function]"){t.nom=name;}_2df[name]=t;}}}return _2df;};function _2e2(_2e3){_2e4.safeMixin(this.prototype,_2e3);return this;};function _2e5(_2e6){return _2e4([this].concat(_2e6));};function _2e7(_2e8,_2e9){return function(){var a=arguments,args=a,a0=a[0],f,i,m,l=_2e8.length,_2ea;if(!(this instanceof a.callee)){return _2eb(a);}if(_2e9&&(a0&&a0.preamble||this.preamble)){_2ea=new Array(_2e8.length);_2ea[0]=a;for(i=0;;){a0=a[0];if(a0){f=a0.preamble;if(f){a=f.apply(this,a)||a;}}f=_2e8[i].prototype;f=f.hasOwnProperty("preamble")&&f.preamble;if(f){a=f.apply(this,a)||a;}if(++i==l){break;}_2ea[i]=a;}}for(i=l-1;i>=0;--i){f=_2e8[i];m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,_2ea?_2ea[i]:a);}}f=this.postscript;if(f){f.apply(this,args);}};};function _2ec(ctor,_2ed){return function(){var a=arguments,t=a,a0=a[0],f;if(!(this instanceof a.callee)){return _2eb(a);}if(_2ed){if(a0){f=a0.preamble;if(f){t=f.apply(this,t)||t;}}f=this.preamble;if(f){f.apply(this,t);}}if(ctor){ctor.apply(this,a);}f=this.postscript;if(f){f.apply(this,a);}};};function _2ee(_2ef){return function(){var a=arguments,i=0,f,m;if(!(this instanceof a.callee)){return _2eb(a);}for(;f=_2ef[i];++i){m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,a);break;}}f=this.postscript;if(f){f.apply(this,a);}};};function _2f0(name,_2f1,_2f2){return function(){var b,m,f,i=0,step=1;if(_2f2){i=_2f1.length-1;step=-1;}for(;b=_2f1[i];i+=step){m=b._meta;f=(m?m.hidden:b.prototype)[name];if(f){f.apply(this,arguments);}}};};function _2f3(ctor){xtor.prototype=ctor.prototype;var t=new xtor;xtor.prototype=null;return t;};function _2eb(args){var ctor=args.callee,t=_2f3(ctor);ctor.apply(t,args);return t;};function _2e4(_2f4,_2f5,_2f6){if(typeof _2f4!="string"){_2f6=_2f5;_2f5=_2f4;_2f4="";}_2f6=_2f6||{};var _2f7,i,t,ctor,name,_2f8,_2f9,_2fa=1,_2fb=_2f5;if(opts.call(_2f5)=="[object Array]"){_2f8=_2c7(_2f5,_2f4);t=_2f8[0];_2fa=_2f8.length-t;_2f5=_2f8[_2fa];}else{_2f8=[0];if(_2f5){if(opts.call(_2f5)=="[object Function]"){t=_2f5._meta;_2f8=_2f8.concat(t?t.bases:_2f5);}else{err("base class is not a callable constructor.",_2f4);}}else{if(_2f5!==null){err("unknown base class. Did you use dojo.require to pull it in?",_2f4);}}}if(_2f5){for(i=_2fa-1;;--i){_2f7=_2f3(_2f5);if(!i){break;}t=_2f8[i];(t._meta?_2da:mix)(_2f7,t.prototype);ctor=new Function;ctor.superclass=_2f5;ctor.prototype=_2f7;_2f5=_2f7.constructor=ctor;}}else{_2f7={};}_2e4.safeMixin(_2f7,_2f6);t=_2f6.constructor;if(t!==op.constructor){t.nom=_2c6;_2f7.constructor=t;}for(i=_2fa-1;i;--i){t=_2f8[i]._meta;if(t&&t.chains){_2f9=mix(_2f9||{},t.chains);}}if(_2f7["-chains-"]){_2f9=mix(_2f9||{},_2f7["-chains-"]);}t=!_2f9||!_2f9.hasOwnProperty(_2c6);_2f8[0]=ctor=(_2f9&&_2f9.constructor==="manual")?_2ee(_2f8):(_2f8.length==1?_2ec(_2f6.constructor,t):_2e7(_2f8,t));ctor._meta={bases:_2f8,hidden:_2f6,chains:_2f9,parents:_2fb,ctor:_2f6.constructor};ctor.superclass=_2f5&&_2f5.prototype;ctor.extend=_2e2;ctor.createSubclass=_2e5;ctor.prototype=_2f7;_2f7.constructor=ctor;_2f7.getInherited=_2d5;_2f7.isInstanceOf=_2d8;_2f7.inherited=_2d7;_2f7.__inherited=_2cf;if(_2f4){_2f7.declaredClass=_2f4;lang.setObject(_2f4,ctor);}if(_2f9){for(name in _2f9){if(_2f7[name]&&typeof _2f9[name]=="string"&&name!=_2c6){t=_2f7[name]=_2f0(name,_2f8,_2f9[name]==="after");t.nom=name;}}}return ctor;};dojo.safeMixin=_2e4.safeMixin=_2de;dojo.declare=_2e4;return _2e4;});},"dojo/dom":function(){define(["./sniff","./_base/lang","./_base/window"],function(has,lang,win){if(has("ie")<=7){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}}var dom={};if(has("ie")){dom.byId=function(id,doc){if(typeof id!="string"){return id;}var _2fc=doc||win.doc,te=id&&_2fc.getElementById(id);if(te&&(te.attributes.id.value==id||te.id==id)){return te;}else{var eles=_2fc.all[id];if(!eles||eles.nodeName){eles=[eles];}var i=0;while((te=eles[i++])){if((te.attributes&&te.attributes.id&&te.attributes.id.value==id)||te.id==id){return te;}}}};}else{dom.byId=function(id,doc){return ((typeof id=="string")?(doc||win.doc).getElementById(id):id)||null;};}dom.isDescendant=function(node,_2fd){try{node=dom.byId(node);_2fd=dom.byId(_2fd);while(node){if(node==_2fd){return true;}node=node.parentNode;}}catch(e){}return false;};dom.setSelectable=function(node,_2fe){node=dom.byId(node);if(has("mozilla")){node.style.MozUserSelect=_2fe?"":"none";}else{if(has("khtml")||has("webkit")){node.style.KhtmlUserSelect=_2fe?"auto":"none";}else{if(has("ie")){var v=(node.unselectable=_2fe?"":"on"),cs=node.getElementsByTagName("*"),i=0,l=cs.length;for(;i<l;++i){cs.item(i).unselectable=v;}}}}};return dom;});},"dojo/_base/browser":function(){if(require.has){require.has.add("config-selectorEngine","acme");}define(["../ready","./kernel","./connect","./unload","./window","./event","./html","./NodeList","../query","./xhr","./fx"],function(dojo){return dojo;});},"dojo/selector/acme":function(){define(["../dom","../sniff","../_base/array","../_base/lang","../_base/window"],function(dom,has,_2ff,lang,win){var trim=lang.trim;var each=_2ff.forEach;var _300=function(){return win.doc;};var _301=(_300().compatMode)=="BackCompat";var _302=">~+";var _303=false;var _304=function(){return true;};var _305=function(_306){if(_302.indexOf(_306.slice(-1))>=0){_306+=" * ";}else{_306+=" ";}var ts=function(s,e){return trim(_306.slice(s,e));};var _307=[];var _308=-1,_309=-1,_30a=-1,_30b=-1,_30c=-1,inId=-1,_30d=-1,_30e,lc="",cc="",_30f;var x=0,ql=_306.length,_310=null,_311=null;var _312=function(){if(_30d>=0){var tv=(_30d==x)?null:ts(_30d,x);_310[(_302.indexOf(tv)<0)?"tag":"oper"]=tv;_30d=-1;}};var _313=function(){if(inId>=0){_310.id=ts(inId,x).replace(/\\/g,"");inId=-1;}};var _314=function(){if(_30c>=0){_310.classes.push(ts(_30c+1,x).replace(/\\/g,""));_30c=-1;}};var _315=function(){_313();_312();_314();};var _316=function(){_315();if(_30b>=0){_310.pseudos.push({name:ts(_30b+1,x)});}_310.loops=(_310.pseudos.length||_310.attrs.length||_310.classes.length);_310.oquery=_310.query=ts(_30f,x);_310.otag=_310.tag=(_310["oper"])?null:(_310.tag||"*");if(_310.tag){_310.tag=_310.tag.toUpperCase();}if(_307.length&&(_307[_307.length-1].oper)){_310.infixOper=_307.pop();_310.query=_310.infixOper.query+" "+_310.query;}_307.push(_310);_310=null;};for(;lc=cc,cc=_306.charAt(x),x<ql;x++){if(lc=="\\"){continue;}if(!_310){_30f=x;_310={query:null,pseudos:[],attrs:[],classes:[],tag:null,oper:null,id:null,getTag:function(){return _303?this.otag:this.tag;}};_30d=x;}if(_30e){if(cc==_30e){_30e=null;}continue;}else{if(cc=="'"||cc=="\""){_30e=cc;continue;}}if(_308>=0){if(cc=="]"){if(!_311.attr){_311.attr=ts(_308+1,x);}else{_311.matchFor=ts((_30a||_308+1),x);}var cmf=_311.matchFor;if(cmf){if((cmf.charAt(0)=="\"")||(cmf.charAt(0)=="'")){_311.matchFor=cmf.slice(1,-1);}}if(_311.matchFor){_311.matchFor=_311.matchFor.replace(/\\/g,"");}_310.attrs.push(_311);_311=null;_308=_30a=-1;}else{if(cc=="="){var _317=("|~^$*".indexOf(lc)>=0)?lc:"";_311.type=_317+cc;_311.attr=ts(_308+1,x-_317.length);_30a=x+1;}}}else{if(_309>=0){if(cc==")"){if(_30b>=0){_311.value=ts(_309+1,x);}_30b=_309=-1;}}else{if(cc=="#"){_315();inId=x+1;}else{if(cc=="."){_315();_30c=x;}else{if(cc==":"){_315();_30b=x;}else{if(cc=="["){_315();_308=x;_311={};}else{if(cc=="("){if(_30b>=0){_311={name:ts(_30b+1,x),value:null};_310.pseudos.push(_311);}_309=x;}else{if((cc==" ")&&(lc!=cc)){_316();}}}}}}}}}return _307;};var _318=function(_319,_31a){if(!_319){return _31a;}if(!_31a){return _319;}return function(){return _319.apply(window,arguments)&&_31a.apply(window,arguments);};};var _31b=function(i,arr){var r=arr||[];if(i){r.push(i);}return r;};var _31c=function(n){return (1==n.nodeType);};var _31d="";var _31e=function(elem,attr){if(!elem){return _31d;}if(attr=="class"){return elem.className||_31d;}if(attr=="for"){return elem.htmlFor||_31d;}if(attr=="style"){return elem.style.cssText||_31d;}return (_303?elem.getAttribute(attr):elem.getAttribute(attr,2))||_31d;};var _31f={"*=":function(attr,_320){return function(elem){return (_31e(elem,attr).indexOf(_320)>=0);};},"^=":function(attr,_321){return function(elem){return (_31e(elem,attr).indexOf(_321)==0);};},"$=":function(attr,_322){return function(elem){var ea=" "+_31e(elem,attr);var _323=ea.lastIndexOf(_322);return _323>-1&&(_323==(ea.length-_322.length));};},"~=":function(attr,_324){var tval=" "+_324+" ";return function(elem){var ea=" "+_31e(elem,attr)+" ";return (ea.indexOf(tval)>=0);};},"|=":function(attr,_325){var _326=_325+"-";return function(elem){var ea=_31e(elem,attr);return ((ea==_325)||(ea.indexOf(_326)==0));};},"=":function(attr,_327){return function(elem){return (_31e(elem,attr)==_327);};}};var _328=(typeof _300().firstChild.nextElementSibling=="undefined");var _329=!_328?"nextElementSibling":"nextSibling";var _32a=!_328?"previousElementSibling":"previousSibling";var _32b=(_328?_31c:_304);var _32c=function(node){while(node=node[_32a]){if(_32b(node)){return false;}}return true;};var _32d=function(node){while(node=node[_329]){if(_32b(node)){return false;}}return true;};var _32e=function(node){var root=node.parentNode;root=root.nodeType!=7?root:root.nextSibling;var i=0,tret=root.children||root.childNodes,ci=(node["_i"]||node.getAttribute("_i")||-1),cl=(root["_l"]||(typeof root.getAttribute!=="undefined"?root.getAttribute("_l"):-1));if(!tret){return -1;}var l=tret.length;if(cl==l&&ci>=0&&cl>=0){return ci;}if(has("ie")&&typeof root.setAttribute!=="undefined"){root.setAttribute("_l",l);}else{root["_l"]=l;}ci=-1;for(var te=root["firstElementChild"]||root["firstChild"];te;te=te[_329]){if(_32b(te)){if(has("ie")){te.setAttribute("_i",++i);}else{te["_i"]=++i;}if(node===te){ci=i;}}}return ci;};var _32f=function(elem){return !((_32e(elem))%2);};var _330=function(elem){return ((_32e(elem))%2);};var _331={"checked":function(name,_332){return function(elem){return !!("checked" in elem?elem.checked:elem.selected);};},"disabled":function(name,_333){return function(elem){return elem.disabled;};},"enabled":function(name,_334){return function(elem){return !elem.disabled;};},"first-child":function(){return _32c;},"last-child":function(){return _32d;},"only-child":function(name,_335){return function(node){return _32c(node)&&_32d(node);};},"empty":function(name,_336){return function(elem){var cn=elem.childNodes;var cnl=elem.childNodes.length;for(var x=cnl-1;x>=0;x--){var nt=cn[x].nodeType;if((nt===1)||(nt==3)){return false;}}return true;};},"contains":function(name,_337){var cz=_337.charAt(0);if(cz=="\""||cz=="'"){_337=_337.slice(1,-1);}return function(elem){return (elem.innerHTML.indexOf(_337)>=0);};},"not":function(name,_338){var p=_305(_338)[0];var _339={el:1};if(p.tag!="*"){_339.tag=1;}if(!p.classes.length){_339.classes=1;}var ntf=_33a(p,_339);return function(elem){return (!ntf(elem));};},"nth-child":function(name,_33b){var pi=parseInt;if(_33b=="odd"){return _330;}else{if(_33b=="even"){return _32f;}}if(_33b.indexOf("n")!=-1){var _33c=_33b.split("n",2);var pred=_33c[0]?((_33c[0]=="-")?-1:pi(_33c[0])):1;var idx=_33c[1]?pi(_33c[1]):0;var lb=0,ub=-1;if(pred>0){if(idx<0){idx=(idx%pred)&&(pred+(idx%pred));}else{if(idx>0){if(idx>=pred){lb=idx-idx%pred;}idx=idx%pred;}}}else{if(pred<0){pred*=-1;if(idx>0){ub=idx;idx=idx%pred;}}}if(pred>0){return function(elem){var i=_32e(elem);return (i>=lb)&&(ub<0||i<=ub)&&((i%pred)==idx);};}else{_33b=idx;}}var _33d=pi(_33b);return function(elem){return (_32e(elem)==_33d);};}};var _33e=(has("ie")&&(has("ie")<9||has("quirks")))?function(cond){var clc=cond.toLowerCase();if(clc=="class"){cond="className";}return function(elem){return (_303?elem.getAttribute(cond):elem[cond]||elem[clc]);};}:function(cond){return function(elem){return (elem&&elem.getAttribute&&elem.hasAttribute(cond));};};var _33a=function(_33f,_340){if(!_33f){return _304;}_340=_340||{};var ff=null;if(!("el" in _340)){ff=_318(ff,_31c);}if(!("tag" in _340)){if(_33f.tag!="*"){ff=_318(ff,function(elem){return (elem&&((_303?elem.tagName:elem.tagName.toUpperCase())==_33f.getTag()));});}}if(!("classes" in _340)){each(_33f.classes,function(_341,idx,arr){var re=new RegExp("(?:^|\\s)"+_341+"(?:\\s|$)");ff=_318(ff,function(elem){return re.test(elem.className);});ff.count=idx;});}if(!("pseudos" in _340)){each(_33f.pseudos,function(_342){var pn=_342.name;if(_331[pn]){ff=_318(ff,_331[pn](pn,_342.value));}});}if(!("attrs" in _340)){each(_33f.attrs,function(attr){var _343;var a=attr.attr;if(attr.type&&_31f[attr.type]){_343=_31f[attr.type](a,attr.matchFor);}else{if(a.length){_343=_33e(a);}}if(_343){ff=_318(ff,_343);}});}if(!("id" in _340)){if(_33f.id){ff=_318(ff,function(elem){return (!!elem&&(elem.id==_33f.id));});}}if(!ff){if(!("default" in _340)){ff=_304;}}return ff;};var _344=function(_345){return function(node,ret,bag){while(node=node[_329]){if(_328&&(!_31c(node))){continue;}if((!bag||_346(node,bag))&&_345(node)){ret.push(node);}break;}return ret;};};var _347=function(_348){return function(root,ret,bag){var te=root[_329];while(te){if(_32b(te)){if(bag&&!_346(te,bag)){break;}if(_348(te)){ret.push(te);}}te=te[_329];}return ret;};};var _349=function(_34a){_34a=_34a||_304;return function(root,ret,bag){var te,x=0,tret=root.children||root.childNodes;while(te=tret[x++]){if(_32b(te)&&(!bag||_346(te,bag))&&(_34a(te,x))){ret.push(te);}}return ret;};};var _34b=function(node,root){var pn=node.parentNode;while(pn){if(pn==root){break;}pn=pn.parentNode;}return !!pn;};var _34c={};var _34d=function(_34e){var _34f=_34c[_34e.query];if(_34f){return _34f;}var io=_34e.infixOper;var oper=(io?io.oper:"");var _350=_33a(_34e,{el:1});var qt=_34e.tag;var _351=("*"==qt);var ecs=_300()["getElementsByClassName"];if(!oper){if(_34e.id){_350=(!_34e.loops&&_351)?_304:_33a(_34e,{el:1,id:1});_34f=function(root,arr){var te=dom.byId(_34e.id,(root.ownerDocument||root));if(!te||!_350(te)){return;}if(9==root.nodeType){return _31b(te,arr);}else{if(_34b(te,root)){return _31b(te,arr);}}};}else{if(ecs&&/\{\s*\[native code\]\s*\}/.test(String(ecs))&&_34e.classes.length&&!_301){_350=_33a(_34e,{el:1,classes:1,id:1});var _352=_34e.classes.join(" ");_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tret=root.getElementsByClassName(_352);while((te=tret[x++])){if(_350(te,root)&&_346(te,bag)){ret.push(te);}}return ret;};}else{if(!_351&&!_34e.loops){_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tag=_34e.getTag(),tret=tag?root.getElementsByTagName(tag):[];while((te=tret[x++])){if(_346(te,bag)){ret.push(te);}}return ret;};}else{_350=_33a(_34e,{el:1,tag:1,id:1});_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tag=_34e.getTag(),tret=tag?root.getElementsByTagName(tag):[];while((te=tret[x++])){if(_350(te,root)&&_346(te,bag)){ret.push(te);}}return ret;};}}}}else{var _353={el:1};if(_351){_353.tag=1;}_350=_33a(_34e,_353);if("+"==oper){_34f=_344(_350);}else{if("~"==oper){_34f=_347(_350);}else{if(">"==oper){_34f=_349(_350);}}}}return _34c[_34e.query]=_34f;};var _354=function(root,_355){var _356=_31b(root),qp,x,te,qpl=_355.length,bag,ret;for(var i=0;i<qpl;i++){ret=[];qp=_355[i];x=_356.length-1;if(x>0){bag={};ret.nozip=true;}var gef=_34d(qp);for(var j=0;(te=_356[j]);j++){gef(te,ret,bag);}if(!ret.length){break;}_356=ret;}return ret;};var _357={},_358={};var _359=function(_35a){var _35b=_305(trim(_35a));if(_35b.length==1){var tef=_34d(_35b[0]);return function(root){var r=tef(root,[]);if(r){r.nozip=true;}return r;};}return function(root){return _354(root,_35b);};};var _35c=has("ie")?"commentStrip":"nozip";var qsa="querySelectorAll";var _35d=!!_300()[qsa];var _35e=/\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g;var _35f=function(_360,pre,ch,post){return ch?(pre?pre+" ":"")+ch+(post?" "+post:""):_360;};var _361=/([^[]*)([^\]]*])?/g;var _362=function(_363,_364,att){return _364.replace(_35e,_35f)+(att||"");};var _365=function(_366,_367){_366=_366.replace(_361,_362);if(_35d){var _368=_358[_366];if(_368&&!_367){return _368;}}var _369=_357[_366];if(_369){return _369;}var qcz=_366.charAt(0);var _36a=(-1==_366.indexOf(" "));if((_366.indexOf("#")>=0)&&(_36a)){_367=true;}var _36b=(_35d&&(!_367)&&(_302.indexOf(qcz)==-1)&&(!has("ie")||(_366.indexOf(":")==-1))&&(!(_301&&(_366.indexOf(".")>=0)))&&(_366.indexOf(":contains")==-1)&&(_366.indexOf(":checked")==-1)&&(_366.indexOf("|=")==-1));if(_36b){var tq=(_302.indexOf(_366.charAt(_366.length-1))>=0)?(_366+" *"):_366;return _358[_366]=function(root){try{if(!((9==root.nodeType)||_36a)){throw "";}var r=root[qsa](tq);r[_35c]=true;return r;}catch(e){return _365(_366,true)(root);}};}else{var _36c=_366.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g);return _357[_366]=((_36c.length<2)?_359(_366):function(root){var _36d=0,ret=[],tp;while((tp=_36c[_36d++])){ret=ret.concat(_359(tp)(root));}return ret;});}};var _36e=0;var _36f=has("ie")?function(node){if(_303){return (node.getAttribute("_uid")||node.setAttribute("_uid",++_36e)||_36e);}else{return node.uniqueID;}}:function(node){return (node._uid||(node._uid=++_36e));};var _346=function(node,bag){if(!bag){return 1;}var id=_36f(node);if(!bag[id]){return bag[id]=1;}return 0;};var _370="_zipIdx";var _371=function(arr){if(arr&&arr.nozip){return arr;}var ret=[];if(!arr||!arr.length){return ret;}if(arr[0]){ret.push(arr[0]);}if(arr.length<2){return ret;}_36e++;var x,te;if(has("ie")&&_303){var _372=_36e+"";arr[0].setAttribute(_370,_372);for(x=1;te=arr[x];x++){if(arr[x].getAttribute(_370)!=_372){ret.push(te);}te.setAttribute(_370,_372);}}else{if(has("ie")&&arr.commentStrip){try{for(x=1;te=arr[x];x++){if(_31c(te)){ret.push(te);}}}catch(e){}}else{if(arr[0]){arr[0][_370]=_36e;}for(x=1;te=arr[x];x++){if(arr[x][_370]!=_36e){ret.push(te);}te[_370]=_36e;}}}return ret;};var _373=function(_374,root){root=root||_300();var od=root.ownerDocument||root;_303=(od.createElement("div").tagName==="div");var r=_365(_374)(root);if(r&&r.nozip){return r;}return _371(r);};_373.filter=function(_375,_376,root){var _377=[],_378=_305(_376),_379=(_378.length==1&&!/[^\w#\.]/.test(_376))?_33a(_378[0]):function(node){return _2ff.indexOf(_373(_376,dom.byId(root)),node)!=-1;};for(var x=0,te;te=_375[x];x++){if(_379(te)){_377.push(te);}}return _377;};return _373;});},"dojo/errors/RequestTimeoutError":function(){define("dojo/errors/RequestTimeoutError",["./create","./RequestError"],function(_37a,_37b){return _37a("RequestTimeoutError",null,_37b,{dojoType:"timeout"});});},"dojo/dom-geometry":function(){define(["./sniff","./_base/window","./dom","./dom-style"],function(has,win,dom,_37c){var geom={};geom.boxModel="content-box";if(has("ie")){geom.boxModel=document.compatMode=="BackCompat"?"border-box":"content-box";}geom.getPadExtents=function getPadExtents(node,_37d){node=dom.byId(node);var s=_37d||_37c.getComputedStyle(node),px=_37c.toPixelValue,l=px(node,s.paddingLeft),t=px(node,s.paddingTop),r=px(node,s.paddingRight),b=px(node,s.paddingBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};var none="none";geom.getBorderExtents=function getBorderExtents(node,_37e){node=dom.byId(node);var px=_37c.toPixelValue,s=_37e||_37c.getComputedStyle(node),l=s.borderLeftStyle!=none?px(node,s.borderLeftWidth):0,t=s.borderTopStyle!=none?px(node,s.borderTopWidth):0,r=s.borderRightStyle!=none?px(node,s.borderRightWidth):0,b=s.borderBottomStyle!=none?px(node,s.borderBottomWidth):0;return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getPadBorderExtents=function getPadBorderExtents(node,_37f){node=dom.byId(node);var s=_37f||_37c.getComputedStyle(node),p=geom.getPadExtents(node,s),b=geom.getBorderExtents(node,s);return {l:p.l+b.l,t:p.t+b.t,r:p.r+b.r,b:p.b+b.b,w:p.w+b.w,h:p.h+b.h};};geom.getMarginExtents=function getMarginExtents(node,_380){node=dom.byId(node);var s=_380||_37c.getComputedStyle(node),px=_37c.toPixelValue,l=px(node,s.marginLeft),t=px(node,s.marginTop),r=px(node,s.marginRight),b=px(node,s.marginBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getMarginBox=function getMarginBox(node,_381){node=dom.byId(node);var s=_381||_37c.getComputedStyle(node),me=geom.getMarginExtents(node,s),l=node.offsetLeft-me.l,t=node.offsetTop-me.t,p=node.parentNode,px=_37c.toPixelValue,pcs;if(has("mozilla")){var sl=parseFloat(s.left),st=parseFloat(s.top);if(!isNaN(sl)&&!isNaN(st)){l=sl;t=st;}else{if(p&&p.style){pcs=_37c.getComputedStyle(p);if(pcs.overflow!="visible"){l+=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t+=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}}else{if(has("opera")||(has("ie")==8&&!has("quirks"))){if(p){pcs=_37c.getComputedStyle(p);l-=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t-=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}return {l:l,t:t,w:node.offsetWidth+me.w,h:node.offsetHeight+me.h};};geom.getContentBox=function getContentBox(node,_382){node=dom.byId(node);var s=_382||_37c.getComputedStyle(node),w=node.clientWidth,h,pe=geom.getPadExtents(node,s),be=geom.getBorderExtents(node,s);if(!w){w=node.offsetWidth;h=node.offsetHeight;}else{h=node.clientHeight;be.w=be.h=0;}if(has("opera")){pe.l+=be.l;pe.t+=be.t;}return {l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h};};function _383(node,l,t,w,h,u){u=u||"px";var s=node.style;if(!isNaN(l)){s.left=l+u;}if(!isNaN(t)){s.top=t+u;}if(w>=0){s.width=w+u;}if(h>=0){s.height=h+u;}};function _384(node){return node.tagName.toLowerCase()=="button"||node.tagName.toLowerCase()=="input"&&(node.getAttribute("type")||"").toLowerCase()=="button";};function _385(node){return geom.boxModel=="border-box"||node.tagName.toLowerCase()=="table"||_384(node);};geom.setContentSize=function setContentSize(node,box,_386){node=dom.byId(node);var w=box.w,h=box.h;if(_385(node)){var pb=geom.getPadBorderExtents(node,_386);if(w>=0){w+=pb.w;}if(h>=0){h+=pb.h;}}_383(node,NaN,NaN,w,h);};var _387={l:0,t:0,w:0,h:0};geom.setMarginBox=function setMarginBox(node,box,_388){node=dom.byId(node);var s=_388||_37c.getComputedStyle(node),w=box.w,h=box.h,pb=_385(node)?_387:geom.getPadBorderExtents(node,s),mb=geom.getMarginExtents(node,s);if(has("webkit")){if(_384(node)){var ns=node.style;if(w>=0&&!ns.width){ns.width="4px";}if(h>=0&&!ns.height){ns.height="4px";}}}if(w>=0){w=Math.max(w-pb.w-mb.w,0);}if(h>=0){h=Math.max(h-pb.h-mb.h,0);}_383(node,box.l,box.t,w,h);};geom.isBodyLtr=function isBodyLtr(doc){doc=doc||win.doc;return (win.body(doc).dir||doc.documentElement.dir||"ltr").toLowerCase()=="ltr";};geom.docScroll=function docScroll(doc){doc=doc||win.doc;var node=win.doc.parentWindow||win.doc.defaultView;return "pageXOffset" in node?{x:node.pageXOffset,y:node.pageYOffset}:(node=has("quirks")?win.body(doc):doc.documentElement)&&{x:geom.fixIeBiDiScrollLeft(node.scrollLeft||0,doc),y:node.scrollTop||0};};if(has("ie")){geom.getIeDocumentElementOffset=function getIeDocumentElementOffset(doc){doc=doc||win.doc;var de=doc.documentElement;if(has("ie")<8){var r=de.getBoundingClientRect(),l=r.left,t=r.top;if(has("ie")<7){l+=de.clientLeft;t+=de.clientTop;}return {x:l<0?0:l,y:t<0?0:t};}else{return {x:0,y:0};}};}geom.fixIeBiDiScrollLeft=function fixIeBiDiScrollLeft(_389,doc){doc=doc||win.doc;var ie=has("ie");if(ie&&!geom.isBodyLtr(doc)){var qk=has("quirks"),de=qk?win.body(doc):doc.documentElement,pwin=win.global;if(ie==6&&!qk&&pwin.frameElement&&de.scrollHeight>de.clientHeight){_389+=de.clientLeft;}return (ie<8||qk)?(_389+de.clientWidth-de.scrollWidth):-_389;}return _389;};geom.position=function(node,_38a){node=dom.byId(node);var db=win.body(node.ownerDocument),ret=node.getBoundingClientRect();ret={x:ret.left,y:ret.top,w:ret.right-ret.left,h:ret.bottom-ret.top};if(has("ie")){var _38b=geom.getIeDocumentElementOffset(node.ownerDocument);ret.x-=_38b.x+(has("quirks")?db.clientLeft+db.offsetLeft:0);ret.y-=_38b.y+(has("quirks")?db.clientTop+db.offsetTop:0);}if(_38a){var _38c=geom.docScroll(node.ownerDocument);ret.x+=_38c.x;ret.y+=_38c.y;}return ret;};geom.getMarginSize=function getMarginSize(node,_38d){node=dom.byId(node);var me=geom.getMarginExtents(node,_38d||_37c.getComputedStyle(node));var size=node.getBoundingClientRect();return {w:(size.right-size.left)+me.w,h:(size.bottom-size.top)+me.h};};geom.normalizeEvent=function(_38e){if(!("layerX" in _38e)){_38e.layerX=_38e.offsetX;_38e.layerY=_38e.offsetY;}if(!has("dom-addeventlistener")){var se=_38e.target;var doc=(se&&se.ownerDocument)||document;var _38f=has("quirks")?doc.body:doc.documentElement;var _390=geom.getIeDocumentElementOffset(doc);_38e.pageX=_38e.clientX+geom.fixIeBiDiScrollLeft(_38f.scrollLeft||0,doc)-_390.x;_38e.pageY=_38e.clientY+(_38f.scrollTop||0)-_390.y;}};return geom;});},"dojo/dom-style":function(){define("dojo/dom-style",["./sniff","./dom"],function(has,dom){var _391,_392={};if(has("webkit")){_391=function(node){var s;if(node.nodeType==1){var dv=node.ownerDocument.defaultView;s=dv.getComputedStyle(node,null);if(!s&&node.style){node.style.display="";s=dv.getComputedStyle(node,null);}}return s||{};};}else{if(has("ie")&&(has("ie")<9||has("quirks"))){_391=function(node){return node.nodeType==1&&node.currentStyle?node.currentStyle:{};};}else{_391=function(node){return node.nodeType==1?node.ownerDocument.defaultView.getComputedStyle(node,null):{};};}}_392.getComputedStyle=_391;var _393;if(!has("ie")){_393=function(_394,_395){return parseFloat(_395)||0;};}else{_393=function(_396,_397){if(!_397){return 0;}if(_397=="medium"){return 4;}if(_397.slice&&_397.slice(-2)=="px"){return parseFloat(_397);}var s=_396.style,rs=_396.runtimeStyle,cs=_396.currentStyle,_398=s.left,_399=rs.left;rs.left=cs.left;try{s.left=_397;_397=s.pixelLeft;}catch(e){_397=0;}s.left=_398;rs.left=_399;return _397;};}_392.toPixelValue=_393;var astr="DXImageTransform.Microsoft.Alpha";var af=function(n,f){try{return n.filters.item(astr);}catch(e){return f?{}:null;}};var _39a=has("ie")<9||(has("ie")&&has("quirks"))?function(node){try{return af(node).Opacity/100;}catch(e){return 1;}}:function(node){return _391(node).opacity;};var _39b=has("ie")<9||(has("ie")&&has("quirks"))?function(node,_39c){var ov=_39c*100,_39d=_39c==1;node.style.zoom=_39d?"":1;if(!af(node)){if(_39d){return _39c;}node.style.filter+=" progid:"+astr+"(Opacity="+ov+")";}else{af(node,1).Opacity=ov;}af(node,1).Enabled=!_39d;if(node.tagName.toLowerCase()=="tr"){for(var td=node.firstChild;td;td=td.nextSibling){if(td.tagName.toLowerCase()=="td"){_39b(td,_39c);}}}return _39c;}:function(node,_39e){return node.style.opacity=_39e;};var _39f={left:true,top:true};var _3a0=/margin|padding|width|height|max|min|offset/;function _3a1(node,type,_3a2){type=type.toLowerCase();if(has("ie")){if(_3a2=="auto"){if(type=="height"){return node.offsetHeight;}if(type=="width"){return node.offsetWidth;}}if(type=="fontweight"){switch(_3a2){case 700:return "bold";case 400:default:return "normal";}}}if(!(type in _39f)){_39f[type]=_3a0.test(type);}return _39f[type]?_393(node,_3a2):_3a2;};var _3a3=has("ie")?"styleFloat":"cssFloat",_3a4={"cssFloat":_3a3,"styleFloat":_3a3,"float":_3a3};_392.get=function getStyle(node,name){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");if(l==2&&op){return _39a(n);}name=_3a4[name]||name;var s=_392.getComputedStyle(n);return (l==1)?s:_3a1(n,name,s[name]||n.style[name]);};_392.set=function setStyle(node,name,_3a5){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");name=_3a4[name]||name;if(l==3){return op?_39b(n,_3a5):n.style[name]=_3a5;}for(var x in name){_392.set(node,x,name[x]);}return _392.getComputedStyle(n);};return _392;});},"dojo/dom-prop":function(){define(["exports","./_base/kernel","./sniff","./_base/lang","./dom","./dom-style","./dom-construct","./_base/connect"],function(_3a6,dojo,has,lang,dom,_3a7,ctr,conn){var _3a8={},_3a9=0,_3aa=dojo._scopeName+"attrid";_3a6.names={"class":"className","for":"htmlFor",tabindex:"tabIndex",readonly:"readOnly",colspan:"colSpan",frameborder:"frameBorder",rowspan:"rowSpan",valuetype:"valueType"};_3a6.get=function getProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3ab=_3a6.names[lc]||name;return node[_3ab];};_3a6.set=function setProp(node,name,_3ac){node=dom.byId(node);var l=arguments.length;if(l==2&&typeof name!="string"){for(var x in name){_3a6.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_3ad=_3a6.names[lc]||name;if(_3ad=="style"&&typeof _3ac!="string"){_3a7.set(node,_3ac);return node;}if(_3ad=="innerHTML"){if(has("ie")&&node.tagName.toLowerCase() in {col:1,colgroup:1,table:1,tbody:1,tfoot:1,thead:1,tr:1,title:1}){ctr.empty(node);node.appendChild(ctr.toDom(_3ac,node.ownerDocument));}else{node[_3ad]=_3ac;}return node;}if(lang.isFunction(_3ac)){var _3ae=node[_3aa];if(!_3ae){_3ae=_3a9++;node[_3aa]=_3ae;}if(!_3a8[_3ae]){_3a8[_3ae]={};}var h=_3a8[_3ae][_3ad];if(h){conn.disconnect(h);}else{try{delete node[_3ad];}catch(e){}}if(_3ac){_3a8[_3ae][_3ad]=conn.connect(node,_3ad,_3ac);}else{node[_3ad]=null;}return node;}node[_3ad]=_3ac;return node;};});},"dojo/when":function(){define(["./Deferred","./promise/Promise"],function(_3af,_3b0){"use strict";return function when(_3b1,_3b2,_3b3,_3b4){var _3b5=_3b1&&typeof _3b1.then==="function";var _3b6=_3b5&&_3b1 instanceof _3b0;if(!_3b5){if(_3b2){return _3b2(_3b1);}else{return new _3af().resolve(_3b1);}}else{if(!_3b6){var _3b7=new _3af(_3b1.cancel);_3b1.then(_3b7.resolve,_3b7.reject,_3b7.progress);_3b1=_3b7.promise;}}if(_3b2||_3b3||_3b4){return _3b1.then(_3b2,_3b3,_3b4);}return _3b1;};});},"dojo/dom-attr":function(){define(["exports","./sniff","./_base/lang","./dom","./dom-style","./dom-prop"],function(_3b8,has,lang,dom,_3b9,prop){var _3ba={innerHTML:1,className:1,htmlFor:has("ie"),value:1},_3bb={classname:"class",htmlfor:"for",tabindex:"tabIndex",readonly:"readOnly"};function _3bc(node,name){var attr=node.getAttributeNode&&node.getAttributeNode(name);return attr&&attr.specified;};_3b8.has=function hasAttr(node,name){var lc=name.toLowerCase();return _3ba[prop.names[lc]||name]||_3bc(dom.byId(node),_3bb[lc]||name);};_3b8.get=function getAttr(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3bd=prop.names[lc]||name,_3be=_3ba[_3bd],_3bf=node[_3bd];if(_3be&&typeof _3bf!="undefined"){return _3bf;}if(_3bd!="href"&&(typeof _3bf=="boolean"||lang.isFunction(_3bf))){return _3bf;}var _3c0=_3bb[lc]||name;return _3bc(node,_3c0)?node.getAttribute(_3c0):null;};_3b8.set=function setAttr(node,name,_3c1){node=dom.byId(node);if(arguments.length==2){for(var x in name){_3b8.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_3c2=prop.names[lc]||name,_3c3=_3ba[_3c2];if(_3c2=="style"&&typeof _3c1!="string"){_3b9.set(node,_3c1);return node;}if(_3c3||typeof _3c1=="boolean"||lang.isFunction(_3c1)){return prop.set(node,name,_3c1);}node.setAttribute(_3bb[lc]||name,_3c1);return node;};_3b8.remove=function removeAttr(node,name){dom.byId(node).removeAttribute(_3bb[name.toLowerCase()]||name);};_3b8.getNodeProp=function getNodeProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3c4=prop.names[lc]||name;if((_3c4 in node)&&_3c4!="href"){return node[_3c4];}var _3c5=_3bb[lc]||name;return _3bc(node,_3c5)?node.getAttribute(_3c5):null;};});},"dojo/dom-construct":function(){define(["exports","./_base/kernel","./sniff","./_base/window","./dom","./dom-attr","./on"],function(_3c6,dojo,has,win,dom,attr,on){var _3c7={option:["select"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","thead","tr"],legend:["fieldset"],caption:["table"],colgroup:["table"],col:["table","colgroup"],li:["ul"]},_3c8=/<\s*([\w\:]+)/,_3c9={},_3ca=0,_3cb="__"+dojo._scopeName+"ToDomId";for(var _3cc in _3c7){if(_3c7.hasOwnProperty(_3cc)){var tw=_3c7[_3cc];tw.pre=_3cc=="option"?"<select multiple=\"multiple\">":"<"+tw.join("><")+">";tw.post="</"+tw.reverse().join("></")+">";}}function _3cd(node,ref){var _3ce=ref.parentNode;if(_3ce){_3ce.insertBefore(node,ref);}};function _3cf(node,ref){var _3d0=ref.parentNode;if(_3d0){if(_3d0.lastChild==ref){_3d0.appendChild(node);}else{_3d0.insertBefore(node,ref.nextSibling);}}};var _3d1=null,_3d2;on(window,"unload",function(){_3d1=null;});_3c6.toDom=function toDom(frag,doc){doc=doc||win.doc;var _3d3=doc[_3cb];if(!_3d3){doc[_3cb]=_3d3=++_3ca+"";_3c9[_3d3]=doc.createElement("div");}frag+="";var _3d4=frag.match(_3c8),tag=_3d4?_3d4[1].toLowerCase():"",_3d5=_3c9[_3d3],wrap,i,fc,df;if(_3d4&&_3c7[tag]){wrap=_3c7[tag];_3d5.innerHTML=wrap.pre+frag+wrap.post;for(i=wrap.length;i;--i){_3d5=_3d5.firstChild;}}else{_3d5.innerHTML=frag;}if(_3d5.childNodes.length==1){return _3d5.removeChild(_3d5.firstChild);}df=doc.createDocumentFragment();while(fc=_3d5.firstChild){df.appendChild(fc);}return df;};_3c6.place=function place(node,_3d6,_3d7){_3d6=dom.byId(_3d6);if(typeof node=="string"){node=/^\s*</.test(node)?_3c6.toDom(node,_3d6.ownerDocument):dom.byId(node);}if(typeof _3d7=="number"){var cn=_3d6.childNodes;if(!cn.length||cn.length<=_3d7){_3d6.appendChild(node);}else{_3cd(node,cn[_3d7<0?0:_3d7]);}}else{switch(_3d7){case "before":_3cd(node,_3d6);break;case "after":_3cf(node,_3d6);break;case "replace":_3d6.parentNode.replaceChild(node,_3d6);break;case "only":_3c6.empty(_3d6);_3d6.appendChild(node);break;case "first":if(_3d6.firstChild){_3cd(node,_3d6.firstChild);break;}default:_3d6.appendChild(node);}}return node;};_3c6.create=function create(tag,_3d8,_3d9,pos){var doc=win.doc;if(_3d9){_3d9=dom.byId(_3d9);doc=_3d9.ownerDocument;}if(typeof tag=="string"){tag=doc.createElement(tag);}if(_3d8){attr.set(tag,_3d8);}if(_3d9){_3c6.place(tag,_3d9,pos);}return tag;};_3c6.empty=has("ie")?function(node){node=dom.byId(node);for(var c;c=node.lastChild;){_3c6.destroy(c);}}:function(node){dom.byId(node).innerHTML="";};_3c6.destroy=function destroy(node){node=dom.byId(node);try{var doc=node.ownerDocument;if(!_3d1||_3d2!=doc){_3d1=doc.createElement("div");_3d2=doc;}_3d1.appendChild(node.parentNode?node.parentNode.removeChild(node):node);_3d1.innerHTML="";}catch(e){}};});},"dojo/request/xhr":function(){define("dojo/request/xhr",["../errors/RequestError","./watch","./handlers","./util","../has"],function(_3da,_3db,_3dc,util,has){has.add("native-xhr",function(){return typeof XMLHttpRequest!=="undefined";});has.add("dojo-force-activex-xhr",function(){return has("activex")&&!document.addEventListener&&window.location.protocol==="file:";});has.add("native-xhr2",function(){if(!has("native-xhr")){return;}var x=new XMLHttpRequest();return typeof x["addEventListener"]!=="undefined"&&(typeof opera==="undefined"||typeof x["upload"]!=="undefined");});has.add("native-formdata",function(){return typeof FormData==="function";});function _3dd(_3de,_3df){var _3e0=_3de.xhr;_3de.status=_3de.xhr.status;_3de.text=_3e0.responseText;if(_3de.options.handleAs==="xml"){_3de.data=_3e0.responseXML;}if(!_3df){try{_3dc(_3de);}catch(e){_3df=e;}}if(_3df){this.reject(_3df);}else{if(util.checkStatus(_3e0.status)){this.resolve(_3de);}else{_3df=new _3da("Unable to load "+_3de.url+" status: "+_3e0.status,_3de);this.reject(_3df);}}};var _3e1,_3e2,_3e3,_3e4;if(has("native-xhr2")){_3e1=function(_3e5){return !this.isFulfilled();};_3e4=function(dfd,_3e6){_3e6.xhr.abort();};_3e3=function(_3e7,dfd,_3e8){function _3e9(evt){dfd.handleResponse(_3e8);};function _3ea(evt){var _3eb=evt.target;var _3ec=new _3da("Unable to load "+_3e8.url+" status: "+_3eb.status,_3e8);dfd.handleResponse(_3e8,_3ec);};function _3ed(evt){if(evt.lengthComputable){_3e8.loaded=evt.loaded;_3e8.total=evt.total;dfd.progress(_3e8);}};_3e7.addEventListener("load",_3e9,false);_3e7.addEventListener("error",_3ea,false);_3e7.addEventListener("progress",_3ed,false);return function(){_3e7.removeEventListener("load",_3e9,false);_3e7.removeEventListener("error",_3ea,false);_3e7.removeEventListener("progress",_3ed,false);};};}else{_3e1=function(_3ee){return _3ee.xhr.readyState;};_3e2=function(_3ef){return 4===_3ef.xhr.readyState;};_3e4=function(dfd,_3f0){var xhr=_3f0.xhr;var _3f1=typeof xhr.abort;if(_3f1==="function"||_3f1==="object"||_3f1==="unknown"){xhr.abort();}};}var _3f2,_3f3={data:null,query:null,sync:false,method:"GET",headers:{"Content-Type":"application/x-www-form-urlencoded"}};function xhr(url,_3f4,_3f5){var _3f6=util.parseArgs(url,util.deepCreate(_3f3,_3f4),has("native-formdata")&&_3f4&&_3f4.data&&_3f4.data instanceof FormData);url=_3f6.url;_3f4=_3f6.options;var _3f7,last=function(){_3f7&&_3f7();};var dfd=util.deferred(_3f6,_3e4,_3e1,_3e2,_3dd,last);var _3f8=_3f6.xhr=xhr._create();if(!_3f8){dfd.cancel(new _3da("XHR was not created"));return _3f5?dfd:dfd.promise;}_3f6.getHeader=function(_3f9){return this.xhr.getResponseHeader(_3f9);};if(_3e3){_3f7=_3e3(_3f8,dfd,_3f6);}var data=_3f4.data,_3fa=!_3f4.sync,_3fb=_3f4.method;try{_3f8.open(_3fb,url,_3fa,_3f4.user||_3f2,_3f4.password||_3f2);if(_3f4.withCredentials){_3f8.withCredentials=_3f4.withCredentials;}var _3fc=_3f4.headers,_3fd;if(_3fc){for(var hdr in _3fc){if(hdr.toLowerCase()==="content-type"){_3fd=_3fc[hdr];}else{if(_3fc[hdr]){_3f8.setRequestHeader(hdr,_3fc[hdr]);}}}}if(_3fd&&_3fd!==false){_3f8.setRequestHeader("Content-Type",_3fd);}if(!_3fc||!("X-Requested-With" in _3fc)){_3f8.setRequestHeader("X-Requested-With","XMLHttpRequest");}if(util.notify){util.notify.emit("send",_3f6,dfd.promise.cancel);}_3f8.send(data);}catch(e){dfd.reject(e);}_3db(dfd);_3f8=null;return _3f5?dfd:dfd.promise;};xhr._create=function(){throw new Error("XMLHTTP not available");};if(has("native-xhr")&&!has("dojo-force-activex-xhr")){xhr._create=function(){return new XMLHttpRequest();};}else{if(has("activex")){try{new ActiveXObject("Msxml2.XMLHTTP");xhr._create=function(){return new ActiveXObject("Msxml2.XMLHTTP");};}catch(e){try{new ActiveXObject("Microsoft.XMLHTTP");xhr._create=function(){return new ActiveXObject("Microsoft.XMLHTTP");};}catch(e){}}}}util.addCommonMethods(xhr);return xhr;});},"dojo/text":function(){define(["./_base/kernel","require","./has","./_base/xhr"],function(dojo,_3fe,has,xhr){var _3ff;if(1){_3ff=function(url,sync,load){xhr("GET",{url:url,sync:!!sync,load:load,headers:dojo.config.textPluginHeaders||{}});};}else{if(_3fe.getText){_3ff=_3fe.getText;}else{console.error("dojo/text plugin failed to load because loader does not support getText");}}var _400={},_401=function(text){if(text){text=text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");var _402=text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(_402){text=_402[1];}}else{text="";}return text;},_403={},_404={};dojo.cache=function(_405,url,_406){var key;if(typeof _405=="string"){if(/\//.test(_405)){key=_405;_406=url;}else{key=_3fe.toUrl(_405.replace(/\./g,"/")+(url?("/"+url):""));}}else{key=_405+"";_406=url;}var val=(_406!=undefined&&typeof _406!="string")?_406.value:_406,_407=_406&&_406.sanitize;if(typeof val=="string"){_400[key]=val;return _407?_401(val):val;}else{if(val===null){delete _400[key];return null;}else{if(!(key in _400)){_3ff(key,true,function(text){_400[key]=text;});}return _407?_401(_400[key]):_400[key];}}};return {dynamic:true,normalize:function(id,_408){var _409=id.split("!"),url=_409[0];return (/^\./.test(url)?_408(url):url)+(_409[1]?"!"+_409[1]:"");},load:function(id,_40a,load){var _40b=id.split("!"),_40c=_40b.length>1,_40d=_40b[0],url=_40a.toUrl(_40b[0]),_40e="url:"+url,text=_403,_40f=function(text){load(_40c?_401(text):text);};if(_40d in _400){text=_400[_40d];}else{if(_40e in _40a.cache){text=_40a.cache[_40e];}else{if(url in _400){text=_400[url];}}}if(text===_403){if(_404[url]){_404[url].push(_40f);}else{var _410=_404[url]=[_40f];_3ff(url,!_40a.async,function(text){_400[_40d]=_400[url]=text;for(var i=0;i<_410.length;){_410[i++](text);}delete _404[url];});}}else{_40f(text);}}};});},"dojo/keys":function(){define("dojo/keys",["./_base/kernel","./sniff"],function(dojo,has){return dojo.keys={BACKSPACE:8,TAB:9,CLEAR:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,META:has("webkit")?91:224,PAUSE:19,CAPS_LOCK:20,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,INSERT:45,DELETE:46,HELP:47,LEFT_WINDOW:91,RIGHT_WINDOW:92,SELECT:93,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,NUMPAD_MULTIPLY:106,NUMPAD_PLUS:107,NUMPAD_ENTER:108,NUMPAD_MINUS:109,NUMPAD_PERIOD:110,NUMPAD_DIVIDE:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,NUM_LOCK:144,SCROLL_LOCK:145,UP_DPAD:175,DOWN_DPAD:176,LEFT_DPAD:177,RIGHT_DPAD:178,copyKey:has("mac")&&!has("air")?(has("safari")?91:224):17};});},"dojo/domReady":function(){define(["./has"],function(has){var _411=this,doc=document,_412={"loaded":1,"complete":1},_413=typeof doc.readyState!="string",_414=!!_412[doc.readyState];if(_413){doc.readyState="loading";}if(!_414){var _415=[],_416=[],_417=function(evt){evt=evt||_411.event;if(_414||(evt.type=="readystatechange"&&!_412[doc.readyState])){return;}_414=1;if(_413){doc.readyState="complete";}while(_415.length){(_415.shift())(doc);}},on=function(node,_418){node.addEventListener(_418,_417,false);_415.push(function(){node.removeEventListener(_418,_417,false);});};if(!has("dom-addeventlistener")){on=function(node,_419){_419="on"+_419;node.attachEvent(_419,_417);_415.push(function(){node.detachEvent(_419,_417);});};var div=doc.createElement("div");try{if(div.doScroll&&_411.frameElement===null){_416.push(function(){try{div.doScroll("left");return 1;}catch(e){}});}}catch(e){}}on(doc,"DOMContentLoaded");on(_411,"load");if("onreadystatechange" in doc){on(doc,"readystatechange");}else{if(!_413){_416.push(function(){return _412[doc.readyState];});}}if(_416.length){var _41a=function(){if(_414){return;}var i=_416.length;while(i--){if(_416[i]()){_417("poller");return;}}setTimeout(_41a,30);};_41a();}}function _41b(_41c){if(_414){_41c(doc);}else{_415.push(_41c);}};_41b.load=function(id,req,load){_41b(load);};return _41b;});},"dojo/_base/lang":function(){define("dojo/_base/lang",["./kernel","../has","../sniff"],function(dojo,has){has.add("bug-for-in-skips-shadowed",function(){for(var i in {toString:1}){return 0;}return 1;});var _41d=has("bug-for-in-skips-shadowed")?"hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split("."):[],_41e=_41d.length,_41f=function(_420,_421,_422){var p,i=0,_423=dojo.global;if(!_422){if(!_420.length){return _423;}else{p=_420[i++];try{_422=dojo.scopeMap[p]&&dojo.scopeMap[p][1];}catch(e){}_422=_422||(p in _423?_423[p]:(_421?_423[p]={}:undefined));}}while(_422&&(p=_420[i++])){_422=(p in _422?_422[p]:(_421?_422[p]={}:undefined));}return _422;},opts=Object.prototype.toString,_424=function(obj,_425,_426){return (_426||[]).concat(Array.prototype.slice.call(obj,_425||0));},_427=/\{([^\}]+)\}/g;var lang={_extraNames:_41d,_mixin:function(dest,_428,_429){var name,s,i,_42a={};for(name in _428){s=_428[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _42a)||_42a[name]!==s))){dest[name]=_429?_429(s):s;}}if(has("bug-for-in-skips-shadowed")){if(_428){for(i=0;i<_41e;++i){name=_41d[i];s=_428[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _42a)||_42a[name]!==s))){dest[name]=_429?_429(s):s;}}}}return dest;},mixin:function(dest,_42b){if(!dest){dest={};}for(var i=1,l=arguments.length;i<l;i++){lang._mixin(dest,arguments[i]);}return dest;},setObject:function(name,_42c,_42d){var _42e=name.split("."),p=_42e.pop(),obj=_41f(_42e,true,_42d);return obj&&p?(obj[p]=_42c):undefined;},getObject:function(name,_42f,_430){return _41f(name.split("."),_42f,_430);},exists:function(name,obj){return lang.getObject(name,false,obj)!==undefined;},isString:function(it){return (typeof it=="string"||it instanceof String);},isArray:function(it){return it&&(it instanceof Array||typeof it=="array");},isFunction:function(it){return opts.call(it)==="[object Function]";},isObject:function(it){return it!==undefined&&(it===null||typeof it=="object"||lang.isArray(it)||lang.isFunction(it));},isArrayLike:function(it){return it&&it!==undefined&&!lang.isString(it)&&!lang.isFunction(it)&&!(it.tagName&&it.tagName.toLowerCase()=="form")&&(lang.isArray(it)||isFinite(it.length));},isAlien:function(it){return it&&!lang.isFunction(it)&&/\{\s*\[native code\]\s*\}/.test(String(it));},extend:function(ctor,_431){for(var i=1,l=arguments.length;i<l;i++){lang._mixin(ctor.prototype,arguments[i]);}return ctor;},_hitchArgs:function(_432,_433){var pre=lang._toArray(arguments,2);var _434=lang.isString(_433);return function(){var args=lang._toArray(arguments);var f=_434?(_432||dojo.global)[_433]:_433;return f&&f.apply(_432||this,pre.concat(args));};},hitch:function(_435,_436){if(arguments.length>2){return lang._hitchArgs.apply(dojo,arguments);}if(!_436){_436=_435;_435=null;}if(lang.isString(_436)){_435=_435||dojo.global;if(!_435[_436]){throw (["lang.hitch: scope[\"",_436,"\"] is null (scope=\"",_435,"\")"].join(""));}return function(){return _435[_436].apply(_435,arguments||[]);};}return !_435?_436:function(){return _436.apply(_435,arguments||[]);};},delegate:(function(){function TMP(){};return function(obj,_437){TMP.prototype=obj;var tmp=new TMP();TMP.prototype=null;if(_437){lang._mixin(tmp,_437);}return tmp;};})(),_toArray:has("ie")?(function(){function slow(obj,_438,_439){var arr=_439||[];for(var x=_438||0;x<obj.length;x++){arr.push(obj[x]);}return arr;};return function(obj){return ((obj.item)?slow:_424).apply(this,arguments);};})():_424,partial:function(_43a){var arr=[null];return lang.hitch.apply(dojo,arr.concat(lang._toArray(arguments)));},clone:function(src){if(!src||typeof src!="object"||lang.isFunction(src)){return src;}if(src.nodeType&&"cloneNode" in src){return src.cloneNode(true);}if(src instanceof Date){return new Date(src.getTime());}if(src instanceof RegExp){return new RegExp(src);}var r,i,l;if(lang.isArray(src)){r=[];for(i=0,l=src.length;i<l;++i){if(i in src){r.push(lang.clone(src[i]));}}}else{r=src.constructor?new src.constructor():{};}return lang._mixin(r,src,lang.clone);},trim:String.prototype.trim?function(str){return str.trim();}:function(str){return str.replace(/^\s\s*/,"").replace(/\s\s*$/,"");},replace:function(tmpl,map,_43b){return tmpl.replace(_43b||_427,lang.isFunction(map)?map:function(_43c,k){return lang.getObject(k,false,map);});}};1&&lang.mixin(dojo,lang);return lang;});},"dojo/request/util":function(){define("dojo/request/util",["exports","../errors/RequestError","../errors/CancelError","../Deferred","../io-query","../_base/array","../_base/lang"],function(_43d,_43e,_43f,_440,_441,_442,lang){_43d.deepCopy=function deepCopy(_443,_444){for(var name in _444){var tval=_443[name],sval=_444[name];if(tval!==sval){if(tval&&typeof tval==="object"&&sval&&typeof sval==="object"){_43d.deepCopy(tval,sval);}else{_443[name]=sval;}}}return _443;};_43d.deepCreate=function deepCreate(_445,_446){_446=_446||{};var _447=lang.delegate(_445),name,_448;for(name in _445){_448=_445[name];if(_448&&typeof _448==="object"){_447[name]=_43d.deepCreate(_448,_446[name]);}}return _43d.deepCopy(_447,_446);};var _449=Object.freeze||function(obj){return obj;};function _44a(_44b){return _449(_44b);};_43d.deferred=function deferred(_44c,_44d,_44e,_44f,_450,last){var def=new _440(function(_451){_44d&&_44d(def,_44c);if(!_451||!(_451 instanceof _43e)&&!(_451 instanceof _43f)){return new _43f("Request canceled",_44c);}return _451;});def.response=_44c;def.isValid=_44e;def.isReady=_44f;def.handleResponse=_450;function _452(_453){_453.response=_44c;throw _453;};var _454=def.then(_44a).otherwise(_452);if(_43d.notify){_454.then(lang.hitch(_43d.notify,"emit","load"),lang.hitch(_43d.notify,"emit","error"));}var _455=_454.then(function(_456){return _456.data||_456.text;});var _457=_449(lang.delegate(_455,{response:_454}));if(last){def.then(function(_458){last.call(def,_458);},function(_459){last.call(def,_44c,_459);});}def.promise=_457;def.then=_457.then;return def;};_43d.addCommonMethods=function addCommonMethods(_45a,_45b){_442.forEach(_45b||["GET","POST","PUT","DELETE"],function(_45c){_45a[(_45c==="DELETE"?"DEL":_45c).toLowerCase()]=function(url,_45d){_45d=lang.delegate(_45d||{});_45d.method=_45c;return _45a(url,_45d);};});};_43d.parseArgs=function parseArgs(url,_45e,_45f){var data=_45e.data,_460=_45e.query;if(data&&!_45f){if(typeof data==="object"){_45e.data=_441.objectToQuery(data);}}if(_460){if(typeof _460==="object"){_460=_441.objectToQuery(_460);}if(_45e.preventCache){_460+=(_460?"&":"")+"request.preventCache="+(+(new Date));}}else{if(_45e.preventCache){_460="request.preventCache="+(+(new Date));}}if(url&&_460){url+=(~url.indexOf("?")?"&":"?")+_460;}return {url:url,options:_45e,getHeader:function(_461){return null;}};};_43d.checkStatus=function(stat){stat=stat||0;return (stat>=200&&stat<300)||stat===304||stat===1223||!stat;};});},"dojo/Evented":function(){define("dojo/Evented",["./aspect","./on"],function(_462,on){"use strict";var _463=_462.after;function _464(){};_464.prototype={on:function(type,_465){return on.parse(this,type,_465,function(_466,type){return _463(_466,"on"+type,_465,true);});},emit:function(type,_467){var args=[this];args.push.apply(args,arguments);return on.emit.apply(on,args);}};return _464;});},"dojo/mouse":function(){define("dojo/mouse",["./_base/kernel","./on","./has","./dom","./_base/window"],function(dojo,on,has,dom,win){has.add("dom-quirks",win.doc&&win.doc.compatMode=="BackCompat");has.add("events-mouseenter",win.doc&&"onmouseenter" in win.doc.createElement("div"));has.add("events-mousewheel",win.doc&&"onmousewheel" in win.doc);var _468;if(has("dom-quirks")||!has("dom-addeventlistener")){_468={LEFT:1,MIDDLE:4,RIGHT:2,isButton:function(e,_469){return e.button&_469;},isLeft:function(e){return e.button&1;},isMiddle:function(e){return e.button&4;},isRight:function(e){return e.button&2;}};}else{_468={LEFT:0,MIDDLE:1,RIGHT:2,isButton:function(e,_46a){return e.button==_46a;},isLeft:function(e){return e.button==0;},isMiddle:function(e){return e.button==1;},isRight:function(e){return e.button==2;}};}dojo.mouseButtons=_468;function _46b(type,_46c){var _46d=function(node,_46e){return on(node,type,function(evt){if(_46c){return _46c(evt,_46e);}if(!dom.isDescendant(evt.relatedTarget,node)){return _46e.call(this,evt);}});};_46d.bubble=function(_46f){return _46b(type,function(evt,_470){var _471=_46f(evt.target);var _472=evt.relatedTarget;if(_471&&(_471!=(_472&&_472.nodeType==1&&_46f(_472)))){return _470.call(_471,evt);}});};return _46d;};var _473;if(has("events-mousewheel")){_473="mousewheel";}else{_473=function(node,_474){return on(node,"DOMMouseScroll",function(evt){evt.wheelDelta=-evt.detail;_474.call(this,evt);});};}return {_eventHandler:_46b,enter:_46b("mouseover"),leave:_46b("mouseout"),wheel:_473,isLeft:_468.isLeft,isMiddle:_468.isMiddle,isRight:_468.isRight};});},"dojo/_base/xhr":function(){define("dojo/_base/xhr",["./kernel","./sniff","require","../io-query","../dom","../dom-form","./Deferred","./config","./json","./lang","./array","../on","../aspect","../request/watch","../request/xhr","../request/util"],function(dojo,has,_475,ioq,dom,_476,_477,_478,json,lang,_479,on,_47a,_47b,_47c,util){dojo._xhrObj=_47c._create;var cfg=dojo.config;dojo.objectToQuery=ioq.objectToQuery;dojo.queryToObject=ioq.queryToObject;dojo.fieldToObject=_476.fieldToObject;dojo.formToObject=_476.toObject;dojo.formToQuery=_476.toQuery;dojo.formToJson=_476.toJson;dojo._blockAsync=false;var _47d=dojo._contentHandlers=dojo.contentHandlers={"text":function(xhr){return xhr.responseText;},"json":function(xhr){return json.fromJson(xhr.responseText||null);},"json-comment-filtered":function(xhr){if(!_478.useCommentedJson){console.warn("Consider using the standard mimetype:application/json."+" json-commenting can introduce security issues. To"+" decrease the chances of hijacking, use the standard the 'json' handler and"+" prefix your json with: {}&&\n"+"Use djConfig.useCommentedJson=true to turn off this message.");}var _47e=xhr.responseText;var _47f=_47e.indexOf("/*");var _480=_47e.lastIndexOf("*/");if(_47f==-1||_480==-1){throw new Error("JSON was not comment filtered");}return json.fromJson(_47e.substring(_47f+2,_480));},"javascript":function(xhr){return dojo.eval(xhr.responseText);},"xml":function(xhr){var _481=xhr.responseXML;if(has("ie")){if((!_481||!_481.documentElement)){var ms=function(n){return "MSXML"+n+".DOMDocument";};var dp=["Microsoft.XMLDOM",ms(6),ms(4),ms(3),ms(2)];_479.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(xhr.responseText);_481=dom;}catch(e){return false;}return true;});}}return _481;},"json-comment-optional":function(xhr){if(xhr.responseText&&/^[^{\[]*\/\*/.test(xhr.responseText)){return _47d["json-comment-filtered"](xhr);}else{return _47d["json"](xhr);}}};dojo._ioSetArgs=function(args,_482,_483,_484){var _485={args:args,url:args.url};var _486=null;if(args.form){var form=dom.byId(args.form);var _487=form.getAttributeNode("action");_485.url=_485.url||(_487?_487.value:null);_486=_476.toObject(form);}var _488=[{}];if(_486){_488.push(_486);}if(args.content){_488.push(args.content);}if(args.preventCache){_488.push({"dojo.preventCache":new Date().valueOf()});}_485.query=ioq.objectToQuery(lang.mixin.apply(null,_488));_485.handleAs=args.handleAs||"text";var d=new _477(function(dfd){dfd.canceled=true;_482&&_482(dfd);var err=dfd.ioArgs.error;if(!err){err=new Error("request cancelled");err.dojoType="cancel";dfd.ioArgs.error=err;}return err;});d.addCallback(_483);var ld=args.load;if(ld&&lang.isFunction(ld)){d.addCallback(function(_489){return ld.call(args,_489,_485);});}var err=args.error;if(err&&lang.isFunction(err)){d.addErrback(function(_48a){return err.call(args,_48a,_485);});}var _48b=args.handle;if(_48b&&lang.isFunction(_48b)){d.addBoth(function(_48c){return _48b.call(args,_48c,_485);});}d.addErrback(function(_48d){return _484(_48d,d);});if(cfg.ioPublish&&dojo.publish&&_485.args.ioPublish!==false){d.addCallbacks(function(res){dojo.publish("/dojo/io/load",[d,res]);return res;},function(res){dojo.publish("/dojo/io/error",[d,res]);return res;});d.addBoth(function(res){dojo.publish("/dojo/io/done",[d,res]);return res;});}d.ioArgs=_485;return d;};var _48e=function(dfd){var ret=_47d[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);return ret===undefined?null:ret;};var _48f=function(_490,dfd){if(!dfd.ioArgs.args.failOk){console.error(_490);}return _490;};var _491=function(dfd){if(_492<=0){_492=0;if(cfg.ioPublish&&dojo.publish&&(!dfd||dfd&&dfd.ioArgs.args.ioPublish!==false)){dojo.publish("/dojo/io/stop");}}};var _492=0;_47a.after(_47b,"_onAction",function(){_492-=1;});_47a.after(_47b,"_onInFlight",_491);dojo._ioCancelAll=_47b.cancelAll;dojo._ioNotifyStart=function(dfd){if(cfg.ioPublish&&dojo.publish&&dfd.ioArgs.args.ioPublish!==false){if(!_492){dojo.publish("/dojo/io/start");}_492+=1;dojo.publish("/dojo/io/send",[dfd]);}};dojo._ioWatch=function(dfd,_493,_494,_495){var args=dfd.ioArgs.options=dfd.ioArgs.args;lang.mixin(dfd,{response:dfd.ioArgs,isValid:function(_496){return _493(dfd);},isReady:function(_497){return _494(dfd);},handleResponse:function(_498){return _495(dfd);}});_47b(dfd);_491(dfd);};var _499="application/x-www-form-urlencoded";dojo._ioAddQueryToUrl=function(_49a){if(_49a.query.length){_49a.url+=(_49a.url.indexOf("?")==-1?"?":"&")+_49a.query;_49a.query=null;}};dojo.xhr=function(_49b,args,_49c){var rDfd;var dfd=dojo._ioSetArgs(args,function(dfd){rDfd&&rDfd.cancel();},_48e,_48f);var _49d=dfd.ioArgs;if("postData" in args){_49d.query=args.postData;}else{if("putData" in args){_49d.query=args.putData;}else{if("rawBody" in args){_49d.query=args.rawBody;}else{if((arguments.length>2&&!_49c)||"POST|PUT".indexOf(_49b.toUpperCase())===-1){dojo._ioAddQueryToUrl(_49d);}}}}var _49e={method:_49b,handleAs:"text",timeout:args.timeout,withCredentials:args.withCredentials,ioArgs:_49d};if(typeof args.headers!=="undefined"){_49e.headers=args.headers;}if(typeof args.contentType!=="undefined"){if(!_49e.headers){_49e.headers={};}_49e.headers["Content-Type"]=args.contentType;}if(typeof _49d.query!=="undefined"){_49e.data=_49d.query;}if(typeof args.sync!=="undefined"){_49e.sync=args.sync;}dojo._ioNotifyStart(dfd);try{rDfd=_47c(_49d.url,_49e,true);}catch(e){dfd.cancel();return dfd;}dfd.ioArgs.xhr=rDfd.response.xhr;rDfd.then(function(){dfd.resolve(dfd);}).otherwise(function(_49f){_49d.error=_49f;dfd.reject(_49f);});return dfd;};dojo.xhrGet=function(args){return dojo.xhr("GET",args);};dojo.rawXhrPost=dojo.xhrPost=function(args){return dojo.xhr("POST",args,true);};dojo.rawXhrPut=dojo.xhrPut=function(args){return dojo.xhr("PUT",args,true);};dojo.xhrDelete=function(args){return dojo.xhr("DELETE",args);};dojo._isDocumentOk=function(x){return util.checkStatus(x.status);};dojo._getText=function(url){var _4a0;dojo.xhrGet({url:url,sync:true,load:function(text){_4a0=text;}});return _4a0;};lang.mixin(dojo.xhr,{_xhrObj:dojo._xhrObj,fieldToObject:_476.fieldToObject,formToObject:_476.toObject,objectToQuery:ioq.objectToQuery,formToQuery:_476.toQuery,formToJson:_476.toJson,queryToObject:ioq.queryToObject,contentHandlers:_47d,_ioSetArgs:dojo._ioSetArgs,_ioCancelAll:dojo._ioCancelAll,_ioNotifyStart:dojo._ioNotifyStart,_ioWatch:dojo._ioWatch,_ioAddQueryToUrl:dojo._ioAddQueryToUrl,_isDocumentOk:dojo._isDocumentOk,_getText:dojo._getText,get:dojo.xhrGet,post:dojo.xhrPost,put:dojo.xhrPut,del:dojo.xhrDelete});return dojo.xhr;});},"dojo/topic":function(){define("dojo/topic",["./Evented"],function(_4a1){var hub=new _4a1;return {publish:function(_4a2,_4a3){return hub.emit.apply(hub,arguments);},subscribe:function(_4a4,_4a5){return hub.on.apply(hub,arguments);}};});},"dojo/loadInit":function(){define("dojo/loadInit",["./_base/loader"],function(_4a6){return {dynamic:0,normalize:function(id){return id;},load:_4a6.loadInit};});},"dojo/_base/unload":function(){define(["./kernel","./lang","../on"],function(dojo,lang,on){var win=window;var _4a7={addOnWindowUnload:function(obj,_4a8){if(!dojo.windowUnloaded){on(win,"unload",(dojo.windowUnloaded=function(){}));}on(win,"unload",lang.hitch(obj,_4a8));},addOnUnload:function(obj,_4a9){on(win,"beforeunload",lang.hitch(obj,_4a9));}};dojo.addOnWindowUnload=_4a7.addOnWindowUnload;dojo.addOnUnload=_4a7.addOnUnload;return _4a7;});},"dojo/Deferred":function(){define(["./has","./_base/lang","./errors/CancelError","./promise/Promise","./promise/instrumentation"],function(has,lang,_4aa,_4ab,_4ac){"use strict";var _4ad=0,_4ae=1,_4af=2;var _4b0="This deferred has already been fulfilled.";var _4b1=Object.freeze||function(){};var _4b2=function(_4b3,type,_4b4,_4b5,_4b6){if(1){if(type===_4af&&_4b7.instrumentRejected&&_4b3.length===0){_4b7.instrumentRejected(_4b4,false,_4b5,_4b6);}}for(var i=0;i<_4b3.length;i++){_4b8(_4b3[i],type,_4b4,_4b5);}};var _4b8=function(_4b9,type,_4ba,_4bb){var func=_4b9[type];var _4bc=_4b9.deferred;if(func){try{var _4bd=func(_4ba);if(_4bd&&typeof _4bd.then==="function"){_4b9.cancel=_4bd.cancel;_4bd.then(_4be(_4bc,_4ae),_4be(_4bc,_4af),_4be(_4bc,_4ad));return;}_4bf(_4bc,_4ae,_4bd);}catch(error){_4bf(_4bc,_4af,error);}}else{_4bf(_4bc,type,_4ba);}if(1){if(type===_4af&&_4b7.instrumentRejected){_4b7.instrumentRejected(_4ba,!!func,_4bb,_4bc.promise);}}};var _4be=function(_4c0,type){return function(_4c1){_4bf(_4c0,type,_4c1);};};var _4bf=function(_4c2,type,_4c3){if(!_4c2.isCanceled()){switch(type){case _4ad:_4c2.progress(_4c3);break;case _4ae:_4c2.resolve(_4c3);break;case _4af:_4c2.reject(_4c3);break;}}};var _4b7=function(_4c4){var _4c5=this.promise=new _4ab();var _4c6=this;var _4c7,_4c8,_4c9;var _4ca=false;var _4cb=[];if(1&&Error.captureStackTrace){Error.captureStackTrace(_4c6,_4b7);Error.captureStackTrace(_4c5,_4b7);}this.isResolved=_4c5.isResolved=function(){return _4c7===_4ae;};this.isRejected=_4c5.isRejected=function(){return _4c7===_4af;};this.isFulfilled=_4c5.isFulfilled=function(){return !!_4c7;};this.isCanceled=_4c5.isCanceled=function(){return _4ca;};this.progress=function(_4cc,_4cd){if(!_4c7){_4b2(_4cb,_4ad,_4cc,null,_4c6);return _4c5;}else{if(_4cd===true){throw new Error(_4b0);}else{return _4c5;}}};this.resolve=function(_4ce,_4cf){if(!_4c7){_4b2(_4cb,_4c7=_4ae,_4c8=_4ce,null,_4c6);_4cb=null;return _4c5;}else{if(_4cf===true){throw new Error(_4b0);}else{return _4c5;}}};var _4d0=this.reject=function(_4d1,_4d2){if(!_4c7){if(1&&Error.captureStackTrace){Error.captureStackTrace(_4c9={},_4d0);}_4b2(_4cb,_4c7=_4af,_4c8=_4d1,_4c9,_4c6);_4cb=null;return _4c5;}else{if(_4d2===true){throw new Error(_4b0);}else{return _4c5;}}};this.then=_4c5.then=function(_4d3,_4d4,_4d5){var _4d6=[_4d5,_4d3,_4d4];_4d6.cancel=_4c5.cancel;_4d6.deferred=new _4b7(function(_4d7){return _4d6.cancel&&_4d6.cancel(_4d7);});if(_4c7&&!_4cb){_4b8(_4d6,_4c7,_4c8,_4c9);}else{_4cb.push(_4d6);}return _4d6.deferred.promise;};this.cancel=_4c5.cancel=function(_4d8,_4d9){if(!_4c7){if(_4c4){var _4da=_4c4(_4d8);_4d8=typeof _4da==="undefined"?_4d8:_4da;}_4ca=true;if(!_4c7){if(typeof _4d8==="undefined"){_4d8=new _4aa();}_4d0(_4d8);return _4d8;}else{if(_4c7===_4af&&_4c8===_4d8){return _4d8;}}}else{if(_4d9===true){throw new Error(_4b0);}}};_4b1(_4c5);};_4b7.prototype.toString=function(){return "[object Deferred]";};if(_4ac){_4ac(_4b7);}return _4b7;});},"dojo/_base/NodeList":function(){define("dojo/_base/NodeList",["./kernel","../query","./array","./html","../NodeList-dom"],function(dojo,_4db,_4dc){var _4dd=_4db.NodeList,nlp=_4dd.prototype;nlp.connect=_4dd._adaptAsForEach(function(){return dojo.connect.apply(this,arguments);});nlp.coords=_4dd._adaptAsMap(dojo.coords);_4dd.events=["blur","focus","change","click","error","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","submit"];_4dc.forEach(_4dd.events,function(evt){var _4de="on"+evt;nlp[_4de]=function(a,b){return this.connect(_4de,a,b);};});dojo.NodeList=_4dd;return _4dd;});},"dojo/_base/Color":function(){define(["./kernel","./lang","./array","./config"],function(dojo,lang,_4df,_4e0){var _4e1=dojo.Color=function(_4e2){if(_4e2){this.setColor(_4e2);}};_4e1.named={"black":[0,0,0],"silver":[192,192,192],"gray":[128,128,128],"white":[255,255,255],"maroon":[128,0,0],"red":[255,0,0],"purple":[128,0,128],"fuchsia":[255,0,255],"green":[0,128,0],"lime":[0,255,0],"olive":[128,128,0],"yellow":[255,255,0],"navy":[0,0,128],"blue":[0,0,255],"teal":[0,128,128],"aqua":[0,255,255],"transparent":_4e0.transparentColor||[0,0,0,0]};lang.extend(_4e1,{r:255,g:255,b:255,a:1,_set:function(r,g,b,a){var t=this;t.r=r;t.g=g;t.b=b;t.a=a;},setColor:function(_4e3){if(lang.isString(_4e3)){_4e1.fromString(_4e3,this);}else{if(lang.isArray(_4e3)){_4e1.fromArray(_4e3,this);}else{this._set(_4e3.r,_4e3.g,_4e3.b,_4e3.a);if(!(_4e3 instanceof _4e1)){this.sanitize();}}}return this;},sanitize:function(){return this;},toRgb:function(){var t=this;return [t.r,t.g,t.b];},toRgba:function(){var t=this;return [t.r,t.g,t.b,t.a];},toHex:function(){var arr=_4df.map(["r","g","b"],function(x){var s=this[x].toString(16);return s.length<2?"0"+s:s;},this);return "#"+arr.join("");},toCss:function(_4e4){var t=this,rgb=t.r+", "+t.g+", "+t.b;return (_4e4?"rgba("+rgb+", "+t.a:"rgb("+rgb)+")";},toString:function(){return this.toCss(true);}});_4e1.blendColors=dojo.blendColors=function(_4e5,end,_4e6,obj){var t=obj||new _4e1();_4df.forEach(["r","g","b","a"],function(x){t[x]=_4e5[x]+(end[x]-_4e5[x])*_4e6;if(x!="a"){t[x]=Math.round(t[x]);}});return t.sanitize();};_4e1.fromRgb=dojo.colorFromRgb=function(_4e7,obj){var m=_4e7.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);return m&&_4e1.fromArray(m[1].split(/\s*,\s*/),obj);};_4e1.fromHex=dojo.colorFromHex=function(_4e8,obj){var t=obj||new _4e1(),bits=(_4e8.length==4)?4:8,mask=(1<<bits)-1;_4e8=Number("0x"+_4e8.substr(1));if(isNaN(_4e8)){return null;}_4df.forEach(["b","g","r"],function(x){var c=_4e8&mask;_4e8>>=bits;t[x]=bits==4?17*c:c;});t.a=1;return t;};_4e1.fromArray=dojo.colorFromArray=function(a,obj){var t=obj||new _4e1();t._set(Number(a[0]),Number(a[1]),Number(a[2]),Number(a[3]));if(isNaN(t.a)){t.a=1;}return t.sanitize();};_4e1.fromString=dojo.colorFromString=function(str,obj){var a=_4e1.named[str];return a&&_4e1.fromArray(a,obj)||_4e1.fromRgb(str,obj)||_4e1.fromHex(str,obj);};return _4e1;});},"dojo/promise/instrumentation":function(){define(["./tracer","../has","../_base/lang","../_base/array"],function(_4e9,has,lang,_4ea){function _4eb(_4ec,_4ed,_4ee){var _4ef="";if(_4ec&&_4ec.stack){_4ef+=_4ec.stack;}if(_4ed&&_4ed.stack){_4ef+="\n ----------------------------------------\n rejected"+_4ed.stack.split("\n").slice(1).join("\n").replace(/^\s+/," ");}if(_4ee&&_4ee.stack){_4ef+="\n ----------------------------------------\n"+_4ee.stack;}console.error(_4ec,_4ef);};function _4f0(_4f1,_4f2,_4f3,_4f4){if(!_4f2){_4eb(_4f1,_4f3,_4f4);}};var _4f5=[];var _4f6=false;var _4f7=1000;function _4f8(_4f9,_4fa,_4fb,_4fc){if(_4fa){_4ea.some(_4f5,function(obj,ix){if(obj.error===_4f9){_4f5.splice(ix,1);return true;}});}else{if(!_4ea.some(_4f5,function(obj){return obj.error===_4f9;})){_4f5.push({error:_4f9,rejection:_4fb,deferred:_4fc,timestamp:new Date().getTime()});}}if(!_4f6){_4f6=setTimeout(_4fd,_4f7);}};function _4fd(){var now=new Date().getTime();var _4fe=now-_4f7;_4f5=_4ea.filter(_4f5,function(obj){if(obj.timestamp<_4fe){_4eb(obj.error,obj.rejection,obj.deferred);return false;}return true;});if(_4f5.length){_4f6=setTimeout(_4fd,_4f5[0].timestamp+_4f7-now);}};return function(_4ff){var _500=has("config-useDeferredInstrumentation");if(_500){_4e9.on("resolved",lang.hitch(console,"log","resolved"));_4e9.on("rejected",lang.hitch(console,"log","rejected"));_4e9.on("progress",lang.hitch(console,"log","progress"));var args=[];if(typeof _500==="string"){args=_500.split(",");_500=args.shift();}if(_500==="report-rejections"){_4ff.instrumentRejected=_4f0;}else{if(_500==="report-unhandled-rejections"||_500===true||_500===1){_4ff.instrumentRejected=_4f8;_4f7=parseInt(args[0],10)||_4f7;}else{throw new Error("Unsupported instrumentation usage <"+_500+">");}}}};});},"dojo/selector/_loader":function(){define(["../has","require"],function(has,_501){"use strict";var _502=document.createElement("div");has.add("dom-qsa2.1",!!_502.querySelectorAll);has.add("dom-qsa3",function(){try{_502.innerHTML="<p class='TEST'></p>";return _502.querySelectorAll(".TEST:empty").length==1;}catch(e){}});var _503;var acme="./acme",lite="./lite";return {load:function(id,_504,_505,_506){var req=_501;id=id=="default"?has("config-selectorEngine")||"css3":id;id=id=="css2"||id=="lite"?lite:id=="css2.1"?has("dom-qsa2.1")?lite:acme:id=="css3"?has("dom-qsa3")?lite:acme:id=="acme"?acme:(req=_504)&&id;if(id.charAt(id.length-1)=="?"){id=id.substring(0,id.length-1);var _507=true;}if(_507&&(has("dom-compliant-qsa")||_503)){return _505(_503);}req([id],function(_508){if(id!="./lite"){_503=_508;}_505(_508);});}};});},"dojo/promise/Promise":function(){define(["../_base/lang"],function(lang){"use strict";function _509(){throw new TypeError("abstract");};return lang.extend(function Promise(){},{then:function(_50a,_50b,_50c){_509();},cancel:function(_50d,_50e){_509();},isResolved:function(){_509();},isRejected:function(){_509();},isFulfilled:function(){_509();},isCanceled:function(){_509();},always:function(_50f){return this.then(_50f,_50f);},otherwise:function(_510){return this.then(null,_510);},trace:function(){return this;},traceRejected:function(){return this;},toString:function(){return "[object Promise]";}});});},"dojo/request/watch":function(){define(["./util","../errors/RequestTimeoutError","../errors/CancelError","../_base/array","../_base/window","../has!host-browser?dom-addeventlistener?:../on:"],function(util,_511,_512,_513,win,on){var _514=null,_515=[];function _516(){var now=+(new Date);for(var i=0,dfd;i<_515.length&&(dfd=_515[i]);i++){var _517=dfd.response,_518=_517.options;if((dfd.isCanceled&&dfd.isCanceled())||(dfd.isValid&&!dfd.isValid(_517))){_515.splice(i--,1);_519._onAction&&_519._onAction();}else{if(dfd.isReady&&dfd.isReady(_517)){_515.splice(i--,1);dfd.handleResponse(_517);_519._onAction&&_519._onAction();}else{if(dfd.startTime){if(dfd.startTime+(_518.timeout||0)<now){_515.splice(i--,1);dfd.cancel(new _511(_517));_519._onAction&&_519._onAction();}}}}}_519._onInFlight&&_519._onInFlight(dfd);if(!_515.length){clearInterval(_514);_514=null;}};function _519(dfd){if(dfd.response.options.timeout){dfd.startTime=+(new Date);}if(dfd.isFulfilled()){return;}_515.push(dfd);if(!_514){_514=setInterval(_516,50);}if(dfd.response.options.sync){_516();}};_519.cancelAll=function cancelAll(){try{_513.forEach(_515,function(dfd){try{dfd.cancel(new _512("All requests canceled."));}catch(e){}});}catch(e){}};if(win&&on&&win.doc.attachEvent){on(win.global,"unload",function(){_519.cancelAll();});}return _519;});},"dojo/on":function(){define(["./has!dom-addeventlistener?:./aspect","./_base/kernel","./has"],function(_51a,dojo,has){"use strict";if(1){var _51b=window.ScriptEngineMajorVersion;has.add("jscript",_51b&&(_51b()+ScriptEngineMinorVersion()/10));has.add("event-orientationchange",has("touch")&&!has("android"));has.add("event-stopimmediatepropagation",window.Event&&!!window.Event.prototype&&!!window.Event.prototype.stopImmediatePropagation);}var on=function(_51c,type,_51d,_51e){if(_51c.on&&typeof type!="function"){return _51c.on(type,_51d);}return on.parse(_51c,type,_51d,_51f,_51e,this);};on.pausable=function(_520,type,_521,_522){var _523;var _524=on(_520,type,function(){if(!_523){return _521.apply(this,arguments);}},_522);_524.pause=function(){_523=true;};_524.resume=function(){_523=false;};return _524;};on.once=function(_525,type,_526,_527){var _528=on(_525,type,function(){_528.remove();return _526.apply(this,arguments);});return _528;};on.parse=function(_529,type,_52a,_52b,_52c,_52d){if(type.call){return type.call(_52d,_529,_52a);}if(type.indexOf(",")>-1){var _52e=type.split(/\s*,\s*/);var _52f=[];var i=0;var _530;while(_530=_52e[i++]){_52f.push(_52b(_529,_530,_52a,_52c,_52d));}_52f.remove=function(){for(var i=0;i<_52f.length;i++){_52f[i].remove();}};return _52f;}return _52b(_529,type,_52a,_52c,_52d);};var _531=/^touch/;function _51f(_532,type,_533,_534,_535){var _536=type.match(/(.*):(.*)/);if(_536){type=_536[2];_536=_536[1];return on.selector(_536,type).call(_535,_532,_533);}if(has("touch")){if(_531.test(type)){_533=_537(_533);}if(!has("event-orientationchange")&&(type=="orientationchange")){type="resize";_532=window;_533=_537(_533);}}if(_538){_533=_538(_533);}if(_532.addEventListener){var _539=type in _53a,_53b=_539?_53a[type]:type;_532.addEventListener(_53b,_533,_539);return {remove:function(){_532.removeEventListener(_53b,_533,_539);}};}type="on"+type;if(_53c&&_532.attachEvent){return _53c(_532,type,_533);}throw new Error("Target must be an event emitter");};on.selector=function(_53d,_53e,_53f){return function(_540,_541){var _542=typeof _53d=="function"?{matches:_53d}:this,_543=_53e.bubble;function _544(_545){_542=_542&&_542.matches?_542:dojo.query;while(!_542.matches(_545,_53d,_540)){if(_545==_540||_53f===false||!(_545=_545.parentNode)||_545.nodeType!=1){return;}}return _545;};if(_543){return on(_540,_543(_544),_541);}return on(_540,_53e,function(_546){var _547=_544(_546.target);return _547&&_541.call(_547,_546);});};};function _548(){this.cancelable=false;};function _549(){this.bubbles=false;};var _54a=[].slice,_54b=on.emit=function(_54c,type,_54d){var args=_54a.call(arguments,2);var _54e="on"+type;if("parentNode" in _54c){var _54f=args[0]={};for(var i in _54d){_54f[i]=_54d[i];}_54f.preventDefault=_548;_54f.stopPropagation=_549;_54f.target=_54c;_54f.type=type;_54d=_54f;}do{_54c[_54e]&&_54c[_54e].apply(_54c,args);}while(_54d&&_54d.bubbles&&(_54c=_54c.parentNode));return _54d&&_54d.cancelable&&_54d;};var _53a={};if(!has("event-stopimmediatepropagation")){var _550=function(){this.immediatelyStopped=true;this.modified=true;};var _538=function(_551){return function(_552){if(!_552.immediatelyStopped){_552.stopImmediatePropagation=_550;return _551.apply(this,arguments);}};};}if(has("dom-addeventlistener")){_53a={focusin:"focus",focusout:"blur"};if(has("opera")){_53a.keydown="keypress";}on.emit=function(_553,type,_554){if(_553.dispatchEvent&&document.createEvent){var _555=_553.ownerDocument.createEvent("HTMLEvents");_555.initEvent(type,!!_554.bubbles,!!_554.cancelable);for(var i in _554){var _556=_554[i];if(!(i in _555)){_555[i]=_554[i];}}return _553.dispatchEvent(_555)&&_555;}return _54b.apply(on,arguments);};}else{on._fixEvent=function(evt,_557){if(!evt){var w=_557&&(_557.ownerDocument||_557.document||_557).parentWindow||window;evt=w.event;}if(!evt){return evt;}if(_558&&evt.type==_558.type){evt=_558;}if(!evt.target){evt.target=evt.srcElement;evt.currentTarget=(_557||evt.srcElement);if(evt.type=="mouseover"){evt.relatedTarget=evt.fromElement;}if(evt.type=="mouseout"){evt.relatedTarget=evt.toElement;}if(!evt.stopPropagation){evt.stopPropagation=_559;evt.preventDefault=_55a;}switch(evt.type){case "keypress":var c=("charCode" in evt?evt.charCode:evt.keyCode);if(c==10){c=0;evt.keyCode=13;}else{if(c==13||c==27){c=0;}else{if(c==3){c=99;}}}evt.charCode=c;_55b(evt);break;}}return evt;};var _558,_55c=function(_55d){this.handle=_55d;};_55c.prototype.remove=function(){delete _dojoIEListeners_[this.handle];};var _55e=function(_55f){return function(evt){evt=on._fixEvent(evt,this);var _560=_55f.call(this,evt);if(evt.modified){if(!_558){setTimeout(function(){_558=null;});}_558=evt;}return _560;};};var _53c=function(_561,type,_562){_562=_55e(_562);if(((_561.ownerDocument?_561.ownerDocument.parentWindow:_561.parentWindow||_561.window||window)!=top||has("jscript")<5.8)&&!has("config-_allow_leaks")){if(typeof _dojoIEListeners_=="undefined"){_dojoIEListeners_=[];}var _563=_561[type];if(!_563||!_563.listeners){var _564=_563;_563=Function("event","var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}");_563.listeners=[];_561[type]=_563;_563.global=this;if(_564){_563.listeners.push(_dojoIEListeners_.push(_564)-1);}}var _565;_563.listeners.push(_565=(_563.global._dojoIEListeners_.push(_562)-1));return new _55c(_565);}return _51a.after(_561,type,_562,true);};var _55b=function(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _559=function(){this.cancelBubble=true;};var _55a=on._preventDefault=function(){this.bubbledKeyCode=this.keyCode;if(this.ctrlKey){try{this.keyCode=0;}catch(e){}}this.defaultPrevented=true;this.returnValue=false;};}if(has("touch")){var _566=function(){};var _567=window.orientation;var _537=function(_568){return function(_569){var _56a=_569.corrected;if(!_56a){var type=_569.type;try{delete _569.type;}catch(e){}if(_569.type){_566.prototype=_569;var _56a=new _566;_56a.preventDefault=function(){_569.preventDefault();};_56a.stopPropagation=function(){_569.stopPropagation();};}else{_56a=_569;_56a.type=type;}_569.corrected=_56a;if(type=="resize"){if(_567==window.orientation){return null;}_567=window.orientation;_56a.type="orientationchange";return _568.call(this,_56a);}if(!("rotation" in _56a)){_56a.rotation=0;_56a.scale=1;}var _56b=_56a.changedTouches[0];for(var i in _56b){delete _56a[i];_56a[i]=_56b[i];}}return _568.call(this,_56a);};};}return on;});},"dojo/_base/sniff":function(){define(["./kernel","./lang","../sniff"],function(dojo,lang,has){if(!1){return has;}dojo._name="browser";lang.mixin(dojo,{isBrowser:true,isFF:has("ff"),isIE:has("ie"),isKhtml:has("khtml"),isWebKit:has("webkit"),isMozilla:has("mozilla"),isMoz:has("mozilla"),isOpera:has("opera"),isSafari:has("safari"),isChrome:has("chrome"),isMac:has("mac"),isIos:has("ios"),isAndroid:has("android"),isWii:has("wii"),isQuirks:has("quirks"),isAir:has("air")});dojo.locale=dojo.locale||(has("ie")?navigator.userLanguage:navigator.language).toLowerCase();return has;});},"dojo/errors/create":function(){define(["../_base/lang"],function(lang){return function(name,ctor,base,_56c){base=base||Error;var _56d=function(_56e){if(base===Error){if(Error.captureStackTrace){Error.captureStackTrace(this,_56d);}var err=Error.call(this,_56e),prop;for(prop in err){if(err.hasOwnProperty(prop)){this[prop]=err[prop];}}this.message=_56e;this.stack=err.stack;}else{base.apply(this,arguments);}if(ctor){ctor.apply(this,arguments);}};_56d.prototype=lang.delegate(base.prototype,_56c);_56d.prototype.name=name;_56d.prototype.constructor=_56d;return _56d;};});},"dojo/_base/array":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var _56f={},u;function _570(fn){return _56f[fn]=new Function("item","index","array",fn);};function _571(some){var _572=!some;return function(a,fn,o){var i=0,l=a&&a.length||0,_573;if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_56f[fn]||_570(fn);}if(o){for(;i<l;++i){_573=!fn.call(o,a[i],i,a);if(some^_573){return !_573;}}}else{for(;i<l;++i){_573=!fn(a[i],i,a);if(some^_573){return !_573;}}}return _572;};};function _574(up){var _575=1,_576=0,_577=0;if(!up){_575=_576=_577=-1;}return function(a,x,from,last){if(last&&_575>0){return _578.lastIndexOf(a,x,from);}var l=a&&a.length||0,end=up?l+_577:_576,i;if(from===u){i=up?_576:l+_577;}else{if(from<0){i=l+from;if(i<0){i=_576;}}else{i=from>=l?l+_577:from;}}if(l&&typeof a=="string"){a=a.split("");}for(;i!=end;i+=_575){if(a[i]==x){return i;}}return -1;};};var _578={every:_571(false),some:_571(true),indexOf:_574(true),lastIndexOf:_574(false),forEach:function(arr,_579,_57a){var i=0,l=arr&&arr.length||0;if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _579=="string"){_579=_56f[_579]||_570(_579);}if(_57a){for(;i<l;++i){_579.call(_57a,arr[i],i,arr);}}else{for(;i<l;++i){_579(arr[i],i,arr);}}},map:function(arr,_57b,_57c,Ctr){var i=0,l=arr&&arr.length||0,out=new (Ctr||Array)(l);if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _57b=="string"){_57b=_56f[_57b]||_570(_57b);}if(_57c){for(;i<l;++i){out[i]=_57b.call(_57c,arr[i],i,arr);}}else{for(;i<l;++i){out[i]=_57b(arr[i],i,arr);}}return out;},filter:function(arr,_57d,_57e){var i=0,l=arr&&arr.length||0,out=[],_57f;if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _57d=="string"){_57d=_56f[_57d]||_570(_57d);}if(_57e){for(;i<l;++i){_57f=arr[i];if(_57d.call(_57e,_57f,i,arr)){out.push(_57f);}}}else{for(;i<l;++i){_57f=arr[i];if(_57d(_57f,i,arr)){out.push(_57f);}}}return out;},clearCache:function(){_56f={};}};1&&lang.mixin(dojo,_578);return _578;});},"dojo/_base/json":function(){define(["./kernel","../json"],function(dojo,json){dojo.fromJson=function(js){return eval("("+js+")");};dojo._escapeString=json.stringify;dojo.toJsonIndentStr="\t";dojo.toJson=function(it,_580){return json.stringify(it,function(key,_581){if(_581){var tf=_581.__json__||_581.json;if(typeof tf=="function"){return tf.call(_581);}}return _581;},_580&&dojo.toJsonIndentStr);};return dojo;});},"dojo/_base/window":function(){define("dojo/_base/window",["./kernel","./lang","../sniff"],function(dojo,lang,has){var ret={global:dojo.global,doc:this["document"]||null,body:function(doc){doc=doc||dojo.doc;return doc.body||doc.getElementsByTagName("body")[0];},setContext:function(_582,_583){dojo.global=ret.global=_582;dojo.doc=ret.doc=_583;},withGlobal:function(_584,_585,_586,_587){var _588=dojo.global;try{dojo.global=ret.global=_584;return ret.withDoc.call(null,_584.document,_585,_586,_587);}finally{dojo.global=ret.global=_588;}},withDoc:function(_589,_58a,_58b,_58c){var _58d=ret.doc,oldQ=has("quirks"),_58e=has("ie"),isIE,mode,pwin;try{dojo.doc=ret.doc=_589;dojo.isQuirks=has.add("quirks",dojo.doc.compatMode=="BackCompat",true,true);if(has("ie")){if((pwin=_589.parentWindow)&&pwin.navigator){isIE=parseFloat(pwin.navigator.appVersion.split("MSIE ")[1])||undefined;mode=_589.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}dojo.isIE=has.add("ie",isIE,true,true);}}if(_58b&&typeof _58a=="string"){_58a=_58b[_58a];}return _58a.apply(_58b,_58c||[]);}finally{dojo.doc=ret.doc=_58d;dojo.isQuirks=has.add("quirks",oldQ,true,true);dojo.isIE=has.add("ie",_58e,true,true);}}};1&&lang.mixin(dojo,ret);return ret;});},"dojo/dom-class":function(){define(["./_base/lang","./_base/array","./dom"],function(lang,_58f,dom){var _590="className";var cls,_591=/\s+/,a1=[""];function _592(s){if(typeof s=="string"||s instanceof String){if(s&&!_591.test(s)){a1[0]=s;return a1;}var a=s.split(_591);if(a.length&&!a[0]){a.shift();}if(a.length&&!a[a.length-1]){a.pop();}return a;}if(!s){return [];}return _58f.filter(s,function(x){return x;});};var _593={};cls={contains:function containsClass(node,_594){return ((" "+dom.byId(node)[_590]+" ").indexOf(" "+_594+" ")>=0);},add:function addClass(node,_595){node=dom.byId(node);_595=_592(_595);var cls=node[_590],_596;cls=cls?" "+cls+" ":" ";_596=cls.length;for(var i=0,len=_595.length,c;i<len;++i){c=_595[i];if(c&&cls.indexOf(" "+c+" ")<0){cls+=c+" ";}}if(_596<cls.length){node[_590]=cls.substr(1,cls.length-2);}},remove:function removeClass(node,_597){node=dom.byId(node);var cls;if(_597!==undefined){_597=_592(_597);cls=" "+node[_590]+" ";for(var i=0,len=_597.length;i<len;++i){cls=cls.replace(" "+_597[i]+" "," ");}cls=lang.trim(cls);}else{cls="";}if(node[_590]!=cls){node[_590]=cls;}},replace:function replaceClass(node,_598,_599){node=dom.byId(node);_593[_590]=node[_590];cls.remove(_593,_599);cls.add(_593,_598);if(node[_590]!==_593[_590]){node[_590]=_593[_590];}},toggle:function toggleClass(node,_59a,_59b){node=dom.byId(node);if(_59b===undefined){_59a=_592(_59a);for(var i=0,len=_59a.length,c;i<len;++i){c=_59a[i];cls[cls.contains(node,c)?"remove":"add"](node,c);}}else{cls[_59b?"add":"remove"](node,_59a);}return _59b;}};return cls;});},"dojo/_base/config":function(){define(["../has","require"],function(has,_59c){var _59d={};if(1){var src=_59c.rawConfig,p;for(p in src){_59d[p]=src[p];}}else{var _59e=function(_59f,_5a0,_5a1){for(p in _59f){p!="has"&&has.add(_5a0+p,_59f[p],0,_5a1);}};_59d=1?_59c.rawConfig:this.dojoConfig||this.djConfig||{};_59e(_59d,"config",1);_59e(_59d.has,"",1);}return _59d;});},"dojo/main":function(){define(["./_base/kernel","./has","require","./sniff","./_base/lang","./_base/array","./_base/config","./ready","./_base/declare","./_base/connect","./_base/Deferred","./_base/json","./_base/Color","./has!dojo-firebug?./_firebug/firebug","./_base/browser","./_base/loader"],function(_5a2,has,_5a3,_5a4,lang,_5a5,_5a6,_5a7){if(_5a6.isDebug){_5a3(["./_firebug/firebug"]);}1||has.add("dojo-config-require",1);if(1){var deps=_5a6.require;if(deps){deps=_5a5.map(lang.isArray(deps)?deps:[deps],function(item){return item.replace(/\./g,"/");});if(_5a2.isAsync){_5a3(deps);}else{_5a7(1,function(){_5a3(deps);});}}}return _5a2;});},"dojo/_base/event":function(){define("dojo/_base/event",["./kernel","../on","../has","../dom-geometry"],function(dojo,on,has,dom){if(on._fixEvent){var _5a8=on._fixEvent;on._fixEvent=function(evt,se){evt=_5a8(evt,se);if(evt){dom.normalizeEvent(evt);}return evt;};}var ret={fix:function(evt,_5a9){if(on._fixEvent){return on._fixEvent(evt,_5a9);}return evt;},stop:function(evt){if(has("dom-addeventlistener")||(evt&&evt.preventDefault)){evt.preventDefault();evt.stopPropagation();}else{evt=evt||window.event;evt.cancelBubble=true;on._preventDefault.call(evt);}}};if(1){dojo.fixEvent=ret.fix;dojo.stopEvent=ret.stop;}return ret;});},"dojo/sniff":function(){define(["./has"],function(has){if(1){var n=navigator,dua=n.userAgent,dav=n.appVersion,tv=parseFloat(dav);has.add("air",dua.indexOf("AdobeAIR")>=0),has.add("khtml",dav.indexOf("Konqueror")>=0?tv:undefined);has.add("webkit",parseFloat(dua.split("WebKit/")[1])||undefined);has.add("chrome",parseFloat(dua.split("Chrome/")[1])||undefined);has.add("safari",dav.indexOf("Safari")>=0&&!has("chrome")?parseFloat(dav.split("Version/")[1]):undefined);has.add("mac",dav.indexOf("Macintosh")>=0);has.add("quirks",document.compatMode=="BackCompat");has.add("ios",/iPhone|iPod|iPad/.test(dua));has.add("android",parseFloat(dua.split("Android ")[1])||undefined);if(!has("webkit")){if(dua.indexOf("Opera")>=0){has.add("opera",tv>=9.8?parseFloat(dua.split("Version/")[1])||tv:tv);}if(dua.indexOf("Gecko")>=0&&!has("khtml")&&!has("webkit")){has.add("mozilla",tv);}if(has("mozilla")){has.add("ff",parseFloat(dua.split("Firefox/")[1]||dua.split("Minefield/")[1])||undefined);}if(document.all&&!has("opera")){var isIE=parseFloat(dav.split("MSIE ")[1])||undefined;var mode=document.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}has.add("ie",isIE);}has.add("wii",typeof opera!="undefined"&&opera.wiiremote);}}return has;});},"dojo/request/handlers":function(){define(["../json","../_base/kernel","../_base/array","../has"],function(JSON,_5aa,_5ab,has){has.add("activex",typeof ActiveXObject!=="undefined");var _5ac;if(has("activex")){var dp=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML.DOMDocument"];_5ac=function(_5ad){var _5ae=_5ad.data;if(!_5ae||!_5ae.documentElement){var text=_5ad.text;_5ab.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(text);_5ae=dom;}catch(e){return false;}return true;});}return _5ae;};}var _5af={"javascript":function(_5b0){return _5aa.eval(_5b0.text||"");},"json":function(_5b1){return JSON.parse(_5b1.text||null);},"xml":_5ac};function _5b2(_5b3){var _5b4=_5af[_5b3.options.handleAs];_5b3.data=_5b4?_5b4(_5b3):(_5b3.data||_5b3.text);return _5b3;};_5b2.register=function(name,_5b5){_5af[name]=_5b5;};return _5b2;});},"dojo/aspect":function(){define("dojo/aspect",[],function(){"use strict";var _5b6,_5b7=0;function _5b8(_5b9,type,_5ba,_5bb){var _5bc=_5b9[type];var _5bd=type=="around";var _5be;if(_5bd){var _5bf=_5ba(function(){return _5bc.advice(this,arguments);});_5be={remove:function(){_5be.cancelled=true;},advice:function(_5c0,args){return _5be.cancelled?_5bc.advice(_5c0,args):_5bf.apply(_5c0,args);}};}else{_5be={remove:function(){var _5c1=_5be.previous;var next=_5be.next;if(!next&&!_5c1){delete _5b9[type];}else{if(_5c1){_5c1.next=next;}else{_5b9[type]=next;}if(next){next.previous=_5c1;}}},id:_5b7++,advice:_5ba,receiveArguments:_5bb};}if(_5bc&&!_5bd){if(type=="after"){var next=_5bc;while(next){_5bc=next;next=next.next;}_5bc.next=_5be;_5be.previous=_5bc;}else{if(type=="before"){_5b9[type]=_5be;_5be.next=_5bc;_5bc.previous=_5be;}}}else{_5b9[type]=_5be;}return _5be;};function _5c2(type){return function(_5c3,_5c4,_5c5,_5c6){var _5c7=_5c3[_5c4],_5c8;if(!_5c7||_5c7.target!=_5c3){_5c3[_5c4]=_5c8=function(){var _5c9=_5b7;var args=arguments;var _5ca=_5c8.before;while(_5ca){args=_5ca.advice.apply(this,args)||args;_5ca=_5ca.next;}if(_5c8.around){var _5cb=_5c8.around.advice(this,args);}var _5cc=_5c8.after;while(_5cc&&_5cc.id<_5c9){if(_5cc.receiveArguments){var _5cd=_5cc.advice.apply(this,args);_5cb=_5cd===_5b6?_5cb:_5cd;}else{_5cb=_5cc.advice.call(this,_5cb,args);}_5cc=_5cc.next;}return _5cb;};if(_5c7){_5c8.around={advice:function(_5ce,args){return _5c7.apply(_5ce,args);}};}_5c8.target=_5c3;}var _5cf=_5b8((_5c8||_5c7),type,_5c5,_5c6);_5c5=null;return _5cf;};};var _5d0=_5c2("after");var _5d1=_5c2("before");var _5d2=_5c2("around");return {before:_5d1,around:_5d2,after:_5d0};});},"dojo/ready":function(){define("dojo/ready",["./_base/kernel","./has","require","./domReady","./_base/lang"],function(dojo,has,_5d3,_5d4,lang){var _5d5=0,_5d6,_5d7=[],_5d8=0,_5d9=function(){_5d5=1;dojo._postLoad=dojo.config.afterOnLoad=true;if(_5d7.length){_5d6(_5da);}},_5da=function(){if(_5d5&&!_5d8&&_5d7.length){_5d8=1;var f=_5d7.shift();try{f();}finally{_5d8=0;}_5d8=0;if(_5d7.length){_5d6(_5da);}}};_5d3.on("idle",_5da);_5d6=function(){if(_5d3.idle()){_5da();}};var _5db=dojo.ready=dojo.addOnLoad=function(_5dc,_5dd,_5de){var _5df=lang._toArray(arguments);if(typeof _5dc!="number"){_5de=_5dd;_5dd=_5dc;_5dc=1000;}else{_5df.shift();}_5de=_5de?lang.hitch.apply(dojo,_5df):function(){_5dd();};_5de.priority=_5dc;for(var i=0;i<_5d7.length&&_5dc>=_5d7[i].priority;i++){}_5d7.splice(i,0,_5de);_5d6();};1||has.add("dojo-config-addOnLoad",1);if(1){var dca=dojo.config.addOnLoad;if(dca){_5db[(lang.isArray(dca)?"apply":"call")](dojo,dca);}}if(1&&dojo.config.parseOnLoad&&!dojo.isAsync){_5db(99,function(){if(!dojo.parser){dojo.deprecated("Add explicit require(['dojo/parser']);","","2.0");_5d3(["dojo/parser"]);}});}if(1){_5d4(_5d9);}else{_5d9();}return _5db;});},"dojo/_base/connect":function(){define(["./kernel","../on","../topic","../aspect","./event","../mouse","./sniff","./lang","../keys"],function(dojo,on,hub,_5e0,_5e1,_5e2,has,lang){has.add("events-keypress-typed",function(){var _5e3={charCode:0};try{_5e3=document.createEvent("KeyboardEvent");(_5e3.initKeyboardEvent||_5e3.initKeyEvent).call(_5e3,"keypress",true,true,null,false,false,false,false,9,3);}catch(e){}return _5e3.charCode==0&&!has("opera");});function _5e4(obj,_5e5,_5e6,_5e7,_5e8){_5e7=lang.hitch(_5e6,_5e7);if(!obj||!(obj.addEventListener||obj.attachEvent)){return _5e0.after(obj||dojo.global,_5e5,_5e7,true);}if(typeof _5e5=="string"&&_5e5.substring(0,2)=="on"){_5e5=_5e5.substring(2);}if(!obj){obj=dojo.global;}if(!_5e8){switch(_5e5){case "keypress":_5e5=_5e9;break;case "mouseenter":_5e5=_5e2.enter;break;case "mouseleave":_5e5=_5e2.leave;break;}}return on(obj,_5e5,_5e7,_5e8);};var _5ea={106:42,111:47,186:59,187:43,188:44,189:45,190:46,191:47,192:96,219:91,220:92,221:93,222:39,229:113};var _5eb=has("mac")?"metaKey":"ctrlKey";var _5ec=function(evt,_5ed){var faux=lang.mixin({},evt,_5ed);_5ee(faux);faux.preventDefault=function(){evt.preventDefault();};faux.stopPropagation=function(){evt.stopPropagation();};return faux;};function _5ee(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _5e9;if(has("events-keypress-typed")){var _5ef=function(e,code){try{return (e.keyCode=code);}catch(e){return 0;}};_5e9=function(_5f0,_5f1){var _5f2=on(_5f0,"keydown",function(evt){var k=evt.keyCode;var _5f3=(k!=13)&&k!=32&&(k!=27||!has("ie"))&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222)&&k!=229;if(_5f3||evt.ctrlKey){var c=_5f3?0:k;if(evt.ctrlKey){if(k==3||k==13){return _5f1.call(evt.currentTarget,evt);}else{if(c>95&&c<106){c-=48;}else{if((!evt.shiftKey)&&(c>=65&&c<=90)){c+=32;}else{c=_5ea[c]||c;}}}}var faux=_5ec(evt,{type:"keypress",faux:true,charCode:c});_5f1.call(evt.currentTarget,faux);if(has("ie")){_5ef(evt,faux.keyCode);}}});var _5f4=on(_5f0,"keypress",function(evt){var c=evt.charCode;c=c>=32?c:0;evt=_5ec(evt,{charCode:c,faux:true});return _5f1.call(this,evt);});return {remove:function(){_5f2.remove();_5f4.remove();}};};}else{if(has("opera")){_5e9=function(_5f5,_5f6){return on(_5f5,"keypress",function(evt){var c=evt.which;if(c==3){c=99;}c=c<32&&!evt.shiftKey?0:c;if(evt.ctrlKey&&!evt.shiftKey&&c>=65&&c<=90){c+=32;}return _5f6.call(this,_5ec(evt,{charCode:c}));});};}else{_5e9=function(_5f7,_5f8){return on(_5f7,"keypress",function(evt){_5ee(evt);return _5f8.call(this,evt);});};}}var _5f9={_keypress:_5e9,connect:function(obj,_5fa,_5fb,_5fc,_5fd){var a=arguments,args=[],i=0;args.push(typeof a[0]=="string"?null:a[i++],a[i++]);var a1=a[i+1];args.push(typeof a1=="string"||typeof a1=="function"?a[i++]:null,a[i++]);for(var l=a.length;i<l;i++){args.push(a[i]);}return _5e4.apply(this,args);},disconnect:function(_5fe){if(_5fe){_5fe.remove();}},subscribe:function(_5ff,_600,_601){return hub.subscribe(_5ff,lang.hitch(_600,_601));},publish:function(_602,args){return hub.publish.apply(hub,[_602].concat(args));},connectPublisher:function(_603,obj,_604){var pf=function(){_5f9.publish(_603,arguments);};return _604?_5f9.connect(obj,_604,pf):_5f9.connect(obj,pf);},isCopyKey:function(e){return e[_5eb];}};_5f9.unsubscribe=_5f9.disconnect;1&&lang.mixin(dojo,_5f9);return _5f9;});},"dojo/errors/CancelError":function(){define(["./create"],function(_605){return _605("CancelError",null,null,{dojoType:"cancel"});});}}});(function(){var _606=this.require;_606({cache:{}});!_606.async&&_606(["dojo"]);_606.boot&&_606.apply(null,_606.boot);})();
\ No newline at end of file
--- a/server/src/main/webapp/js/main_coweb.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-//
-// Cooperative web application template.
-//
-// Copyright (c) The Dojo Foundation 2011. All Rights Reserved.
-//
-
-// assumes admin servlet deployed with the application
-var cowebConfig = {
- adminUrl : './admin'
-};
-
-require({moduleUrl : 'lib'},
- ['coweb/main','dojo'],
-function(coweb, dojo) {
- // do application setup here
-
- dojo.ready(function() {
- // on page load, prepare, join, and update in a session
- var sess = coweb.initSession();
- sess.prepare();
- this.collab = coweb.initCollab({id:'renkan'});
- });
-});
-
--- a/server/src/main/webapp/js/models.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-(function() {
-
- var root = this;
-
- var Backbone = root.Backbone;
-
- var Models = root.Rkns.Models = {};
-
-
- Models.getUID = function(obj) {
- var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
- return v.toString(16);
- });
- return obj.type + "-" + guid;
- };
-
-
- var RenkanModel = Backbone.RelationalModel.extend({
- idAttribute : "_id",
- constructor: function(options) {
-
- if (typeof options !== "undefined") {
- options._id = options.id || Models.getUID(this);
- options.title = options.title || "(untitled " + this.type + ")";
- options.description = options.description || "";
- options.uri = options.uri || "";
-
- if(typeof this.prepare === "function") {
- options = this.prepare(options);
- }
- }
- Backbone.RelationalModel.prototype.constructor.call(this, options);
- },
- validate: function() {
- if(!this.type) {
- return "object has no type";
- }
- },
- addReference : function(_options, _propName, _list, _id, _default) {
- var _element = _list.get(_id);
- if (typeof _element === "undefined" && typeof _default !== "undefined") {
- _options[_propName ] = _default;
- }
- else {
- _options[_propName ] = _element;
- }
- }
- });
-
-
- // USER
- var User = Models.User = root.Rkns.Models.User = RenkanModel.extend({
- type: "user",
- prepare: function(options) {
- options.color = options.color || "#666666";
- return options;
- }
-
- });
-
- // NODE
- var Node = Models.Node = root.Rkns.Models.Node = RenkanModel.extend({
- type: "node",
- relations: [{
- type: Backbone.HasOne,
- key: "created_by",
- relatedModel: User
- }],
- prepare: function(options) {
- project = options.project;
- this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
- options.description = options.description || "";
- return options;
- }
-
- });
-
- // EDGE
- var Edge = Models.Edge = root.Rkns.Models.Edge = RenkanModel.extend({
- type: "edge",
- relations: [
- {
- type: Backbone.HasOne,
- key: "created_by",
- relatedModel: User
- },
- {
- type: Backbone.HasOne,
- key: "from",
- relatedModel: Node
- },
- {
- type: Backbone.HasOne,
- key: "to",
- relatedModel: Node
- },
- ],
- prepare: function(options) {
- project = options.project;
- this.addReference(options, "created_by", options.created_by, project.get("users"), project.current_user);
- this.addReference(options, "from", options.from, project.get("nodes"));
- this.addReference(options, "to", options.to, project.get("nodes"));
- return options;
- }
- });
-
- // PROJECT
- var Project = Models.Project = root.Rkns.Models.Project = RenkanModel.extend({
- type: "project",
- relations: [
- {
- type: Backbone.HasMany,
- key: "users",
- relatedModel: User,
- reverseRelation: {
- key: 'project',
- includeInJSON: '_id'
- },
- },
- {
- type: Backbone.HasMany,
- key: "nodes",
- relatedModel: Node,
- reverseRelation: {
- key: 'project',
- includeInJSON: '_id'
- },
- },
- {
- type: Backbone.HasMany,
- key: "edges",
- relatedModel: Edge,
- reverseRelation: {
- key: 'project',
- includeInJSON: '_id'
- },
- }
- ],
- addNode: function(_props) {
- _props.project = this;
- this.get("nodes").push(_props);
- }
- });
-
-
-}).call(this);
-
--- a/server/src/main/webapp/js/underscore.js Fri Dec 21 16:22:08 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-// Underscore.js 1.3.3
-// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
-c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
-g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,
-c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&&
-a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
-c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
-a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
-function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&
-(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
-j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,
-0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,
-e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
-i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<=
-1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=
-i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=
-g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));
-return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
-c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
-function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
-b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
-b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
-function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
-u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
-b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
-this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/model-test.html Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,340 @@
+<!doctype html>
+<html class="no-js" lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+
+ <title>Test Model Renkan</title>
+ <meta name="description" content="">
+ <meta name="author" content="">
+
+ <meta name="viewport" content="width=device-width">
+
+ <link rel="stylesheet" href="css/style.css">
+
+ <script type="text/javascript" src="js/config.js"></script>
+ <script type="text/javascript" src="js/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+ <script src="lib/jquery.min.js"></script>
+ <script src="lib/underscore-min.js"></script>
+ <script src="js/backbone.js"></script>
+ <script src="js/backbone-relational.js"></script>
+ <script src="js/main_test_models.js"></script>
+ <script src="js/models.js"></script>
+ <script type="text/javascript" src="js/config.js"></script>
+ <script data-main="main" src="js/main_coweb.js"></script>
+ <script type="text/javascript">
+
+ function set_project(project) {
+
+ require(["dojo/dom", "dojo/on", "corenkan"], function(dom, on, corenkan) {
+
+ var template_html = dom.byId("project_disp_template").innerHTML;
+ var el = dom.byId("project_display");
+
+
+ var project_form_view = new FormView({el: dom.byId("form_display"), model: project, template: dom.byId("project_form_template").innerHTML});
+
+ project_view = new ModelView({
+ el:el,
+ model: project,
+ template: template_html,
+ form_view: project_form_view,
+ form_el : dom.byId("form_display_div")
+ });
+
+ var user_list_view = new ColView({
+ el: dom.byId("users_list_base"),
+ collection: project.get("users"),
+ element: {
+ template: dom.byId("user_disp_template").innerHTML
+ },
+ element_form: {
+ tagName: "div",
+ attributes: {
+ id:"form_display",
+ },
+ template: dom.byId("user_form_template").innerHTML
+ },
+ element_form_el : dom.byId("form_display_div")
+ });
+
+ var node_list_view = new ColView({
+ el: dom.byId("nodes_list_base"),
+ collection: project.get("nodes"),
+ element: {
+ template: dom.byId("node_disp_template").innerHTML
+ },
+ element_form: {
+ tagName: "div",
+ attributes: {
+ id:"form_display",
+ },
+ template: dom.byId("node_form_template").innerHTML
+ },
+ element_form_el : dom.byId("form_display_div")
+ });
+
+ var current_user_view = new CurrentUserView({
+ el: dom.byId("users_select"),
+ model: project
+ })
+
+ project_view.render();
+ user_list_view.render();
+ node_list_view.render();
+ current_user_view.render();
+
+ on(dom.byId("add_user"), "click", function() {
+ project.get("users").push(new Rkns.Models.User({}));
+ });
+ on(dom.byId("add_node"), "click", function() {
+ project.get("nodes").push(new Rkns.Models.Node({project: project}));
+ });
+
+ on(dom.byId("users_select"), "change", function(evt) {
+ var val = evt.currentTarget.value;
+ var current_user = null;
+ if(typeof val !== "undefined" && val != "") {
+ current_user = project.get("users").get(val);
+ }
+
+ if(current_user != null) {
+ project.current_user = current_user;
+ dom.byId("current_user").innerHTML = current_user.get("title");
+ }
+ else {
+ project.current_user = null;
+ dom.byId("current_user").innerHTML = "";
+ }
+
+ });
+
+ project.get("users").on("change", function(evt) {
+ if(project.current_user == null) {
+ dom.byId("current_user").innerHTML = "";
+ }
+ else if(evt.id == project.current_user.id) {
+ dom.byId("current_user").innerHTML = project.current_user.get("title");
+ }
+ });
+
+ project.get("users").on("remove", function(evt) {
+ if(typeof project.current_user === "undefined" || project.current_user == null || evt.id == project.current_user.id) {
+ dom.byId("current_user").innerHTML = "";
+ }
+ });
+
+ corenkan.app.setProject(project);
+ });
+ }
+
+ function load_project(project_id) {
+ var project = null;
+
+ if(project_id) {
+ project = new Rkns.Models.Project({_id: project_id});
+ }
+ else {
+ project = new Rkns.Models.Project({});
+ }
+ project.urlRoot = "rest/projects";
+
+ if(project_id) {
+ project.fetch({
+ success: function(project, resp) {
+ set_project(project);
+ }
+ });
+ }
+ else {
+ set_project(project);
+ }
+
+ return project;
+ }
+
+ var current_project = null;
+
+ require(["dojo/dom", "dojo/on", "dojo/domReady!"], function(dom, on) {
+
+ var project_list_item_view = BasicModelView.extend({template: _.template(dom.byId("project_list_item_template").innerHTML), tagName: "li"});
+
+ var project_list_col = new (Backbone.Collection.extend({model: Rkns.Models.Project.extend({idAttribute:'_id', urlRoot:'rest/projects'})}))();
+ project_list_col.url = "rest/projects";
+ project_list_col.on("all", function(){
+ if(!project_list_view) {
+ return;
+ }
+ _(project_list_view.element_views).each(function(ev){
+ if(ev.model.id === current_project.id) {
+ $(".project_load_button",ev.el).attr('disabled','disabled');
+ $(".project_delete_button",ev.el).attr('disabled','disabled');
+ }
+ else {
+ $(".project_load_button",ev.el).removeAttr('disabled');
+ $(".project_delete_button",ev.el).removeAttr('disabled');
+ }
+ });
+ });
+
+ var project_list_view = null;
+
+ project_list_col.fetch({
+ success:function(collection, response) {
+ project_list_view = new (BasicListView.extend({events: {
+ "click .project_load_button" : function(evt) {
+ var proj_id = $(evt.target).val();
+ if(current_project && current_project.id == proj_id) {
+ return;
+ }
+ current_project = load_project($(evt.target).val());
+ project_list_col.trigger("sync");
+ },
+ "click .project_delete_button": function(evt) {
+ var delete_id = $(evt.target).val();
+ if(!current_project || delete_id != current_project.id) {
+ _(project_list_col.where({_id: delete_id})).each(function(proj) {
+ proj.destroy();
+ });
+ }
+ }
+ }}))({collection: collection, element_view_constructor: project_list_item_view, el: dom.byId("project_list")});
+ project_list_view.render();
+ }
+ });
+
+ on(dom.byId("project_save_button"), "click", function(evt){
+ if(current_project) {
+ current_project.save({}, {success: function(model, response) {
+ if(project_list_view != null) {
+ project_list_col.fetch({
+ success:function(collection, response) {
+ project_list_view.render();
+ }
+ });
+ }
+ }});
+ }
+ });
+
+ on(dom.byId("new_project_button"), "click", function(evt) {
+ current_project = load_project();
+ });
+
+ });
+ </script>
+</head>
+<body>
+<header>
+</header>
+
+<div>
+<div class="project_current_user"><span class="project_label project_user_label">User: </span><span id="current_user"></span></div>
+<select id="users_select">
+ <option value="">None</option>
+</select>
+</div>
+
+<button type="button" id="new_project_button">New Project</button>
+
+<div id="project_list_div">
+<ul id="project_list">
+</ul>
+</div>
+
+<div role="main" id="project_display">
+</div>
+<button type="button" id="project_save_button" value="save">Save</button>
+
+<div id="users_list_div">
+ <button id="add_user">Add user</button>
+ <ul id="users_list_base">
+ </ul>
+</div>
+
+<div id="nodes_list_div">
+ <button id="add_node">Add node</button>
+ <ul id="nodes_list_base">
+ </ul>
+</div>
+
+
+<div id="form_display_div">
+</div>
+
+<footer>
+</footer>
+
+<script type="text/template" id="current_user_template">
+</script>
+
+<script type="text/template" id="project_disp_template">
+ <div class="show_form">
+ <h2 class="project_title">Project <%= _id %>: <%= title %></h2>
+ <div class="project_desc"><span class="project_label project_desc_label">Desc: </span><%= description %></div>
+ <div class="project_uri"><span class="project_label project_uri_label">Uri: </span><%= uri %></div>
+ </div>
+</script>
+<script type="text/template" id="project_form_template">
+ <table class="project_form">
+ <thead>
+ <tr><th>Field</th><th>Value</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>Title:</td><td><input type="text" name="title" id="project_form_title" class="form_field" value="<%= title %>"></input></td></tr>
+ <tr><td>Uri :</td><td><input type="text" name="uri" id="project_form_text" class="form_field" value="<%= uri %>"></input></td></tr>
+ <tr><td>Desc :</td><td><textarea name="description" id="project_form_description" class="form_field"><%= description %></textarea></td></tr>
+ </tbody>
+ </table>
+</script>
+<script type="text/template" id="user_disp_template">
+ <div class="show_form">
+ <h2 class="user_title">User <%= _id %>: <%= title %></h2>
+ <div class="user_desc"><span class="user_label user_desc_label">Desc: </span><%= description %></div>
+ <div class="user_uri"><span class="user_label user_uri_label">Uri: </span><%= uri %></div>
+ <div class="user_color"><span class="user_label user_color_label">Color: </span><%= color %></div>
+ </div>
+ <button type="button" class="remove_button" value="<%= _id %>">Remove<button>
+</script>
+<script type="text/template" id="user_form_template">
+ <table class="user_form">
+ <thead>
+ <tr><th>Field</th><th>Value</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>Title:</td><td><input type="text" name="title" class="form_field" value="<%= title %>"></input></td></tr>
+ <tr><td>Uri :</td><td><input type="text" name="uri" class="form_field" value="<%= uri %>"></input></td></tr>
+ <tr><td>Color :</td><td><input type="text" name="color" class="form_field" value="<%= color %>"></input></td></tr>
+ <tr><td>Desc :</td><td><textarea name="description" class="form_field"><%= description %></textarea></td></tr>
+ </tbody>
+ </table>
+</script>
+<script type="text/template" id="node_disp_template">
+ <div class="show_form">
+ <h2 class="user_title">Node <%= _id %>: <%= title %></h2>
+ <div class="user_desc"><span class="user_label user_desc_label">Desc: </span><%= description %></div>
+ <div class="user_uri"><span class="user_label user_uri_label">Uri: </span><%= uri %></div>
+ <div class="user_creator"><span class="user_label user_uri_label">Creator: </span><%= created_by.title %></div>
+ </div>
+ <button type="button" class="remove_button" value="<%= _id %>">Remove<button>
+</script>
+<script type="text/template" id="node_form_template">
+ <table class="node_form">
+ <thead>
+ <tr><th>Field</th><th>Value</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>Node title:</td><td><input type="text" name="title" class="form_field" value="<%= title %>"></input></td></tr>
+ <tr><td>Node uri :</td><td><input type="text" name="uri" class="form_field" value="<%= uri %>"></input></td></tr>
+ <tr><td>Node creator :</td><td><input type="text" name="created_by" class="form_field" value="<%= created_by.title %>" readonly="readonly"></input></td></tr>
+ <tr><td>Node desc :</td><td><textarea name="description" class="form_field"><%= description %></textarea></td></tr>
+ </tbody>
+ </table>
+</script>
+<script type="text/template" id="project_list_item_template">
+ <span class="title"><%= title %></span> <button type="button" class="project_load_button" value="<%= _id %>">Load</button><button type="button" class="project_delete_button" value="<%= _id %>">Delete</button>
+</script>
+
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/css/index.css Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,107 @@
+ body {
+ margin: 0;
+ height: 100%;
+ color: #333;
+ font: 14px helvetica, sans-serif;
+ background: #ddd;
+ background: -webkit-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ background: -moz-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ background: -ms-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ background: -o-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+ border-top: 8px solid rgba(51,51,51,.8);
+ }
+ #wrapper {
+ border-top: 1px solid #999;
+ margin-top: 160px;
+ padding: 15px;
+ background: #eee;
+ background: -webkit-linear-gradient(#fff,#ccc);
+ background: -moz-linear-gradient(#fff,#ccc);
+ background: -ms-linear-gradient(#fff,#ccc);
+ background: -o-linear-gradient(#fff,#ccc);
+ opacity: .9;
+ box-shadow: 0px 1px 8px rgba(0,0,0,0.3);
+ }
+ #inner {
+ width: 300px;
+ margin: 0 auto;
+ }
+ #button {
+ margin: 0 auto;
+ border-radius: 3px;
+ text-align: center;
+ font: 36px verdana,arial,sans-serif;
+ color: white;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.8);
+ height: 70px;
+ line-height: 70px;
+ background: #555;
+ background: -webkit-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ background: -moz-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ background: -ms-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ background: -o-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.9);
+ }
+ #button:hover {
+ cursor: pointer;
+ background: #666;
+ background: -webkit-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ background: -moz-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ background: -ms-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ background: -o-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+ }
+ #button:active {
+ box-shadow: inset 0 1px 12px rgba(0,0,0,0.9);
+ background: #444;
+ }
+ #label {
+ text-align: left;
+ text-shadow: 0 1px 1px #fff;
+ margin: 16px auto 0;
+ }
+ form {
+ height: 38px;
+ background: #fff;
+ border: 1px solid #bbb;
+ border-radius: 3px;
+ position: relative;
+ }
+ button, input {
+ font-weight: bold;
+ font-size: 15px;
+ }
+ input[type="text"] {
+ border-radius: 3px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ padding: 0 45px 0 10px;
+ *padding: 0; /* IE7 hack */
+ width: 100%;
+ height: 100%;
+ outline: none;
+ border: none;
+ position: absolute;
+ }
+ button[type="submit"] {
+ position: absolute;
+ right: 0;
+ width: 45px;
+ height: 38px;
+ }
+ @media only screen and (min-device-width: 320px) and (max-device-width: 720px) {
+ body {
+ background: #bbb;
+ background: -webkit-linear-gradient(#aaa,#eee 60%) center fixed;
+ background: -moz-linear-gradient(#aaa,#eee 60%) center fixed;
+ background: -ms-linear-gradient(#aaa,#eee 60%) center fixed;
+ }
+ #wrapper {
+ margin-top: 0;
+ }
+ #inner {
+ width: 95%;
+ }
+ #label {
+ text-align: center;
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/css/renkan-publish.css Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,134 @@
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+ul, li {
+ list-style: none;
+}
+
+input::-moz-focus-inner /*Remove button padding in FF*/
+{
+ border: 0;
+ padding: 0;
+}
+
+table {
+ border-collapse: separate; border-spacing: 0;
+}
+
+th, td {
+ vertical-align: top;
+}
+
+img a {
+ border: none;
+}
+
+body {
+ font-size: 10px; font-family: Arial, Helvetica, sans-serif;
+ background: #ffffff; color: #000000;
+}
+
+a {
+ color: #303080;
+}
+
+.Rk-ProjectList {
+ position: absolute; left: 0; top: 0; list-style: none; padding: 0; margin: 0;
+}
+
+.Rk-Project {
+ list-style: none; margin-right: 5px; padding: 5px; height: 15px; font-size: 13px; font-weight: bold;
+ float: left; border-top-left-radius: 8px; border-top-right-radius: 8px;
+ background: #505050; color: #E0E0E0; cursor: pointer;
+ background: -moz-linear-gradient(top, #333333 20%, #666666 80%);
+}
+
+.Rk-Project:hover {
+ background: -moz-linear-gradient(bottom, #333333 20%, #666666 80%);
+}
+
+.Rk-Project.active {
+ background: #505080;
+ color: #ffffc0;
+ background: -moz-linear-gradient(bottom, #333366 20%, #666699 80%);
+}
+
+.Rk-Render {
+ position: absolute; left: 0; top: 25px; right: 0; bottom: 0;
+ background: -moz-linear-gradient(top, rgba(180,180,180,.2) 0, rgba(255,255,255,.2) 30%, rgba(255,255,255,.2) 70%, rgba(180,180,180,.2) 100%);
+}
+
+.Rk-Canvas {
+ background: -moz-linear-gradient(left, rgba(180,180,180,.2) 0, rgba(255,255,255,.2) 30%, rgba(255,255,255,.2) 70%, rgba(180,180,180,.2) 100%);
+ position: absolute; left: 0; top: 0; right: 0; bottom: 0;
+}
+
+.Rk-Editor {
+ position: absolute; left: 0; top: 0;
+}
+
+.Rk-CloseX {
+ float: right; cursor: pointer;
+}
+
+.Rk-Editor h2 {
+ font-size: 14px; font-weight: bold;
+}
+
+.Rk-Editor p {
+ margin: 5px 0; font-size: 11px;
+}
+
+.Rk-RelatedList {
+ list-style: none;
+}
+
+.Rk-Related {
+ color: #a000c0; cursor: pointer; margin: 5px 0;
+}
+
+.Rk-Related b {
+ font-weight: bolder;
+}
+
+.Rk-Related:hover {
+ text-decoration: underline;
+}
+
+.Rk-ZoomButtons {
+ position: absolute; left: 0; top: 0; cursor: pointer;
+}
+
+.Rk-ZoomIn, .Rk-ZoomOut {
+ width: 21px; height: 20px; background: url(../img/zoombuttons.png); margin: 5px;
+}
+
+.Rk-ZoomIn:hover {
+ background-position: 0 -20px;
+}
+
+.Rk-ZoomOut {
+ background-position: -21px 0;
+}
+
+.Rk-ZoomOut:hover {
+ background-position: -21px -20px;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/css/renkan.css Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,468 @@
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+ul, li {
+ list-style: none;
+}
+
+input::-moz-focus-inner /*Remove button padding in FF*/
+{
+ border: 0;
+ padding: 0;
+}
+
+table {
+ border-collapse: separate; border-spacing: 0;
+}
+
+th, td {
+ vertical-align: top;
+}
+
+img a {
+ border: none;
+}
+
+body {
+ font-size: 10px; font-family: Arial, Helvetica, sans-serif;
+ background: #ffffff; color: #000000;
+}
+
+a {
+ color: #6060c0;
+}
+
+.Rk-Main {
+ position: absolute; left: 0; top: 0; right: 0; bottom: 0;
+}
+
+.Rk-Render {
+ position: absolute; left: 300px; top: 0; right: 0; bottom: 0;
+ background: #ffffff;
+ background: -moz-linear-gradient(left, #f3f3f3 0, #ffffff 30%, #ffffff 70%, #f3f3f3 100%);
+ background: -webkit-linear-gradient(left, #f3f3f3 0, #ffffff 30%, #ffffff 70%, #f3f3f3 100%);
+}
+
+/* Top Bar */
+
+.Rk-TopBar {
+ position: absolute; left: 0; top: 0; right: 0; height: 35px;
+ background: #333333;
+ background: -moz-linear-gradient(top, #505050 5px, #1e1e1e 30px);
+ background: -webkit-linear-gradient(top, #505050 5px, #1e1e1e 30px);
+}
+
+.Rk-PadTitle {
+ float: left; font-size: 14px; height: 16px; margin: 4px 5px; width: 130px; background: #666666; padding: 4px; border: 1px solid #333333;
+ border-radius: 3px; box-shadow: 0 1px 0 #505050; color: #ffffff; font-weight: bold;
+}
+
+.Rk-Users {
+ float: right; width: 130px; margin: 4px 5px;
+}
+
+.Rk-CurrentUser {
+ font-size: 13px; background: #666666; padding: 4px; border: 1px solid #333333; border-radius: 3px; box-shadow: 0 1px 0 #505050; color: #ffffff;
+}
+
+.Rk-CurrentUser-Color {
+ display: inline-block; width: 12px; height: 12px; border: 1px solid #333333; margin: -2px 2px;
+}
+
+.Rk-UserList {
+ box-shadow: 0 2px 2px #999999;
+ position: relative; z-index: 3; display: none; padding-top: 8px;
+}
+
+.Rk-User {
+ background: #ffffff; padding: 3px; font-size: 12px; border-style: solid solid none; border-color: #cccccc; border-width: 1px;
+}
+
+.Rk-TopBar-Button {
+ float: right; background: url(../img/topbarbuttons.png) no-repeat; height: 35px; cursor: pointer;
+ position: relative;
+}
+
+.Rk-TopBar-Separator {
+ background: #666666;
+ background: -moz-linear-gradient(top, #666666 20%, #333333 80%);
+ background: -webkit-linear-gradient(top, #666666 20%, #333333 80%);
+ content: ""; display: block; height: 35px; float: right; width: 1px; border-left: 1px solid #111111;
+ margin: 0 3px;
+}
+
+.Rk-TopBar-Tooltip {
+ position: absolute; top: 31px; left: 50%; margin-left: -60px; width: 120px; z-index: 3; display: none;
+}
+
+.Rk-TopBar-Tooltip-Contents {
+ background: #ffffff;
+ font-size: 13px; font-weight: bold; color: #6060c0; text-align: center; padding: 2px;
+ border-style: none solid solid; border-width: 1px; border-color: #cccccc; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;
+}
+
+.Rk-TopBar-Tooltip-Tip {
+ height: 7px; background: url(../img/tooltiparrow.png) center no-repeat; margin: 0 1px;
+}
+
+.Rk-AddNode-Button {
+ width: 34px;
+}
+
+.Rk-AddNode-Button:hover {
+ background-position: 0 -35px;
+}
+
+.Rk-FullScreen-Button {
+ width: 34px; background-position: -34px 0;
+}
+
+.Rk-FullScreen-Button:hover {
+ background-position: -34px -35px;
+}
+
+.Rk-AddEdge-Button {
+ width: 34px; background-position: -68px 0;
+}
+
+.Rk-AddEdge-Button:hover {
+ background-position: -68px -35px;
+}
+/* Canvas */
+
+.Rk-Canvas {
+ background: -moz-linear-gradient(top, rgba(180,180,180,.2) 0, rgba(255,255,255,.2) 30%, rgba(255,255,255,.2) 70%, rgba(180,180,180,.2) 100%);
+ background: -webkit-linear-gradient(top, rgba(180,180,180,.2) 0, rgba(255,255,255,.2) 30%, rgba(255,255,255,.2) 70%, rgba(180,180,180,.2) 100%);
+ position: absolute; left: 0; top: 35px; right: 0; bottom: 0; z-index: 1;
+}
+
+/* Editors */
+
+.Rk-Editor {
+ position: absolute; left: 0; top: 35px; right: 0; z-index: 2;
+}
+
+.Rk-Notifications {
+ position: absolute; right: 15px; top: 15px; width: 200px;
+ padding: 10px; border-radius: 8px; display: none;
+ color: #ffffff; font-size: 13px; text-align: center; font-weight: bold;
+ background: rgba(20,20,20,.7);
+ background: -moz-linear-gradient(top, rgba(40,40,40,.7) 20%, rgba(0,0,0,.7) 80%);
+ background: -webkit-linear-gradient(top, rgba(40,40,40,.7) 20%, rgba(0,0,0,.7) 80%);
+}
+
+.Rk-CloseX {
+ float: right; cursor: pointer;
+}
+
+.Rk-Editor h2 {
+ font-size: 16px; font-weight: bold;
+}
+
+.Rk-Editor p {
+ margin: 5px 0; font-size: 12px;
+}
+
+.Rk-Editor label {
+ display: inline-block; width: 70px;
+}
+
+a.Rk-Edit-Goto {
+ display: block; float: right; width: 18px; height: 17px; margin: 1px 0; border: none; background: url(../img/goto.png);
+}
+
+.Rk-Edit-Title, .Rk-Edit-URI, .Rk-Edit-Image {
+ font-size: 12px; width: 225px;
+}
+
+.Rk-Edit-URI {
+ font-size: 12px; width: 205px;
+}
+
+.Rk-Edit-ImgPreview {
+ border: 1px solid #666; margin: 5px 0; min-height: 10px; display: block;
+ max-width: 100% !important; max-height: 100px !important;
+}
+
+.Rk-Editor textarea {
+ width: 225px; height: 120px; resize: none;
+}
+
+.Rk-UserColor {
+ display: inline-block; width: 1em; height: 1em; border: 1px solid #666666; margin: -2px 2px;
+}
+
+.Rk-ZoomButtons {
+ position: absolute; left: 0; top: 0; cursor: pointer;
+}
+
+.Rk-ZoomIn, .Rk-ZoomOut {
+ width: 21px; height: 20px; background: url(../img/zoombuttons.png); margin: 5px;
+}
+
+.Rk-ZoomIn:hover {
+ background-position: 0 -20px;
+}
+
+.Rk-ZoomOut {
+ background-position: -21px 0;
+}
+
+.Rk-ZoomOut:hover {
+ background-position: -21px -20px;
+}
+
+/* Bins */
+
+.Rk-Title {
+ position: absolute; left: 0; top: 0; width: 300px; height: 35px;
+ background: #333333;
+ background: -moz-linear-gradient(top, #505050 5px, #1e1e1e 30px);
+ background: -webkit-linear-gradient(top, #505050 5px, #1e1e1e 30px);
+}
+
+.Rk-Title h1 {
+ font-size: 18px; color: #ffffff; margin: 5px;
+}
+
+
+.Rk-Title:after {
+ background: #666666;
+ background: -moz-linear-gradient(top, #666666 20%, #333333 80%);
+ background: -webkit-linear-gradient(top, #666666 20%, #333333 80%);
+ content: ""; display: block; height: 35px;
+ left: 298px; position: absolute; top: 0; width: 1px; border-left: 1px solid #111111;
+}
+
+.Rk-Bins {
+ background: #ffffff; position: absolute; left: 0; top: 35px; width: 299px; bottom: 0;
+ overflow: hidden; border-right: 1px solid #252525;
+}
+
+/* Bin Search Field */
+
+.Rk-Search-Form {
+ padding: 10px; height: 27px;
+ background: #666666;
+ background: -moz-linear-gradient(top, #606060 20%, #909090 80%);
+ background: -webkit-linear-gradient(top, #606060 20%, #909090 80%);
+}
+
+.Rk-Search-Input, .Rk-Search-Select {
+ float: left; border-width: 1px; border-color: #003050;
+}
+
+.Rk-Search-Input {
+ border-top-left-radius: 5px; border-bottom-left-radius: 5px; border-style: solid;
+ font-size: 13px; width: 190px; background: #ffffff; height: 15px; padding: 5px;
+}
+
+.Rk-Search-Select {
+ display: inline-block; position: relative; width: 45px;
+ border-style: solid none; cursor: pointer;
+ height: 25px; background: #ffffff url(../img/more.png) 30px 10px no-repeat;
+}
+
+.Rk-Search-Select:hover {
+ background-color: #3030FF;
+}
+
+.Rk-Search-Current {
+ width: 40px; height: 20px; margin: 2px; background-repeat: no-repeat;
+}
+
+.Rk-Search-List {
+ width: 180px; margin-left: 15px; font-size: 13px;
+ position: absolute; right: 0; top: 25px; background: #ffffff;
+ box-shadow: 1px 1px 2px #505050; display: none;
+ border: 1px solid #cccccc;
+}
+
+.Rk-Search-List li {
+ padding: 2px 2px 2px 30px; border-top: 1px solid #cccccc; height: 16px;
+ background-color: #ffffff; background-repeat: no-repeat; cursor: pointer;
+}
+
+.Rk-Search-List li:hover {
+ background-color: #3030ff; color: #ffffff;
+}
+
+.Rk-Search-Submit {
+ border: 1px solid #003050; height: 27px; width: 30px; border-top-right-radius: 5px; border-bottom-right-radius: 5px;
+ background: #333333 center no-repeat url(../img/search.png); cursor: pointer;
+}
+
+.Rk-Search-Submit:hover {
+ background-color: #999999;
+}
+
+/* Individual Bins */
+
+
+.Rk-Bin-Title {
+ background: #333333;
+ background: -moz-linear-gradient(top, #505050 20%, #1e1e1e 80%);
+ background: -webkit-linear-gradient(top, #505050 20%, #1e1e1e 80%);
+ border-bottom: 1px solid #666666; font-weight: bold;
+ font-size: 14px; padding: 5px 5px 5px 30px; cursor: pointer; color: #f0f0f0;
+}
+
+.Rk-Bin-Close {
+ float: right; display: block; font-size: 16px; font-weight: bold; margin: 2px 3px 0; color: #f0f0f0; cursor: pointer;
+ text-shadow: -1px -1px 1px #999999, 1px 1px 1px #000000; text-decoration: none;
+}
+
+.Rk-Bin-Close:hover {
+ color: #ffff80;
+}
+
+.Rk-Bin-Title:hover {
+ color: #ffffe0;
+ background: -moz-linear-gradient(top, rgb(20,20,20) 20%, rgb(60,60,60) 80%);
+ background: -webkit-linear-gradient(top, rgb(20,20,20) 20%, rgb(60,60,60) 80%);
+}
+
+.Rk-Bin-Refresh {
+ width: 18px; height: 17px; background: url(../img/refresh.png); display: block; float: right; margin-top: 4px;
+}
+
+.Rk-Bin-Refresh:hover {
+ background-position: -18px 0;
+}
+
+.Rk-Bin-Title-Icon {
+ float: left; width: 25px; margin: 2px;
+}
+
+.Rk-Bin-Main {
+ overflow: auto;
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #e0e0e0 0, #FFFFFF 2%, #FFFFFF 98%, #e0e0e0 100%);
+ background: -webkit-linear-gradient(top, #e0e0e0 0, #FFFFFF 2%, #FFFFFF 98%, #e0e0e0 100%);
+}
+
+.Rk-Bin-Item {
+ cursor: move;
+}
+
+.Rk-Bin-Item:hover {
+ background: -moz-linear-gradient(top, rgba(0,0,0,.1) 20%, rgba(128,128,128,.1) 80%);
+ background: -webkit-linear-gradient(top, rgba(0,0,0,.1) 20%, rgba(128,128,128,.1) 80%);
+}
+
+.Rk-Bin-Item.dragging {
+ background: -moz-linear-gradient(top, rgba(128,0,0,.1) 20%, rgba(255,128,128,.1) 80%);
+ background: -webkit-linear-gradient(top, rgba(128,0,0,.1) 20%, rgba(255,128,128,.1) 80%);
+ color: #660000;
+}
+
+.Rk-Bin-Item.selected {
+ background: #ffffc0;
+}
+
+.Rk-Bin-Main li {
+ padding: 2px; border-bottom: 1px solid #cccccc;
+ clear: both;
+}
+
+.Rk-Bin-Main h3 {
+ font-size: 14px; font-style: italic; font-weight: bold; text-align: center;
+}
+
+.Rk-Bin-Main h4 {
+ font-size: 12px; font-weight: bold;
+}
+
+.Rk-Bin-Main p {
+ font-size: 11px;
+}
+
+.Rk-Twitter-Icon {
+ background-image: url(../img/search-logos.png); background-position: 0 -80px;
+}
+
+.Rk-Twitter-Title-Icon {
+ height: 20px; background: url(../img/search-logos.png); background-position: 0 -80px;
+}
+
+.Rk-Twitter-TwImage {
+ float: left; width: 48px; height: 48px; margin: 2px 0;
+}
+
+.Rk-Twitter-TwTitle, .Rk-Twitter-TwDate, .Rk-Twitter-TwText, .Rk-Twitter-TwActions {
+ margin: 2px 0 2px 50px;
+}
+
+p.Rk-Twitter-TwDate {
+ font-size: 11px; font-style: italic;
+}
+
+p.Rk-Twitter-TwActions {
+ font-size: 11px;
+}
+
+.Rk-Bin-Main .searchmatch {
+ background: #ffff80;
+}
+
+.Rk-Wikipedia-Search-Icon {
+ background-image: url(../img/search-logos.png);
+}
+
+.Rk-Wikipedia-Icon {
+ float: left; margin: 3px;
+}
+
+.Rk-Wikipedia-Title-Icon {
+ height: 20px; background: url(../img/search-logos.png);
+}
+
+.Rk-Wikipedia-Lang-en {
+ background-position: 0 -20px;
+}
+
+.Rk-Wikipedia-Lang-fr {
+ background-position: 0 -40px;
+}
+
+.Rk-Wikipedia-Lang-ja {
+ background-position: 0 -60px;
+}
+
+.Rk-Wikipedia-Result {
+ min-height: 51px;
+}
+
+.Rk-Wikipedia-Result p, .Rk-Wikipedia-Result h4 {
+ margin-left: 54px;
+}
+
+.Rk-Ldt-Tag-Icon {
+ float: left; margin: 0 2px 0 0;
+}
+
+.Rk-Ldt-Annotation-Icon {
+ float: left; margin: 3px;
+}
+
+.Rk-Clear {
+ clear: both;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/css/style.css Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,130 @@
+/* =============================================================================
+ HTML5 Boilerplate CSS: h5bp.com/css
+ ========================================================================== */
+
+article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
+audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
+audio:not([controls]) { display: none; }
+[hidden] { display: none; }
+
+html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
+html, button, input, select, textarea { font-family: sans-serif; color: #222; }
+body { margin: 0; font-size: 1em; line-height: 1.4; }
+
+::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; }
+::selection { background: #fe57a1; color: #fff; text-shadow: none; }
+
+a { color: #00e; }
+a:visited { color: #551a8b; }
+a:hover { color: #06e; }
+a:focus { outline: thin dotted; }
+a:hover, a:active { outline: 0; }
+
+abbr[title] { border-bottom: 1px dotted; }
+b, strong { font-weight: bold; }
+blockquote { margin: 1em 40px; }
+dfn { font-style: italic; }
+hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
+ins { background: #ff9; color: #000; text-decoration: none; }
+mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
+pre, code, kbd, samp { font-family: monospace, serif; _font-family: 'courier new', monospace; font-size: 1em; }
+pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
+q { quotes: none; }
+q:before, q:after { content: ""; content: none; }
+small { font-size: 85%; }
+
+sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
+sup { top: -0.5em; }
+sub { bottom: -0.25em; }
+
+ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
+dd { margin: 0 0 0 40px; }
+nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
+
+img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
+
+svg:not(:root) { overflow: hidden; }
+
+figure { margin: 0; }
+
+form { margin: 0; }
+fieldset { border: 0; margin: 0; padding: 0; }
+label { cursor: pointer; }
+legend { border: 0; *margin-left: -7px; padding: 0; white-space: normal; }
+button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
+button, input { line-height: normal; }
+button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; *overflow: visible; }
+button[disabled], input[disabled] { cursor: default; }
+input[type="checkbox"], input[type="radio"] { box-sizing: border-box; padding: 0; *width: 13px; *height: 13px; }
+input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
+input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
+button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
+textarea { overflow: auto; vertical-align: top; resize: vertical; }
+input:valid, textarea:valid { }
+input:invalid, textarea:invalid { background-color: #f0dddd; }
+
+table { border-collapse: collapse; border-spacing: 0; }
+td { vertical-align: top; }
+
+.chromeframe { margin: 0.2em 0; background: #ccc; color: black; padding: 0.2em 0; }
+
+
+
+/* ===== Primary Styles ========================================================
+ Author:
+ ========================================================================== */
+.templates { display: none; }
+
+.project_desc_label { font-weight: bold; }
+
+#project_display {
+ background: #9cbc2c;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 20px;
+ width: 400px;
+}
+
+
+
+/* =============================================================================
+ Media Queries
+ ========================================================================== */
+
+@media only screen and (min-width: 35em) {
+ /* Style adjustments for viewports that meet the condition */
+}
+
+/* =============================================================================
+ Non-Semantic Helper Classes
+ ========================================================================== */
+
+.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; *line-height: 0; }
+.ir br { display: none; }
+.hidden { display: none !important; visibility: hidden; }
+.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
+.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
+.invisible { visibility: hidden; }
+.clearfix:before, .clearfix:after { content: ""; display: table; }
+.clearfix:after { clear: both; }
+.clearfix { *zoom: 1; }
+
+/* =============================================================================
+ Print Styles
+ ========================================================================== */
+
+@media print {
+ * { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */
+ a, a:visited { text-decoration: underline; }
+ a[href]:after { content: " (" attr(href) ")"; }
+ abbr[title]:after { content: " (" attr(title) ")"; }
+ .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */
+ pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
+ thead { display: table-header-group; } /* h5bp.com/t */
+ tr, img { page-break-inside: avoid; }
+ img { max-width: 100% !important; }
+ @page { margin: 0.5cm; }
+ p, h2, h3 { orphans: 3; widows: 3; }
+ h2, h3 { page-break-after: avoid; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/data/simple-persist.php Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,14 @@
+<?php
+ header('Content-Type: application/json; charset=utf-8');
+ $file = "dynamic-data.json";
+ if (isset($_GET['reset']) && $_GET['reset']) {
+ $resetfile = "test-data.json";
+ file_put_contents($file, file_get_contents($resetfile));
+ }
+ if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
+ file_put_contents($file, file_get_contents("php://input"));
+ echo json_encode(array("result" => "OK"));
+ } else {
+ echo file_get_contents($file);
+ }
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/data/test-data.json Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,298 @@
+{
+ "users": [
+ {
+ "_id": "u-anonymous",
+ "title": "anonymous",
+ "uri": "",
+ "description": "",
+ "color": "#dd00dd"
+ }, {
+ "_id": "u-cybunk",
+ "title": "Samuel",
+ "uri": "http://twitter.com/cybunk",
+ "description": "",
+ "color": "#e00000"
+ }, {
+ "_id": "u-raphv",
+ "title": "Raphael",
+ "uri": "http://twitter.com/raphv",
+ "description": "",
+ "color": "#00a000"
+ }
+ ],
+ "nodes": [
+ {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-0001",
+ "title": "Chocs technologiques et tâches de l’université...",
+ "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/e328e188-ff2f-11e0-b9e1-00145ea49a02/#id=s_6C326EED-B91A-AEDF-032D-40D9A60AAD7E",
+ "description": "Bernard Stiegler:\nChocs technologiques et tâches de l’université. L'époque des digital studies\nベルナール・スティグレールによるプレゼンテーション『テクノロジーの衝撃と大学の諸課題――デジタル・スタディーズの時代』 (langue française フランス語)",
+ "position": {
+ "x": 35.50145330596697,
+ "y": -79.8809523809524
+ },
+ "image": "http://www.iri.centrepompidou.fr/dev/~veltr/hitachi-tests/img/ldt-segment.png",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-0002",
+ "title": "Wiki: ベルナール・スティグレール",
+ "uri": "http://ja.wikipedia.org/wiki/%E3%83%99%E3%83%AB%E3%83%8A%E3%83%BC%E3%83%AB%E3%83%BB%E3%82%B9%E3%83%86%E3%82%A3%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%AB",
+ "description": "|image_name = Bernard-Stiegler.jpg\n'''ベルナール・スティグレール'''('''Bernard Stiegler''',[[1952年]][[4月1日]] - )は、[[フランス]]の[[哲学者]]。\n",
+ "position": {
+ "x": -212.89325104742056,
+ "y": -142.05921029473706
+ },
+ "image": "http://www.iri.centrepompidou.fr/dev/~veltr/hitachi-tests/img/wikipedia.png",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-0003",
+ "title": "Wiki: Bernard Stiegler",
+ "uri": "http://fr.wikipedia.org/wiki/Bernard_Stiegler",
+ "description": "Bernard Stiegler, né le 1 | avril | 1952, est un philosophe français qui axe sa réflexion sur les enjeux des mutations actuelles — ... ",
+ "position": {
+ "x": -199.613212880364,
+ "y": -297.6715155910511
+ },
+ "image": "http://www.iri.centrepompidou.fr/dev/~veltr/hitachi-tests/img/wikipedia.png",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-0004",
+ "title": "Tag: Stiegler",
+ "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/search/?search=Stiegler&field=all",
+ "description": "Tag 'Stiegler'",
+ "position": {
+ "x": -68.40773762286169,
+ "y": -205.76155213199334
+ },
+ "image": "http://www.iri.centrepompidou.fr/dev/~veltr/hitachi-tests/img/ldt-tag.png",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-0009",
+ "title": "Wiki: Humanités numériques",
+ "uri": "http://fr.wikipedia.org/wiki/Humanit%C3%A9s_num%C3%A9riques",
+ "description": "une proposition de définition a été élaborée lors du THATCamp des 18 et 19 mai 2010 sous la forme d'un « Manifeste des digital humanities : ... ",
+ "position": {
+ "x": -227.84295519248332,
+ "y": 91.1816115015538
+ },
+ "image": "http://www.iri.centrepompidou.fr/dev/~veltr/hitachi-tests/img/wikipedia.png",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-000a",
+ "title": "Wiki: デジタル・ヒューマニティーズ",
+ "uri": "http://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E3%83%BB%E3%83%92%E3%83%A5%E3%83%BC%E3%83%9E%E3%83%8B%E3%83%86%E3%82%A3%E3%83%BC%E3%82%BA",
+ "description": "...(digital humanities)は、コンピューティングと人文科学(humanities)諸分野と間の接点に関して調査、研究、教育、および�\n* Centre for Computing in the Humanities\n",
+ "position": {
+ "x": -221.48701615763574,
+ "y": 242.80740052545508
+ },
+ "image": "http://www.iri.centrepompidou.fr/dev/~veltr/hitachi-tests/img/wikipedia.png",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-000b",
+ "title": "Digital studies",
+ "uri": "",
+ "description": "",
+ "position": {
+ "x": -62.798895620242085,
+ "y": 32.09820725365255
+ },
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-9da6eef6c6391d05-000c",
+ "title": "Digital Humanities",
+ "uri": "",
+ "description": "",
+ "position": {
+ "x": -110.57020731070799,
+ "y": 160.92139209086253
+ },
+ "created_by": "u-raphv"
+ }, {
+ "_id": "node-2012-08-22-b778a9fc31296d6b-0008",
+ "title": "Les rétentions (Tweet)",
+ "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/e328e188-ff2f-11e0-b9e1-00145ea49a02/#id=a924b90c-46a1-4f0a-9e13-bcf69f7b5de0-127750274034049024",
+ "description": "Tweet by Vincent Puig: #tfcem Les rétentions primaires (perception) s'aggrégent et forment des rétentions secondaires (mémoire), gravées sur rétentions tertiaires",
+ "position": {
+ "x": 186.15055288633457,
+ "y": -184.66836073709257
+ },
+ "image": "http://a1.twimg.com/profile_images/379424006/PortaitVP120Ko_normal.jpg",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "node-2012-08-22-b778a9fc31296d6b-0009",
+ "title": "L'origine de la géométrie (Tweet)",
+ "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/e328e188-ff2f-11e0-b9e1-00145ea49a02/#id=5b34ae61-ffb1-4535-a479-007cb0ef57e8-127752118743474177",
+ "description": "Tweet by Vincent Puig: #tfcem L'origine de la géométrie: l'écriture est processus long de transindividuation. Nos tweets quasi temps réel sont de même nature++",
+ "position": {
+ "x": 87.82365160023906,
+ "y": -280.3591650733953
+ },
+ "image": "http://a1.twimg.com/profile_images/379424006/PortaitVP120Ko_normal.jpg",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "title": "Polemictweet : un outil Digital Studies (Tweet)",
+ "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/e328e188-ff2f-11e0-b9e1-00145ea49a02/#id=4b34e895-221b-467b-a0f2-8ff4ae87cae4-127758736415666177",
+ "description": "Tweet by Vincent Puig:\n#tfcem Polemictweet : un outil Digital Studies pensé à l'IRI comme rétention tertiaire numérique avec les même armes que l'industrie",
+ "position": {
+ "x": 168.59118089416432,
+ "y": 57.97933221077804
+ },
+ "image": "http://a1.twimg.com/profile_images/379424006/PortaitVP120Ko_normal.jpg",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "node-2012-08-22-b778a9fc31296d6b-000f",
+ "title": "Rétention (Définition AI)",
+ "uri": "http://arsindustrialis.org/vocabulaire-ars-industrialis/r%C3%A9tention",
+ "description": "Les rétentions sont ce qui est retenu ou recueilli par la conscience. Ce terme est emprunté à Husserl ; mais les rétentions tertiaires sont propres à la philosophie de Bernard Stiegler.\n\nLes rétentions sont des sélections : dans le flux de conscience que vous êtes vous ne pouvez pas tout retenir, ce que vous retenez est ce que vous êtes, mais ce que vous retenez dépend ce que vous avez déjà retenu.\n\nL’espèce humaine, étant originairement constituée par sa prothéticité, dispose d’une troisième mémoire, ni génétique, ni épigénétique : le milieu épiphylogénétique, comme ensemble des rétentions tertiaires formant des dispositifs rétentionels.",
+ "position": {
+ "x": 276.41820932461013,
+ "y": -62.82646518900019
+ },
+ "image": "http://www.arsindustrialis.org/sites/default/files/userfiles/user3/Logovocabulairenoir.JPG",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "node-2012-08-22-5b349e49066c1b01-0001",
+ "title": "Polemic Tweet",
+ "uri": "http://polemictweet.com/",
+ "description": "Polemic Tweet Web Site",
+ "position": {
+ "x": 220.96817493563964,
+ "y": 196.75746750735607
+ },
+ "image": "http://www.polemictweet.com/images/ENMI_2010_logo.gif",
+ "created_by": "u-cybunk"
+ }
+ ],
+ "edges": [
+ {
+ "_id": "edge-2012-08-22-9da6eef6c6391d05-0005",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-0002",
+ "to": "node-2012-08-22-9da6eef6c6391d05-0004",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-9da6eef6c6391d05-0006",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-0003",
+ "to": "node-2012-08-22-9da6eef6c6391d05-0004",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-9da6eef6c6391d05-0007",
+ "title": "speech by",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-0001",
+ "to": "node-2012-08-22-9da6eef6c6391d05-0004",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-0001",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-0001",
+ "to": "node-2012-08-22-9da6eef6c6391d05-000b",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-0002",
+ "title": "Are related to",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-000b",
+ "to": "node-2012-08-22-9da6eef6c6391d05-000c",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-0003",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-0009",
+ "to": "node-2012-08-22-9da6eef6c6391d05-000c",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-0004",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-9da6eef6c6391d05-000a",
+ "to": "node-2012-08-22-9da6eef6c6391d05-000c",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-000b",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "to": "node-2012-08-22-9da6eef6c6391d05-000b",
+ "created_by": "u-raphv"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-000c",
+ "title": "tweeted during",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-0009",
+ "to": "node-2012-08-22-9da6eef6c6391d05-0001",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-000d",
+ "title": "tweeted during",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-0008",
+ "to": "node-2012-08-22-9da6eef6c6391d05-0001",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-000e",
+ "title": "tweeted during",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "to": "node-2012-08-22-9da6eef6c6391d05-0001",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-0011",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-0008",
+ "to": "node-2012-08-22-b778a9fc31296d6b-000f",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "edge-2012-08-22-b778a9fc31296d6b-0012",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "to": "node-2012-08-22-b778a9fc31296d6b-000f",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "edge-2012-08-22-5b349e49066c1b01-0002",
+ "title": "is about",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "to": "node-2012-08-22-5b349e49066c1b01-0001",
+ "created_by": "u-cybunk"
+ }, {
+ "_id": "edge-2012-09-06-70cc0c2d5e1112d3-0001",
+ "title": "is an example of",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "to": "node-2012-08-22-9da6eef6c6391d05-000b",
+ "created_by": "u-anonymous"
+ }, {
+ "_id": "edge-2012-09-06-70cc0c2d5e1112d3-0002",
+ "title": "tool used",
+ "uri": "",
+ "description": "",
+ "from": "node-2012-08-22-5b349e49066c1b01-0001",
+ "to": "node-2012-08-22-b778a9fc31296d6b-000a",
+ "created_by": "u-anonymous"
+ }
+ ]
+}
\ No newline at end of file
Binary file server/src/main/webapp/static/img/edit.png has changed
Binary file server/src/main/webapp/static/img/goto.png has changed
Binary file server/src/main/webapp/static/img/ldt-point.png has changed
Binary file server/src/main/webapp/static/img/ldt-segment.png has changed
Binary file server/src/main/webapp/static/img/ldt-tag.png has changed
Binary file server/src/main/webapp/static/img/link.png has changed
Binary file server/src/main/webapp/static/img/more.png has changed
Binary file server/src/main/webapp/static/img/refresh.png has changed
Binary file server/src/main/webapp/static/img/remove.png has changed
Binary file server/src/main/webapp/static/img/search-logos.png has changed
Binary file server/src/main/webapp/static/img/search.png has changed
Binary file server/src/main/webapp/static/img/tooltiparrow.png has changed
Binary file server/src/main/webapp/static/img/topbarbuttons.png has changed
Binary file server/src/main/webapp/static/img/wikipedia.png has changed
Binary file server/src/main/webapp/static/img/zoombuttons.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/config.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,41 @@
+//
+// Config file. Split out from the app for ease of overlaying a new config
+// without affecting the app controller.
+//
+// Copyright (c) The Dojo Foundation 2011. All Rights Reserved.
+//
+var dojoConfig = {
+ baseUrl: '/renkan',
+ async:true,
+ paths : {
+ coweb : 'lib/coweb',
+ cowebx: 'lib/cowebx',
+ org : 'lib/org',
+ corenkan: 'static/js/corenkan',
+ underscore: 'static/lib/underscore-min',
+ },
+ /*packages:[{
+ name: 'dojo',
+ location:'lib/dojo',
+ main:'main'
+ },
+ {
+ name: 'dijit',
+ location:'lib/dijit',
+ main:'main'
+ },
+ {
+ name: 'dojox',
+ location:'lib/dojox',
+ main:'main'
+ }]*/
+};
+
+var cowebConfig = {
+ baseUrl: window.location.protocol + '//' +window.location.host,
+ adminUrl : '/renkan/admin',
+ debug: false,
+ //useWebSockets: true
+};
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/corenkan-json.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,19 @@
+
+Rkns.jsonIO = function(_renkan, _opts) {
+ var _proj = _renkan.project;
+ if (typeof _opts.http_method == "undefined") {
+ _opts.http_method = 'PUT';
+ }
+ var _load = function() {
+ Rkns.$.getJSON(_opts.url, function(_data) {
+ _data['_id'] = _data['id'];
+ _proj.set(_data, {silent: true});
+ _renkan.renderer.autoScale();
+ if(typeof _opts.callback !== "undefined") {
+ console.log("Corenkan json: project loaded, calling callback fro project id " + _proj.id, _data, _proj);
+ _opts.callback(_proj, _renkan);
+ }
+ });
+ };
+ _load();
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/corenkan.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,331 @@
+define([
+ "dojo",
+ "coweb/main"
+], function(dojo, coweb) {
+
+ var CoRenkan = function() {
+ };
+
+ var proto = CoRenkan.prototype;
+
+ proto.init = function() {
+ console.log("ready callback");
+
+ //this.initCollab();
+
+ var sess = coweb.initSession();
+ var that = this;
+ sess.onStatusChange = function(status) {
+ console.log(status);
+ if(typeof that.onStatusChange === "function") {
+ that.onStatusChange(status);
+ }
+ };
+ sess.prepare();
+ this.project = null;
+
+ };
+
+ proto.initCollab = function(id) {
+ this.collab = coweb.initCollab({id : id});
+ this.collab.subscribeSync("project", this, "onRemoteProjectChange");
+ this.collab.subscribeSync("user", this, "onRemoteUserChange");
+ this.collab.subscribeSync("node", this, "onRemoteNodeChange");
+ this.collab.subscribeSync("edge", this, "onRemoteEdgeChange");
+ };
+
+ function prepareValues(obj,c) {
+ values = {};
+ for(var fieldname in c.changes) {
+ if(c.changes[fieldname]) {
+ values[fieldname] = obj.get(fieldname);
+ }
+ }
+ return values;
+ }
+
+ proto.addObjectBind = function(type, obj, c, options) {
+ console.log("add " + type,obj, c, options, this.project.toJSON());
+ var values = obj.toJSON();
+ var new_values = {
+ id: obj.id,
+ _type: type,
+ _index: options.index,
+ _project_id : obj.get("project").get("_id")
+ };
+ for(var k in new_values) {
+ values[k] = new_values[k];
+ }
+ console.log("add values : ", values);
+ this.collab.sendSync(type, values, "insert", options.index);
+ };
+
+ proto.removeObjectBind = function(type, obj, c, options) {
+ console.log("delete " + type,obj, c, options);
+ var values = {
+ id: obj.id,
+ _type: type,
+ _index: options.index,
+ _project_id : obj.get("project").id
+ };
+ this.collab.sendSync(type, values, "delete", options.index);
+ };
+
+ proto.updateObjectBind = function(type, obj, options) {
+ console.log("change " + type,obj, options);
+ if(typeof obj != "undefined" && obj.hasChanged()) {
+ var values = {
+ id: obj.id,
+ _type: type,
+ _project_id : obj.get("project").id
+ };
+ _.extend(values,obj.changed);
+ this.collab.sendSync(type, values);
+ }
+ };
+
+ proto.setProject = function(project) {
+
+ console.log("project", project);
+
+ var projectFields = ["title", "description", "uri"];
+ var that = this;
+ for(var fieldIndex in projectFields) {
+ (function(fi){
+ var field = projectFields[fi];
+ project.bind("change:"+field, function(obj, c) {
+ console.log(c);
+ values = {
+ id: obj.id,
+ type: "project",
+ project_id: obj.id
+ };
+ values[field] = c;
+ that.collab.sendSync("project", values);
+ });
+ })(fieldIndex);
+ }
+
+ project.get("nodes").bind("add", function(obj, c, options) {
+ that.addObjectBind("node", obj, c, options);
+ });
+
+ project.get("nodes").bind("remove", function(obj, c, options) {
+ that.removeObjectBind("node", obj, c, options);
+ });
+
+ project.get("nodes").bind("change", function(obj, options) {
+ that.updateObjectBind("node", obj, options);
+ });
+
+ project.get("users").bind("add", function(obj, c, options) {
+ that.addObjectBind("user", obj, c, options);
+ });
+
+ project.get("users").bind("remove", function(obj, c, options) {
+ that.removeObjectBind("user", obj, c, options);
+ });
+
+ project.get("users").bind("change", function(obj, options) {
+ that.updateObjectBind("user", obj, options);
+ });
+
+ project.get("edges").bind("add", function(obj, c, options) {
+ that.addObjectBind("edge", obj, c, options);
+ });
+
+ project.get("edges").bind("remove", function(obj, c, options) {
+ that.removeObjectBind("edge", obj, c, options);
+ });
+
+ project.get("edges").bind("change", function(obj, options) {
+ that.updateObjectBind("edge", obj, options);
+ });
+
+
+ this.project = project;
+ this.initCollab("renkan_" + project.id);
+ };
+
+
+ /**
+ * Called when a remote data store for project changes in some manner. Dispatches to
+ * local methods for insert, update, delete handling.
+ * TODO: manage project list change on server
+ * @param args Cooperative web event
+ */
+ proto.onRemoteProjectChange = function(args) {
+ console.log("Remote project change", args);
+ if (args.type === "update") {
+ this.onRemoteProjectUpdate(args.value, args.position);
+ }
+ /*if (args.type === "insert") {
+ this.onRemoteInsert(value, args.position);
+ } else if (args.type === "update") {
+ this.onRemoteUpdate(value, args.position);
+ } else if (args.type === "delete") {
+ this.onRemoteDelete(args.position);
+ }*/
+ };
+
+
+ /**
+ * Called when a remote data store for nodes changes in some manner. Dispatches to
+ * local methods for insert, update, delete handling.
+ * @param args Cooperative web event
+ */
+ proto.onRemoteObjectChange = function(field, args) {
+ console.log("Remote "+ field +" change",args);
+ if (args.type === "insert") {
+ this.onRemoteObjectInsert(field, args.value, args.position);
+ } else if (args.type === "update") {
+ this.onRemoteObjectUpdate(field, args.value, args.position);
+ } else if (args.type === "delete") {
+ this.onRemoteObjectDelete(field, args.position);
+ }
+ };
+
+
+ /**
+ * Called when a remote data store for nodes changes in some manner. Dispatches to
+ * local methods for insert, update, delete handling.
+ * @param args Cooperative web event
+ */
+ proto.onRemoteNodeChange = function(args) {
+ this.onRemoteObjectChange("nodes", args);
+ };
+
+
+ /**
+ * Called when a remote data store for nodes changes in some manner. Dispatches to
+ * local methods for insert, update, delete handling.
+ * @param args Cooperative web event
+ */
+ proto.onRemoteUserChange = function(args) {
+ this.onRemoteObjectChange("users", args);
+ };
+
+ /**
+ * Called when a remote data store for nodes changes in some manner. Dispatches to
+ * local methods for insert, update, delete handling.
+ * @param args Cooperative web event
+ */
+ proto.onRemoteEdgeChange = function(args) {
+ this.onRemoteObjectChange("edges", args);
+ };
+
+
+ /**
+ * Called when a project attribute changes value in a remote data store.
+ * Updates the attribute value of the item with the same id in the local
+ * data store.
+ *
+ * @param value Item data sent by remote data store
+ * @param position Which item to update.
+ */
+ proto.onRemoteProjectUpdate = function(values, position) {
+ var project_id = values['id'];
+ if(typeof(project_id) === "undefined") {
+ return;
+ }
+
+ if(this.project != null && project_id == this.project.id) {
+ for(var fieldname in values) {
+ if(fieldname != "id" && fieldname != "type") {
+ this.project.set(fieldname, values[fieldname]);
+ }
+ }
+ }
+
+ };
+
+ /**
+ * Called when an object is inserted in a remote data store.
+ *
+ * @param value Item data sent by remote data store
+ * @param position Which item to update.
+ */
+ proto.onRemoteObjectInsert = function(field, values, position) {
+
+ console.log("Remote "+ field +" insert values ", values, "position", position);
+
+ var coll = this.project.get(field);
+ var object_id = values['id'];
+
+ var obj = coll.get(object_id);
+
+ if(obj != null) {
+ this.onRemoteObjectUpdate(field, values, coll.indexOf(obj));
+ }
+ else {
+ var add_values = {};
+ for(var fieldname in values) {
+ if(fieldname == "_id" || fieldname[0] !== '_' ) {
+ add_values[fieldname] = values[fieldname];
+ }
+ }
+ switch(field) {
+ case "nodes":
+ this.project.addNode(add_values, {at:position});
+ break;
+ case "edges":
+ this.project.addEdge(add_values, {at:position});
+ break;
+ case "users":
+ this.project.addUser(add_values, {at:position});
+ break;
+ }
+ }
+
+ };
+
+ /**
+ * Called when a object attribute changes value in a remote data store.
+ * Updates the attribute value of the item with the same id in the local
+ * data store.
+ *
+ * @param field The collection field
+ * @param value Item data sent by remote data store
+ * @param position Which item to update.
+ */
+ proto.onRemoteObjectUpdate = function(field, values, position) {
+
+ console.log("Remote "+ field +" update values ", values, "position", position);
+
+ var object_id = values['id'];
+
+ if(this.project != null) {
+ var obj = this.project.get(field).get(object_id);
+ if(obj != null) {
+ var changed_val = {};
+ for(var fieldname in values) {
+ if(fieldname != "id" && fieldname != "type") {
+ changed_val[fieldname] = values[fieldname];
+ }
+ }
+ obj.set(changed_val);
+ }
+ }
+ };
+
+ /**
+ * Called when a object is deleted in a remote data store.
+ *
+ * @param position Which item to update.
+ */
+ proto.onRemoteObjectDelete = function(field, position) {
+ console.log("Remote "+ field +" delete position", position);
+ this.project.get(field).remove(this.project.get(field).at(position));
+ };
+
+
+ var app = new CoRenkan();
+ dojo.ready(function() {
+ app.init();
+ });
+
+
+ return {
+ app: app
+ };
+});
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/dojo.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,15 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+//>>built
+(function(_1,_2){var _3=function(){},_4=function(it){for(var p in it){return 0;}return 1;},_5={}.toString,_6=function(it){return _5.call(it)=="[object Function]";},_7=function(it){return _5.call(it)=="[object String]";},_8=function(it){return _5.call(it)=="[object Array]";},_9=function(_a,_b){if(_a){for(var i=0;i<_a.length;){_b(_a[i++]);}}},_c=function(_d,_e){for(var p in _e){_d[p]=_e[p];}return _d;},_f=function(_10,_11){return _c(new Error(_10),{src:"dojoLoader",info:_11});},_12=1,uid=function(){return "_"+_12++;},req=function(_13,_14,_15){return _16(_13,_14,_15,0,req);},_17=this,doc=_17.document,_18=doc&&doc.createElement("DiV"),has=req.has=function(_19){return _6(_1a[_19])?(_1a[_19]=_1a[_19](_17,doc,_18)):_1a[_19];},_1a=has.cache=_2.hasCache;has.add=function(_1b,_1c,now,_1d){(_1a[_1b]===undefined||_1d)&&(_1a[_1b]=_1c);return now&&has(_1b);};0&&has.add("host-node",_1.has&&"host-node" in _1.has?_1.has["host-node"]:(typeof process=="object"&&process.versions&&process.versions.node&&process.versions.v8));if(0){require("./_base/configNode.js").config(_2);_2.loaderPatch.nodeRequire=require;}0&&has.add("host-rhino",_1.has&&"host-rhino" in _1.has?_1.has["host-rhino"]:(typeof load=="function"&&(typeof Packages=="function"||typeof Packages=="object")));if(0){for(var _1e=_1.baseUrl||".",arg,_1f=this.arguments,i=0;i<_1f.length;){arg=(_1f[i++]+"").split("=");if(arg[0]=="baseUrl"){_1e=arg[1];break;}}load(_1e+"/_base/configRhino.js");rhinoDojoConfig(_2,_1e,_1f);}for(var p in _1.has){has.add(p,_1.has[p],0,1);}var _20=1,_21=2,_22=3,_23=4,_24=5;if(0){_20="requested";_21="arrived";_22="not-a-module";_23="executing";_24="executed";}var _25=0,_26="sync",xd="xd",_27=[],_28=0,_29=_3,_2a=_3,_2b;if(1){req.isXdUrl=_3;req.initSyncLoader=function(_2c,_2d,_2e){if(!_28){_28=_2c;_29=_2d;_2a=_2e;}return {sync:_26,requested:_20,arrived:_21,nonmodule:_22,executing:_23,executed:_24,syncExecStack:_27,modules:_2f,execQ:_30,getModule:_31,injectModule:_32,setArrived:_33,signal:_34,finishExec:_35,execModule:_36,dojoRequirePlugin:_28,getLegacyMode:function(){return _25;},guardCheckComplete:_37};};if(1){var _38=location.protocol,_39=location.host;req.isXdUrl=function(url){if(/^\./.test(url)){return false;}if(/^\/\//.test(url)){return true;}var _3a=url.match(/^([^\/\:]+\:)\/+([^\/]+)/);return _3a&&(_3a[1]!=_38||(_39&&_3a[2]!=_39));};1||has.add("dojo-xhr-factory",1);has.add("dojo-force-activex-xhr",1&&!doc.addEventListener&&window.location.protocol=="file:");has.add("native-xhr",typeof XMLHttpRequest!="undefined");if(has("native-xhr")&&!has("dojo-force-activex-xhr")){_2b=function(){return new XMLHttpRequest();};}else{for(var _3b=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],_3c,i=0;i<3;){try{_3c=_3b[i++];if(new ActiveXObject(_3c)){break;}}catch(e){}}_2b=function(){return new ActiveXObject(_3c);};}req.getXhr=_2b;has.add("dojo-gettext-api",1);req.getText=function(url,_3d,_3e){var xhr=_2b();xhr.open("GET",_3f(url),false);xhr.send(null);if(xhr.status==200||(!location.host&&!xhr.status)){if(_3e){_3e(xhr.responseText,_3d);}}else{throw _f("xhrFailed",xhr.status);}return xhr.responseText;};}}else{req.async=1;}var _40=new Function("return eval(arguments[0]);");req.eval=function(_41,_42){return _40(_41+"\r\n////@ sourceURL="+_42);};var _43={},_44="error",_34=req.signal=function(_45,_46){var _47=_43[_45];_9(_47&&_47.slice(0),function(_48){_48.apply(null,_8(_46)?_46:[_46]);});},on=req.on=function(_49,_4a){var _4b=_43[_49]||(_43[_49]=[]);_4b.push(_4a);return {remove:function(){for(var i=0;i<_4b.length;i++){if(_4b[i]===_4a){_4b.splice(i,1);return;}}}};};var _4c=[],_4d={},_4e=[],_4f={},map=req.map={},_50=[],_2f={},_51="",_52={},_53="url:",_54={},_55={};if(1){var _56=function(_57){var p,_58,_59,now,m;for(p in _54){_58=_54[p];_59=p.match(/^url\:(.+)/);if(_59){_52[_53+_5a(_59[1],_57)]=_58;}else{if(p=="*now"){now=_58;}else{if(p!="*noref"){m=_5b(p,_57);_52[m.mid]=_52[_53+m.url]=_58;}}}}if(now){now(_5c(_57));}_54={};},_5d=function(s){return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(c){return "\\"+c;});},_5e=function(map,_5f){_5f.splice(0,_5f.length);for(var p in map){_5f.push([p,map[p],new RegExp("^"+_5d(p)+"(/|$)"),p.length]);}_5f.sort(function(lhs,rhs){return rhs[3]-lhs[3];});return _5f;},_60=function(_61){var _62=_61.name;if(!_62){_62=_61;_61={name:_62};}_61=_c({main:"main"},_61);_61.location=_61.location?_61.location:_62;if(_61.packageMap){map[_62]=_61.packageMap;}if(!_61.main.indexOf("./")){_61.main=_61.main.substring(2);}_4f[_62]=_61;},_63=function(_64,_65,_66){for(var p in _64){if(p=="waitSeconds"){req.waitms=(_64[p]||0)*1000;}if(p=="cacheBust"){_51=_64[p]?(_7(_64[p])?_64[p]:(new Date()).getTime()+""):"";}if(p=="baseUrl"||p=="combo"){req[p]=_64[p];}if(1&&p=="async"){var _67=_64[p];req.legacyMode=_25=(_7(_67)&&/sync|legacyAsync/.test(_67)?_67:(!_67?_26:false));req.async=!_25;}if(_64[p]!==_1a){req.rawConfig[p]=_64[p];p!="has"&&has.add("config-"+p,_64[p],0,_65);}}if(!req.baseUrl){req.baseUrl="./";}if(!/\/$/.test(req.baseUrl)){req.baseUrl+="/";}for(p in _64.has){has.add(p,_64.has[p],0,_65);}_9(_64.packages,_60);for(_1e in _64.packagePaths){_9(_64.packagePaths[_1e],function(_68){var _69=_1e+"/"+_68;if(_7(_68)){_68={name:_68};}_68.location=_69;_60(_68);});}_5e(_c(map,_64.map),_50);_9(_50,function(_6a){_6a[1]=_5e(_6a[1],[]);if(_6a[0]=="*"){_50.star=_6a[1];}});_5e(_c(_4d,_64.paths),_4e);_9(_64.aliases,function(_6b){if(_7(_6b[0])){_6b[0]=new RegExp("^"+_5d(_6b[0])+"$");}_4c.push(_6b);});for(p in _64.config){var _6c=_31(p,_66);_6c.config=_c(_6c.config||{},_64.config[p]);}if(_64.cache){_56();_54=_64.cache;if(_64.cache["*noref"]){_56();}}_34("config",[_64,req.rawConfig]);};if(has("dojo-cdn")||1){var _6d=doc.getElementsByTagName("script"),i=0,_6e,_6f,src,_70;while(i<_6d.length){_6e=_6d[i++];if((src=_6e.getAttribute("src"))&&(_70=src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){_6f=_70[3]||"";_2.baseUrl=_2.baseUrl||_6f;src=(_6e.getAttribute("data-dojo-config")||_6e.getAttribute("djConfig"));if(src){_55=req.eval("({ "+src+" })","data-dojo-config");}if(0){var _71=_6e.getAttribute("data-main");if(_71){_55.deps=_55.deps||[_71];}}break;}}}if(0){try{if(window.parent!=window&&window.parent.require){var doh=window.parent.require("doh");doh&&_c(_55,doh.testConfig);}}catch(e){}}req.rawConfig={};_63(_2,1);if(has("dojo-cdn")){_4f.dojo.location=_6f;if(_6f){_6f+="/";}_4f.dijit.location=_6f+"../dijit/";_4f.dojox.location=_6f+"../dojox/";}_63(_1,1);_63(_55,1);}else{_4d=_2.paths;_4e=_2.pathsMapProg;_4f=_2.packs;_4c=_2.aliases;_50=_2.mapProgs;_2f=_2.modules;_52=_2.cache;_51=_2.cacheBust;req.rawConfig=_2;}if(0){req.combo=req.combo||{add:_3};var _72=0,_73=[],_74=null;}var _75=function(_76){_37(function(){_9(_76.deps,_32);if(0&&_72&&!_74){_74=setTimeout(function(){_72=0;_74=null;req.combo.done(function(_77,url){var _78=function(){_79(0,_77);_7a();};_73.push(_77);_7b=_77;req.injectUrl(url,_78,_77);_7b=0;},req);},0);}});},_16=function(a1,a2,a3,_7c,_7d){var _7e,_7f;if(_7(a1)){_7e=_31(a1,_7c,true);if(_7e&&_7e.executed){return _7e.result;}throw _f("undefinedModule",a1);}if(!_8(a1)){_63(a1,0,_7c);a1=a2;a2=a3;}if(_8(a1)){if(!a1.length){a2&&a2();}else{_7f="require*"+uid();for(var mid,_80=[],i=0;i<a1.length;){mid=a1[i++];_80.push(_31(mid,_7c));}_7e=_c(_81("",_7f,0,""),{injected:_21,deps:_80,def:a2||_3,require:_7c?_7c.require:req,gc:1});_2f[_7e.mid]=_7e;_75(_7e);var _82=_83&&_25!=_26;_37(function(){_36(_7e,_82);});if(!_7e.executed){_30.push(_7e);}_7a();}}return _7d;},_5c=function(_84){if(!_84){return req;}var _85=_84.require;if(!_85){_85=function(a1,a2,a3){return _16(a1,a2,a3,_84,_85);};_84.require=_c(_85,req);_85.module=_84;_85.toUrl=function(_86){return _5a(_86,_84);};_85.toAbsMid=function(mid){return _b3(mid,_84);};if(0){_85.undef=function(mid){req.undef(mid,_84);};}if(1){_85.syncLoadNls=function(mid){var _87=_5b(mid,_84),_88=_2f[_87.mid];if(!_88||!_88.executed){_89=_52[_87.mid]||_52[_53+_87.url];if(_89){_8a(_89);_88=_2f[_87.mid];}}return _88&&_88.executed&&_88.result;};}}return _85;},_30=[],_8b=[],_8c={},_8d=function(_8e){_8e.injected=_20;_8c[_8e.mid]=1;if(_8e.url){_8c[_8e.url]=_8e.pack||1;}_8f();},_33=function(_90){_90.injected=_21;delete _8c[_90.mid];if(_90.url){delete _8c[_90.url];}if(_4(_8c)){_91();1&&_25==xd&&(_25=_26);}},_92=req.idle=function(){return !_8b.length&&_4(_8c)&&!_30.length&&!_83;},_93=function(_94,map){if(map){for(var i=0;i<map.length;i++){if(map[i][2].test(_94)){return map[i];}}}return 0;},_95=function(_96){var _97=[],_98,_99;_96=_96.replace(/\\/g,"/").split("/");while(_96.length){_98=_96.shift();if(_98==".."&&_97.length&&_99!=".."){_97.pop();_99=_97[_97.length-1];}else{if(_98!="."){_97.push(_99=_98);}}}return _97.join("/");},_81=function(pid,mid,_9a,url){if(1){var xd=req.isXdUrl(url);return {pid:pid,mid:mid,pack:_9a,url:url,executed:0,def:0,isXd:xd,isAmd:!!(xd||(_4f[pid]&&_4f[pid].isAmd))};}else{return {pid:pid,mid:mid,pack:_9a,url:url,executed:0,def:0};}},_9b=function(mid,_9c,_9d,_9e,_9f,_a0,_a1,_a2){var pid,_a3,_a4,_a5,_a6,url,_a7,_a8,_a9;_a9=mid;_a8=/^\./.test(mid);if(/(^\/)|(\:)|(\.js$)/.test(mid)||(_a8&&!_9c)){return _81(0,mid,0,mid);}else{mid=_95(_a8?(_9c.mid+"/../"+mid):mid);if(/^\./.test(mid)){throw _f("irrationalPath",mid);}if(_9c){_a6=_93(_9c.mid,_a0);}_a6=_a6||_a0.star;_a6=_a6&&_93(mid,_a6[1]);if(_a6){mid=_a6[1]+mid.substring(_a6[3]);}_70=mid.match(/^([^\/]+)(\/(.+))?$/);pid=_70?_70[1]:"";if((_a3=_9d[pid])){mid=pid+"/"+(_a4=(_70[3]||_a3.main));}else{pid="";}var _aa=0,_ab=0;_9(_4c,function(_ac){var _ad=mid.match(_ac[0]);if(_ad&&_ad.length>_aa){_ab=_6(_ac[1])?mid.replace(_ac[0],_ac[1]):_ac[1];}});if(_ab){return _9b(_ab,0,_9d,_9e,_9f,_a0,_a1,_a2);}_a7=_9e[mid];if(_a7){return _a2?_81(_a7.pid,_a7.mid,_a7.pack,_a7.url):_9e[mid];}}_a6=_93(mid,_a1);if(_a6){url=_a6[1]+mid.substring(_a6[3]);}else{if(pid){url=_a3.location+"/"+_a4;}else{if(has("config-tlmSiblingOfDojo")){url="../"+mid;}else{url=mid;}}}if(!(/(^\/)|(\:)/.test(url))){url=_9f+url;}url+=".js";return _81(pid,mid,_a3,_95(url));},_5b=function(mid,_ae){return _9b(mid,_ae,_4f,_2f,req.baseUrl,_50,_4e);},_af=function(_b0,_b1,_b2){return _b0.normalize?_b0.normalize(_b1,function(mid){return _b3(mid,_b2);}):_b3(_b1,_b2);},_b4=0,_31=function(mid,_b5,_b6){var _b7,_b8,_b9,_ba;_b7=mid.match(/^(.+?)\!(.*)$/);if(_b7){_b8=_31(_b7[1],_b5,_b6);if(1&&_25==_26&&!_b8.executed){_32(_b8);if(_b8.injected===_21&&!_b8.executed){_37(function(){_36(_b8);});}if(_b8.executed){_bb(_b8);}else{_30.unshift(_b8);}}if(_b8.executed===_24&&!_b8.load){_bb(_b8);}if(_b8.load){_b9=_af(_b8,_b7[2],_b5);mid=(_b8.mid+"!"+(_b8.dynamic?++_b4+"!":"")+_b9);}else{_b9=_b7[2];mid=_b8.mid+"!"+(++_b4)+"!waitingForPlugin";}_ba={plugin:_b8,mid:mid,req:_5c(_b5),prid:_b9};}else{_ba=_5b(mid,_b5);}return _2f[_ba.mid]||(!_b6&&(_2f[_ba.mid]=_ba));},_b3=req.toAbsMid=function(mid,_bc){return _5b(mid,_bc).mid;},_5a=req.toUrl=function(_bd,_be){var _bf=_5b(_bd+"/x",_be),url=_bf.url;return _3f(_bf.pid===0?_bd:url.substring(0,url.length-5));},_c0={injected:_21,executed:_24,def:_22,result:_22},_c1=function(mid){return _2f[mid]=_c({mid:mid},_c0);},_c2=_c1("require"),_c3=_c1("exports"),_c4=_c1("module"),_c5=function(_c6,_c7){req.trace("loader-run-factory",[_c6.mid]);var _c8=_c6.def,_c9;1&&_27.unshift(_c6);if(has("config-dojo-loader-catches")){try{_c9=_6(_c8)?_c8.apply(null,_c7):_c8;}catch(e){_34(_44,_c6.result=_f("factoryThrew",[_c6,e]));}}else{_c9=_6(_c8)?_c8.apply(null,_c7):_c8;}_c6.result=_c9===undefined&&_c6.cjs?_c6.cjs.exports:_c9;1&&_27.shift(_c6);},_ca={},_cb=0,_bb=function(_cc){var _cd=_cc.result;_cc.dynamic=_cd.dynamic;_cc.normalize=_cd.normalize;_cc.load=_cd.load;return _cc;},_ce=function(_cf){var map={};_9(_cf.loadQ,function(_d0){var _d1=_af(_cf,_d0.prid,_d0.req.module),mid=_cf.dynamic?_d0.mid.replace(/waitingForPlugin$/,_d1):(_cf.mid+"!"+_d1),_d2=_c(_c({},_d0),{mid:mid,prid:_d1,injected:0});if(!_2f[mid]){_e4(_2f[mid]=_d2);}map[_d0.mid]=_2f[mid];_33(_d0);delete _2f[_d0.mid];});_cf.loadQ=0;var _d3=function(_d4){for(var _d5,_d6=_d4.deps||[],i=0;i<_d6.length;i++){_d5=map[_d6[i].mid];if(_d5){_d6[i]=_d5;}}};for(var p in _2f){_d3(_2f[p]);}_9(_30,_d3);},_35=function(_d7){req.trace("loader-finish-exec",[_d7.mid]);_d7.executed=_24;_d7.defOrder=_cb++;1&&_9(_d7.provides,function(cb){cb();});if(_d7.loadQ){_bb(_d7);_ce(_d7);}for(i=0;i<_30.length;){if(_30[i]===_d7){_30.splice(i,1);}else{i++;}}if(/^require\*/.test(_d7.mid)){delete _2f[_d7.mid];}},_d8=[],_36=function(_d9,_da){if(_d9.executed===_23){req.trace("loader-circular-dependency",[_d8.concat(_d9.mid).join("->")]);return (!_d9.def||_da)?_ca:(_d9.cjs&&_d9.cjs.exports);}if(!_d9.executed){if(!_d9.def){return _ca;}var mid=_d9.mid,_db=_d9.deps||[],arg,_dc,_dd=[],i=0;if(0){_d8.push(mid);req.trace("loader-exec-module",["exec",_d8.length,mid]);}_d9.executed=_23;while(i<_db.length){arg=_db[i++];_dc=((arg===_c2)?_5c(_d9):((arg===_c3)?_d9.cjs.exports:((arg===_c4)?_d9.cjs:_36(arg,_da))));if(_dc===_ca){_d9.executed=0;req.trace("loader-exec-module",["abort",mid]);0&&_d8.pop();return _ca;}_dd.push(_dc);}_c5(_d9,_dd);_35(_d9);0&&_d8.pop();}return _d9.result;},_83=0,_37=function(_de){try{_83++;_de();}finally{_83--;}if(_92()){_34("idle",[]);}},_7a=function(){if(_83){return;}_37(function(){_29();for(var _df,_e0,i=0;i<_30.length;){_df=_cb;_e0=_30[i];_36(_e0);if(_df!=_cb){_29();i=0;}else{i++;}}});};if(0){req.undef=function(_e1,_e2){var _e3=_31(_e1,_e2);_33(_e3);delete _2f[_e3.mid];};}if(1){if(has("dojo-loader-eval-hint-url")===undefined){has.add("dojo-loader-eval-hint-url",1);}var _3f=function(url){url+="";return url+(_51?((/\?/.test(url)?"&":"?")+_51):"");},_e4=function(_e5){var _e6=_e5.plugin;if(_e6.executed===_24&&!_e6.load){_bb(_e6);}var _e7=function(def){_e5.result=def;_33(_e5);_35(_e5);_7a();};if(_e6.load){_e6.load(_e5.prid,_e5.req,_e7);}else{if(_e6.loadQ){_e6.loadQ.push(_e5);}else{_e6.loadQ=[_e5];_30.unshift(_e6);_32(_e6);}}},_89=0,_7b=0,_e8=0,_8a=function(_e9,_ea){if(has("config-stripStrict")){_e9=_e9.replace(/"use strict"/g,"");}_e8=1;if(has("config-dojo-loader-catches")){try{if(_e9===_89){_89.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}catch(e){_34(_44,_f("evalModuleThrew",_ea));}}else{if(_e9===_89){_89.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}_e8=0;},_32=function(_eb){var mid=_eb.mid,url=_eb.url;if(_eb.executed||_eb.injected||_8c[mid]||(_eb.url&&((_eb.pack&&_8c[_eb.url]===_eb.pack)||_8c[_eb.url]==1))){return;}_8d(_eb);if(0){var _ec=0;if(_eb.plugin&&_eb.plugin.isCombo){req.combo.add(_eb.plugin.mid,_eb.prid,0,req);_ec=1;}else{if(!_eb.plugin){_ec=req.combo.add(0,_eb.mid,_eb.url,req);}}if(_ec){_72=1;return;}}if(_eb.plugin){_e4(_eb);return;}var _ed=function(){_79(_eb);if(_eb.injected!==_21){_33(_eb);_c(_eb,_c0);req.trace("loader-define-nonmodule",[_eb.url]);}if(1&&_25){!_27.length&&_7a();}else{_7a();}};_89=_52[mid]||_52[_53+_eb.url];if(_89){req.trace("loader-inject",["cache",_eb.mid,url]);_8a(_89,_eb);_ed();return;}if(1&&_25){if(_eb.isXd){_25==_26&&(_25=xd);}else{if(_eb.isAmd&&_25!=_26){}else{var _ee=function(_ef){if(_25==_26){_27.unshift(_eb);_8a(_ef,_eb);_27.shift();_79(_eb);if(!_eb.cjs){_33(_eb);_35(_eb);}if(_eb.finish){var _f0=mid+"*finish",_f1=_eb.finish;delete _eb.finish;def(_f0,["dojo",("dojo/require!"+_f1.join(",")).replace(/\./g,"/")],function(_f2){_9(_f1,function(mid){_f2.require(mid);});});_30.unshift(_31(_f0));}_ed();}else{_ef=_2a(_eb,_ef);if(_ef){_8a(_ef,_eb);_ed();}else{_7b=_eb;req.injectUrl(_3f(url),_ed,_eb);_7b=0;}}};req.trace("loader-inject",["xhr",_eb.mid,url,_25!=_26]);if(has("config-dojo-loader-catches")){try{req.getText(url,_25!=_26,_ee);}catch(e){_34(_44,_f("xhrInjectFailed",[_eb,e]));}}else{req.getText(url,_25!=_26,_ee);}return;}}}req.trace("loader-inject",["script",_eb.mid,url]);_7b=_eb;req.injectUrl(_3f(url),_ed,_eb);_7b=0;},_f3=function(_f4,_f5,def){req.trace("loader-define-module",[_f4.mid,_f5]);if(0&&_f4.plugin&&_f4.plugin.isCombo){_f4.result=_6(def)?def():def;_33(_f4);_35(_f4);return _f4;}var mid=_f4.mid;if(_f4.injected===_21){_34(_44,_f("multipleDefine",_f4));return _f4;}_c(_f4,{deps:_f5,def:def,cjs:{id:_f4.mid,uri:_f4.url,exports:(_f4.result={}),setExports:function(_f6){_f4.cjs.exports=_f6;},config:function(){return _f4.config;}}});for(var i=0;i<_f5.length;i++){_f5[i]=_31(_f5[i],_f4);}if(1&&_25&&!_8c[mid]){_75(_f4);_30.push(_f4);_7a();}_33(_f4);if(!_6(def)&&!_f5.length){_f4.result=def;_35(_f4);}return _f4;},_79=function(_f7,_f8){var _f9=[],_fa,_fb;while(_8b.length){_fb=_8b.shift();_f8&&(_fb[0]=_f8.shift());_fa=(_fb[0]&&_31(_fb[0]))||_f7;_f9.push([_fa,_fb[1],_fb[2]]);}_56(_f7);_9(_f9,function(_fc){_75(_f3.apply(null,_fc));});};}var _fd=0,_91=_3,_8f=_3;if(1){_91=function(){_fd&&clearTimeout(_fd);_fd=0;},_8f=function(){_91();if(req.waitms){_fd=window.setTimeout(function(){_91();_34(_44,_f("timeout",_8c));},req.waitms);}};}if(1){has.add("ie-event-behavior",!!doc.attachEvent&&(typeof opera==="undefined"||opera.toString()!="[object Opera]"));}if(1&&(1||1)){var _fe=function(_ff,_100,_101,_102){if(!has("ie-event-behavior")){_ff.addEventListener(_100,_102,false);return function(){_ff.removeEventListener(_100,_102,false);};}else{_ff.attachEvent(_101,_102);return function(){_ff.detachEvent(_101,_102);};}},_103=_fe(window,"load","onload",function(){req.pageLoaded=1;doc.readyState!="complete"&&(doc.readyState="complete");_103();});if(1){var _104=doc.getElementsByTagName("script")[0],_105=_104.parentNode;req.injectUrl=function(url,_106,_107){var node=_107.node=doc.createElement("script"),_108=function(e){e=e||window.event;var node=e.target||e.srcElement;if(e.type==="load"||/complete|loaded/.test(node.readyState)){_109();_10a();_106&&_106();}},_109=_fe(node,"load","onreadystatechange",_108),_10a=_fe(node,"error","onerror",function(e){_109();_10a();_34(_44,_f("scriptError",[url,e]));});node.type="text/javascript";node.charset="utf-8";node.src=url;_105.insertBefore(node,_104);return node;};}}if(1){req.log=function(){try{for(var i=0;i<arguments.length;i++){}}catch(e){}};}else{req.log=_3;}if(0){var _10b=req.trace=function(_10c,args){if(_10b.on&&_10b.group[_10c]){_34("trace",[_10c,args]);for(var arg,dump=[],text="trace:"+_10c+(args.length?(":"+args[0]):""),i=1;i<args.length;){arg=args[i++];if(_7(arg)){text+=", "+arg;}else{dump.push(arg);}}req.log(text);dump.length&&dump.push(".");req.log.apply(req,dump);}};_c(_10b,{on:1,group:{},set:function(_10d,_10e){if(_7(_10d)){_10b.group[_10d]=_10e;}else{_c(_10b.group,_10d);}}});_10b.set(_c(_c(_c({},_2.trace),_1.trace),_55.trace));on("config",function(_10f){_10f.trace&&_10b.set(_10f.trace);});}else{req.trace=_3;}var def=function(mid,_110,_111){var _112=arguments.length,_113=["require","exports","module"],args=[0,mid,_110];if(_112==1){args=[0,(_6(mid)?_113:[]),mid];}else{if(_112==2&&_7(mid)){args=[mid,(_6(_110)?_113:[]),_110];}else{if(_112==3){args=[mid,_110,_111];}}}if(0&&args[1]===_113){args[2].toString().replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,"").replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g,function(_114,dep){args[1].push(dep);});}req.trace("loader-define",args.slice(0,2));var _115=args[0]&&_31(args[0]),_116;if(_115&&!_8c[_115.mid]){_75(_f3(_115,args[1],args[2]));}else{if(!has("ie-event-behavior")||!1||_e8){_8b.push(args);}else{_115=_115||_7b;if(!_115){for(mid in _8c){_116=_2f[mid];if(_116&&_116.node&&_116.node.readyState==="interactive"){_115=_116;break;}}if(0&&!_115){for(var i=0;i<_73.length;i++){_115=_73[i];if(_115.node&&_115.node.readyState==="interactive"){break;}_115=0;}}}if(0&&_8(_115)){_75(_f3(_31(_115.shift()),args[1],args[2]));if(!_115.length){_73.splice(i,1);}}else{if(_115){_56(_115);_75(_f3(_115,args[1],args[2]));}else{_34(_44,_f("ieDefineFailed",args[0]));}}_7a();}}};def.amd={vendor:"dojotoolkit.org"};if(0){req.def=def;}_c(_c(req,_2.loaderPatch),_1.loaderPatch);on(_44,function(arg){try{console.error(arg);if(arg instanceof Error){for(var p in arg){}}}catch(e){}});_c(req,{uid:uid,cache:_52,packs:_4f});if(0){_c(req,{paths:_4d,aliases:_4c,modules:_2f,legacyMode:_25,execQ:_30,defQ:_8b,waiting:_8c,packs:_4f,mapProgs:_50,pathsMapProg:_4e,listenerQueues:_43,computeMapProg:_5e,runMapProg:_93,compactPath:_95,getModuleInfo:_9b});}if(_17.define){if(1){_34(_44,_f("defineAlreadyDefined",0));}return;}else{_17.define=def;_17.require=req;if(0){require=req;}}if(0&&req.combo&&req.combo.plugins){var _117=req.combo.plugins,_118;for(_118 in _117){_c(_c(_31(_118),_117[_118]),{isCombo:1,executed:"executed",load:1});}}if(1){var _119=_55.deps||_1.deps||_2.deps,_11a=_55.callback||_1.callback||_2.callback;req.boot=(_119||_11a)?[_119||[],_11a]:0;}if(!1){!req.async&&req(["dojo"]);req.boot&&req.apply(null,req.boot);}})(this.dojoConfig||this.djConfig||this.require||{},{async:0,hasCache:{"config-selectorEngine":"acme","config-tlmSiblingOfDojo":1,"dojo-built":1,"dojo-loader":1,dom:1,"host-browser":1},packages:[{location:"../dijit",name:"dijit"},{location:"../dojox",name:"dojox"},{location:".",name:"dojo"}]});require({cache:{"dojo/_base/fx":function(){define(["./kernel","./config","./lang","../Evented","./Color","./connect","./sniff","../dom","../dom-style"],function(dojo,_11b,lang,_11c,_11d,_11e,has,dom,_11f){var _120=lang.mixin;var _121={};var _122=_121._Line=function(_123,end){this.start=_123;this.end=end;};_122.prototype.getValue=function(n){return ((this.end-this.start)*n)+this.start;};var _124=_121.Animation=function(args){_120(this,args);if(lang.isArray(this.curve)){this.curve=new _122(this.curve[0],this.curve[1]);}};_124.prototype=new _11c();lang.extend(_124,{duration:350,repeat:0,rate:20,_percent:0,_startRepeatCount:0,_getStep:function(){var _125=this._percent,_126=this.easing;return _126?_126(_125):_125;},_fire:function(evt,args){var a=args||[];if(this[evt]){if(_11b.debugAtAllCosts){this[evt].apply(this,a);}else{try{this[evt].apply(this,a);}catch(e){console.error("exception in animation handler for:",evt);console.error(e);}}}return this;},play:function(_127,_128){var _129=this;if(_129._delayTimer){_129._clearTimer();}if(_128){_129._stopTimer();_129._active=_129._paused=false;_129._percent=0;}else{if(_129._active&&!_129._paused){return _129;}}_129._fire("beforeBegin",[_129.node]);var de=_127||_129.delay,_12a=lang.hitch(_129,"_play",_128);if(de>0){_129._delayTimer=setTimeout(_12a,de);return _129;}_12a();return _129;},_play:function(_12b){var _12c=this;if(_12c._delayTimer){_12c._clearTimer();}_12c._startTime=new Date().valueOf();if(_12c._paused){_12c._startTime-=_12c.duration*_12c._percent;}_12c._active=true;_12c._paused=false;var _12d=_12c.curve.getValue(_12c._getStep());if(!_12c._percent){if(!_12c._startRepeatCount){_12c._startRepeatCount=_12c.repeat;}_12c._fire("onBegin",[_12d]);}_12c._fire("onPlay",[_12d]);_12c._cycle();return _12c;},pause:function(){var _12e=this;if(_12e._delayTimer){_12e._clearTimer();}_12e._stopTimer();if(!_12e._active){return _12e;}_12e._paused=true;_12e._fire("onPause",[_12e.curve.getValue(_12e._getStep())]);return _12e;},gotoPercent:function(_12f,_130){var _131=this;_131._stopTimer();_131._active=_131._paused=true;_131._percent=_12f;if(_130){_131.play();}return _131;},stop:function(_132){var _133=this;if(_133._delayTimer){_133._clearTimer();}if(!_133._timer){return _133;}_133._stopTimer();if(_132){_133._percent=1;}_133._fire("onStop",[_133.curve.getValue(_133._getStep())]);_133._active=_133._paused=false;return _133;},status:function(){if(this._active){return this._paused?"paused":"playing";}return "stopped";},_cycle:function(){var _134=this;if(_134._active){var curr=new Date().valueOf();var step=_134.duration===0?1:(curr-_134._startTime)/(_134.duration);if(step>=1){step=1;}_134._percent=step;if(_134.easing){step=_134.easing(step);}_134._fire("onAnimate",[_134.curve.getValue(step)]);if(_134._percent<1){_134._startTimer();}else{_134._active=false;if(_134.repeat>0){_134.repeat--;_134.play(null,true);}else{if(_134.repeat==-1){_134.play(null,true);}else{if(_134._startRepeatCount){_134.repeat=_134._startRepeatCount;_134._startRepeatCount=0;}}}_134._percent=0;_134._fire("onEnd",[_134.node]);!_134.repeat&&_134._stopTimer();}}return _134;},_clearTimer:function(){clearTimeout(this._delayTimer);delete this._delayTimer;}});var ctr=0,_135=null,_136={run:function(){}};lang.extend(_124,{_startTimer:function(){if(!this._timer){this._timer=_11e.connect(_136,"run",this,"_cycle");ctr++;}if(!_135){_135=setInterval(lang.hitch(_136,"run"),this.rate);}},_stopTimer:function(){if(this._timer){_11e.disconnect(this._timer);this._timer=null;ctr--;}if(ctr<=0){clearInterval(_135);_135=null;ctr=0;}}});var _137=has("ie")?function(node){var ns=node.style;if(!ns.width.length&&_11f.get(node,"width")=="auto"){ns.width="auto";}}:function(){};_121._fade=function(args){args.node=dom.byId(args.node);var _138=_120({properties:{}},args),_139=(_138.properties.opacity={});_139.start=!("start" in _138)?function(){return +_11f.get(_138.node,"opacity")||0;}:_138.start;_139.end=_138.end;var anim=_121.animateProperty(_138);_11e.connect(anim,"beforeBegin",lang.partial(_137,_138.node));return anim;};_121.fadeIn=function(args){return _121._fade(_120({end:1},args));};_121.fadeOut=function(args){return _121._fade(_120({end:0},args));};_121._defaultEasing=function(n){return 0.5+((Math.sin((n+1.5)*Math.PI))/2);};var _13a=function(_13b){this._properties=_13b;for(var p in _13b){var prop=_13b[p];if(prop.start instanceof _11d){prop.tempColor=new _11d();}}};_13a.prototype.getValue=function(r){var ret={};for(var p in this._properties){var prop=this._properties[p],_13c=prop.start;if(_13c instanceof _11d){ret[p]=_11d.blendColors(_13c,prop.end,r,prop.tempColor).toCss();}else{if(!lang.isArray(_13c)){ret[p]=((prop.end-_13c)*r)+_13c+(p!="opacity"?prop.units||"px":0);}}}return ret;};_121.animateProperty=function(args){var n=args.node=dom.byId(args.node);if(!args.easing){args.easing=dojo._defaultEasing;}var anim=new _124(args);_11e.connect(anim,"beforeBegin",anim,function(){var pm={};for(var p in this.properties){if(p=="width"||p=="height"){this.node.display="block";}var prop=this.properties[p];if(lang.isFunction(prop)){prop=prop(n);}prop=pm[p]=_120({},(lang.isObject(prop)?prop:{end:prop}));if(lang.isFunction(prop.start)){prop.start=prop.start(n);}if(lang.isFunction(prop.end)){prop.end=prop.end(n);}var _13d=(p.toLowerCase().indexOf("color")>=0);function _13e(node,p){var v={height:node.offsetHeight,width:node.offsetWidth}[p];if(v!==undefined){return v;}v=_11f.get(node,p);return (p=="opacity")?+v:(_13d?v:parseFloat(v));};if(!("end" in prop)){prop.end=_13e(n,p);}else{if(!("start" in prop)){prop.start=_13e(n,p);}}if(_13d){prop.start=new _11d(prop.start);prop.end=new _11d(prop.end);}else{prop.start=(p=="opacity")?+prop.start:parseFloat(prop.start);}}this.curve=new _13a(pm);});_11e.connect(anim,"onAnimate",lang.hitch(_11f,"set",anim.node));return anim;};_121.anim=function(node,_13f,_140,_141,_142,_143){return _121.animateProperty({node:node,duration:_140||_124.prototype.duration,properties:_13f,easing:_141,onEnd:_142}).play(_143||0);};if(1){_120(dojo,_121);dojo._Animation=_124;}return _121;});},"dojo/dom-form":function(){define(["./_base/lang","./dom","./io-query","./json"],function(lang,dom,ioq,json){function _144(obj,name,_145){if(_145===null){return;}var val=obj[name];if(typeof val=="string"){obj[name]=[val,_145];}else{if(lang.isArray(val)){val.push(_145);}else{obj[name]=_145;}}};var _146="file|submit|image|reset|button";var form={fieldToObject:function fieldToObject(_147){var ret=null;_147=dom.byId(_147);if(_147){var _148=_147.name,type=(_147.type||"").toLowerCase();if(_148&&type&&!_147.disabled){if(type=="radio"||type=="checkbox"){if(_147.checked){ret=_147.value;}}else{if(_147.multiple){ret=[];var _149=[_147.firstChild];while(_149.length){for(var node=_149.pop();node;node=node.nextSibling){if(node.nodeType==1&&node.tagName.toLowerCase()=="option"){if(node.selected){ret.push(node.value);}}else{if(node.nextSibling){_149.push(node.nextSibling);}if(node.firstChild){_149.push(node.firstChild);}break;}}}}else{ret=_147.value;}}}}return ret;},toObject:function formToObject(_14a){var ret={},_14b=dom.byId(_14a).elements;for(var i=0,l=_14b.length;i<l;++i){var item=_14b[i],_14c=item.name,type=(item.type||"").toLowerCase();if(_14c&&type&&_146.indexOf(type)<0&&!item.disabled){_144(ret,_14c,form.fieldToObject(item));if(type=="image"){ret[_14c+".x"]=ret[_14c+".y"]=ret[_14c].x=ret[_14c].y=0;}}}return ret;},toQuery:function formToQuery(_14d){return ioq.objectToQuery(form.toObject(_14d));},toJson:function formToJson(_14e,_14f){return json.stringify(form.toObject(_14e),null,_14f?4:0);}};return form;});},"dojo/i18n":function(){define(["./_base/kernel","require","./has","./_base/array","./_base/config","./_base/lang","./_base/xhr","./json","module"],function(dojo,_150,has,_151,_152,lang,xhr,json,_153){has.add("dojo-preload-i18n-Api",1);1||has.add("dojo-v1x-i18n-Api",1);var _154=dojo.i18n={},_155=/(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,_156=function(root,_157,_158,_159){for(var _15a=[_158+_159],_15b=_157.split("-"),_15c="",i=0;i<_15b.length;i++){_15c+=(_15c?"-":"")+_15b[i];if(!root||root[_15c]){_15a.push(_158+_15c+"/"+_159);}}return _15a;},_15d={},_15e=function(_15f,_160,_161){_161=_161?_161.toLowerCase():dojo.locale;_15f=_15f.replace(/\./g,"/");_160=_160.replace(/\./g,"/");return (/root/i.test(_161))?(_15f+"/nls/"+_160):(_15f+"/nls/"+_161+"/"+_160);},_162=dojo.getL10nName=function(_163,_164,_165){return _163=_153.id+"!"+_15e(_163,_164,_165);},_166=function(_167,_168,_169,_16a,_16b,load){_167([_168],function(root){var _16c=lang.clone(root.root),_16d=_156(!root._v1x&&root,_16b,_169,_16a);_167(_16d,function(){for(var i=1;i<_16d.length;i++){_16c=lang.mixin(lang.clone(_16c),arguments[i]);}var _16e=_168+"/"+_16b;_15d[_16e]=_16c;load();});});},_16f=function(id,_170){return /^\./.test(id)?_170(id):id;},_171=function(_172){var list=_152.extraLocale||[];list=lang.isArray(list)?list:[list];list.push(_172);return list;},load=function(id,_173,load){if(has("dojo-preload-i18n-Api")){var _174=id.split("*"),_175=_174[1]=="preload";if(_175){if(!_15d[id]){_15d[id]=1;_176(_174[2],json.parse(_174[3]),1,_173);}load(1);}if(_175||_177(id,_173,load)){return;}}var _178=_155.exec(id),_179=_178[1]+"/",_17a=_178[5]||_178[4],_17b=_179+_17a,_17c=(_178[5]&&_178[4]),_17d=_17c||dojo.locale,_17e=_17b+"/"+_17d,_17f=_17c?[_17d]:_171(_17d),_180=_17f.length,_181=function(){if(!--_180){load(lang.delegate(_15d[_17e]));}};_151.forEach(_17f,function(_182){var _183=_17b+"/"+_182;if(has("dojo-preload-i18n-Api")){_184(_183);}if(!_15d[_183]){_166(_173,_17b,_179,_17a,_182,_181);}else{_181();}});};if(has("dojo-unit-tests")){var _185=_154.unitTests=[];}if(has("dojo-preload-i18n-Api")||1){var _186=_154.normalizeLocale=function(_187){var _188=_187?_187.toLowerCase():dojo.locale;return _188=="root"?"ROOT":_188;},isXd=function(mid,_189){return (1&&1)?_189.isXdUrl(_150.toUrl(mid+".js")):true;},_18a=0,_18b=[],_176=_154._preloadLocalizations=function(_18c,_18d,_18e,_18f){_18f=_18f||_150;function _190(mid,_191){if(isXd(mid,_18f)||_18e){_18f([mid],_191);}else{_19b([mid],_191,_18f);}};function _192(_193,func){var _194=_193.split("-");while(_194.length){if(func(_194.join("-"))){return;}_194.pop();}func("ROOT");};function _195(_196){_196=_186(_196);_192(_196,function(loc){if(_151.indexOf(_18d,loc)>=0){var mid=_18c.replace(/\./g,"/")+"_"+loc;_18a++;_190(mid,function(_197){for(var p in _197){_15d[_150.toAbsMid(p)+"/"+loc]=_197[p];}--_18a;while(!_18a&&_18b.length){load.apply(null,_18b.shift());}});return true;}return false;});};_195();_151.forEach(dojo.config.extraLocale,_195);},_177=function(id,_198,load){if(_18a){_18b.push([id,_198,load]);}return _18a;},_184=function(){};}if(1){var _199={},_19a=new Function("__bundle","__checkForLegacyModules","__mid","__amdValue","var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;},"+"\t require = function(){define.called = 1;};"+"try{"+"define.called = 0;"+"eval(__bundle);"+"if(define.called==1)"+"return __amdValue;"+"if((__checkForLegacyModules = __checkForLegacyModules(__mid)))"+"return __checkForLegacyModules;"+"}catch(e){}"+"try{"+"return eval('('+__bundle+')');"+"}catch(e){"+"return e;"+"}"),_19b=function(deps,_19c,_19d){var _19e=[];_151.forEach(deps,function(mid){var url=_19d.toUrl(mid+".js");function load(text){var _19f=_19a(text,_184,mid,_199);if(_19f===_199){_19e.push(_15d[url]=_199.result);}else{if(_19f instanceof Error){console.error("failed to evaluate i18n bundle; url="+url,_19f);_19f={};}_19e.push(_15d[url]=(/nls\/[^\/]+\/[^\/]+$/.test(url)?_19f:{root:_19f,_v1x:1}));}};if(_15d[url]){_19e.push(_15d[url]);}else{var _1a0=_19d.syncLoadNls(mid);if(_1a0){_19e.push(_1a0);}else{if(!xhr){try{_19d.getText(url,true,load);}catch(e){_19e.push(_15d[url]={});}}else{xhr.get({url:url,sync:true,load:load,error:function(){_19e.push(_15d[url]={});}});}}}});_19c&&_19c.apply(null,_19e);};_184=function(_1a1){for(var _1a2,_1a3=_1a1.split("/"),_1a4=dojo.global[_1a3[0]],i=1;_1a4&&i<_1a3.length-1;_1a4=_1a4[_1a3[i++]]){}if(_1a4){_1a2=_1a4[_1a3[i]];if(!_1a2){_1a2=_1a4[_1a3[i].replace(/-/g,"_")];}if(_1a2){_15d[_1a1]=_1a2;}}return _1a2;};_154.getLocalization=function(_1a5,_1a6,_1a7){var _1a8,_1a9=_15e(_1a5,_1a6,_1a7);load(_1a9,(!isXd(_1a9,_150)?function(deps,_1aa){_19b(deps,_1aa,_150);}:_150),function(_1ab){_1a8=_1ab;});return _1a8;};if(has("dojo-unit-tests")){_185.push(function(doh){doh.register("tests.i18n.unit",function(t){var _1ac;_1ac=_19a("{prop:1}",_184,"nonsense",_199);t.is({prop:1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("({prop:1})",_184,"nonsense",_199);t.is({prop:1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("{'prop-x':1}",_184,"nonsense",_199);t.is({"prop-x":1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("({'prop-x':1})",_184,"nonsense",_199);t.is({"prop-x":1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("define({'prop-x':1})",_184,"nonsense",_199);t.is(_199,_1ac);t.is({"prop-x":1},_199.result);_1ac=_19a("define('some/module', {'prop-x':1})",_184,"nonsense",_199);t.is(_199,_1ac);t.is({"prop-x":1},_199.result);_1ac=_19a("this is total nonsense and should throw an error",_184,"nonsense",_199);t.is(_1ac instanceof Error,true);});});}}return lang.mixin(_154,{dynamic:true,normalize:_16f,load:load,cache:_15d});});},"dojo/promise/tracer":function(){define(["../_base/lang","./Promise","../Evented"],function(lang,_1ad,_1ae){"use strict";var _1af=new _1ae;var emit=_1af.emit;_1af.emit=null;function _1b0(args){setTimeout(function(){emit.apply(_1af,args);},0);};_1ad.prototype.trace=function(){var args=lang._toArray(arguments);this.then(function(_1b1){_1b0(["resolved",_1b1].concat(args));},function(_1b2){_1b0(["rejected",_1b2].concat(args));},function(_1b3){_1b0(["progress",_1b3].concat(args));});return this;};_1ad.prototype.traceRejected=function(){var args=lang._toArray(arguments);this.otherwise(function(_1b4){_1b0(["rejected",_1b4].concat(args));});return this;};return _1af;});},"dojo/errors/RequestError":function(){define(["./create"],function(_1b5){return _1b5("RequestError",function(_1b6,_1b7){this.response=_1b7;});});},"dojo/_base/html":function(){define("dojo/_base/html",["./kernel","../dom","../dom-style","../dom-attr","../dom-prop","../dom-class","../dom-construct","../dom-geometry"],function(dojo,dom,_1b8,attr,prop,cls,ctr,geom){dojo.byId=dom.byId;dojo.isDescendant=dom.isDescendant;dojo.setSelectable=dom.setSelectable;dojo.getAttr=attr.get;dojo.setAttr=attr.set;dojo.hasAttr=attr.has;dojo.removeAttr=attr.remove;dojo.getNodeProp=attr.getNodeProp;dojo.attr=function(node,name,_1b9){if(arguments.length==2){return attr[typeof name=="string"?"get":"set"](node,name);}return attr.set(node,name,_1b9);};dojo.hasClass=cls.contains;dojo.addClass=cls.add;dojo.removeClass=cls.remove;dojo.toggleClass=cls.toggle;dojo.replaceClass=cls.replace;dojo._toDom=dojo.toDom=ctr.toDom;dojo.place=ctr.place;dojo.create=ctr.create;dojo.empty=function(node){ctr.empty(node);};dojo._destroyElement=dojo.destroy=function(node){ctr.destroy(node);};dojo._getPadExtents=dojo.getPadExtents=geom.getPadExtents;dojo._getBorderExtents=dojo.getBorderExtents=geom.getBorderExtents;dojo._getPadBorderExtents=dojo.getPadBorderExtents=geom.getPadBorderExtents;dojo._getMarginExtents=dojo.getMarginExtents=geom.getMarginExtents;dojo._getMarginSize=dojo.getMarginSize=geom.getMarginSize;dojo._getMarginBox=dojo.getMarginBox=geom.getMarginBox;dojo.setMarginBox=geom.setMarginBox;dojo._getContentBox=dojo.getContentBox=geom.getContentBox;dojo.setContentSize=geom.setContentSize;dojo._isBodyLtr=dojo.isBodyLtr=geom.isBodyLtr;dojo._docScroll=dojo.docScroll=geom.docScroll;dojo._getIeDocumentElementOffset=dojo.getIeDocumentElementOffset=geom.getIeDocumentElementOffset;dojo._fixIeBiDiScrollLeft=dojo.fixIeBiDiScrollLeft=geom.fixIeBiDiScrollLeft;dojo.position=geom.position;dojo.marginBox=function marginBox(node,box){return box?geom.setMarginBox(node,box):geom.getMarginBox(node);};dojo.contentBox=function contentBox(node,box){return box?geom.setContentSize(node,box):geom.getContentBox(node);};dojo.coords=function(node,_1ba){dojo.deprecated("dojo.coords()","Use dojo.position() or dojo.marginBox().");node=dom.byId(node);var s=_1b8.getComputedStyle(node),mb=geom.getMarginBox(node,s);var abs=geom.position(node,_1ba);mb.x=abs.x;mb.y=abs.y;return mb;};dojo.getProp=prop.get;dojo.setProp=prop.set;dojo.prop=function(node,name,_1bb){if(arguments.length==2){return prop[typeof name=="string"?"get":"set"](node,name);}return prop.set(node,name,_1bb);};dojo.getStyle=_1b8.get;dojo.setStyle=_1b8.set;dojo.getComputedStyle=_1b8.getComputedStyle;dojo.__toPixelValue=dojo.toPixelValue=_1b8.toPixelValue;dojo.style=function(node,name,_1bc){switch(arguments.length){case 1:return _1b8.get(node);case 2:return _1b8[typeof name=="string"?"get":"set"](node,name);}return _1b8.set(node,name,_1bc);};return dojo;});},"dojo/_base/kernel":function(){define(["../has","./config","require","module"],function(has,_1bd,_1be,_1bf){var i,p,_1c0={},_1c1={},dojo={config:_1bd,global:this,dijit:_1c0,dojox:_1c1};var _1c2={dojo:["dojo",dojo],dijit:["dijit",_1c0],dojox:["dojox",_1c1]},_1c3=(_1be.map&&_1be.map[_1bf.id.match(/[^\/]+/)[0]]),item;for(p in _1c3){if(_1c2[p]){_1c2[p][0]=_1c3[p];}else{_1c2[p]=[_1c3[p],{}];}}for(p in _1c2){item=_1c2[p];item[1]._scopeName=item[0];if(!_1bd.noGlobals){this[item[0]]=item[1];}}dojo.scopeMap=_1c2;dojo.baseUrl=dojo.config.baseUrl=_1be.baseUrl;dojo.isAsync=!1||_1be.async;dojo.locale=_1bd.locale;var rev="$Rev: 29458 $".match(/\d+/);dojo.version={major:1,minor:8,patch:0,flag:"",revision:rev?+rev[0]:NaN,toString:function(){var v=dojo.version;return v.major+"."+v.minor+"."+v.patch+v.flag+" ("+v.revision+")";}};1||has.add("extend-dojo",1);(Function("d","d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);if(0){dojo.exit=function(_1c4){quit(_1c4);};}else{dojo.exit=function(){};}1||has.add("dojo-guarantee-console",1);if(1){typeof console!="undefined"||(console={});var cn=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","profile","profileEnd","time","timeEnd","trace","warn","log"];var tn;i=0;while((tn=cn[i++])){if(!console[tn]){(function(){var tcn=tn+"";console[tcn]=("log" in console)?function(){var a=Array.apply({},arguments);a.unshift(tcn+":");console["log"](a.join(" "));}:function(){};console[tcn]._fake=true;})();}}}has.add("dojo-debug-messages",!!_1bd.isDebug);dojo.deprecated=dojo.experimental=function(){};if(has("dojo-debug-messages")){dojo.deprecated=function(_1c5,_1c6,_1c7){var _1c8="DEPRECATED: "+_1c5;if(_1c6){_1c8+=" "+_1c6;}if(_1c7){_1c8+=" -- will be removed in version: "+_1c7;}console.warn(_1c8);};dojo.experimental=function(_1c9,_1ca){var _1cb="EXPERIMENTAL: "+_1c9+" -- APIs subject to change without notice.";if(_1ca){_1cb+=" "+_1ca;}console.warn(_1cb);};}1||has.add("dojo-modulePaths",1);if(1){if(_1bd.modulePaths){dojo.deprecated("dojo.modulePaths","use paths configuration");var _1cc={};for(p in _1bd.modulePaths){_1cc[p.replace(/\./g,"/")]=_1bd.modulePaths[p];}_1be({paths:_1cc});}}1||has.add("dojo-moduleUrl",1);if(1){dojo.moduleUrl=function(_1cd,url){dojo.deprecated("dojo.moduleUrl()","use require.toUrl","2.0");var _1ce=null;if(_1cd){_1ce=_1be.toUrl(_1cd.replace(/\./g,"/")+(url?("/"+url):"")+"/*.*").replace(/\/\*\.\*/,"")+(url?"":"/");}return _1ce;};}dojo._hasResource={};return dojo;});},"dojo/io-query":function(){define(["./_base/lang"],function(lang){var _1cf={};return {objectToQuery:function objectToQuery(map){var enc=encodeURIComponent,_1d0=[];for(var name in map){var _1d1=map[name];if(_1d1!=_1cf[name]){var _1d2=enc(name)+"=";if(lang.isArray(_1d1)){for(var i=0,l=_1d1.length;i<l;++i){_1d0.push(_1d2+enc(_1d1[i]));}}else{_1d0.push(_1d2+enc(_1d1));}}}return _1d0.join("&");},queryToObject:function queryToObject(str){var dec=decodeURIComponent,qp=str.split("&"),ret={},name,val;for(var i=0,l=qp.length,item;i<l;++i){item=qp[i];if(item.length){var s=item.indexOf("=");if(s<0){name=dec(item);val="";}else{name=dec(item.slice(0,s));val=dec(item.slice(s+1));}if(typeof ret[name]=="string"){ret[name]=[ret[name]];}if(lang.isArray(ret[name])){ret[name].push(val);}else{ret[name]=val;}}}return ret;}};});},"dojo/_base/Deferred":function(){define(["./kernel","../Deferred","../promise/Promise","../errors/CancelError","../has","./lang","../when"],function(dojo,_1d3,_1d4,_1d5,has,lang,when){var _1d6=function(){};var _1d7=Object.freeze||function(){};var _1d8=dojo.Deferred=function(_1d9){var _1da,_1db,_1dc,head,_1dd;var _1de=(this.promise=new _1d4());function _1df(_1e0){if(_1db){throw new Error("This deferred has already been resolved");}_1da=_1e0;_1db=true;_1e1();};function _1e1(){var _1e2;while(!_1e2&&_1dd){var _1e3=_1dd;_1dd=_1dd.next;if((_1e2=(_1e3.progress==_1d6))){_1db=false;}var func=(_1dc?_1e3.error:_1e3.resolved);if(has("config-useDeferredInstrumentation")){if(_1dc&&_1d3.instrumentRejected){_1d3.instrumentRejected(_1da,!!func);}}if(func){try{var _1e4=func(_1da);if(_1e4&&typeof _1e4.then==="function"){_1e4.then(lang.hitch(_1e3.deferred,"resolve"),lang.hitch(_1e3.deferred,"reject"),lang.hitch(_1e3.deferred,"progress"));continue;}var _1e5=_1e2&&_1e4===undefined;if(_1e2&&!_1e5){_1dc=_1e4 instanceof Error;}_1e3.deferred[_1e5&&_1dc?"reject":"resolve"](_1e5?_1da:_1e4);}catch(e){_1e3.deferred.reject(e);}}else{if(_1dc){_1e3.deferred.reject(_1da);}else{_1e3.deferred.resolve(_1da);}}}};this.resolve=this.callback=function(_1e6){this.fired=0;this.results=[_1e6,null];_1df(_1e6);};this.reject=this.errback=function(_1e7){_1dc=true;this.fired=1;if(has("config-useDeferredInstrumentation")){if(_1d3.instrumentRejected){_1d3.instrumentRejected(_1e7,!!_1dd);}}_1df(_1e7);this.results=[null,_1e7];};this.progress=function(_1e8){var _1e9=_1dd;while(_1e9){var _1ea=_1e9.progress;_1ea&&_1ea(_1e8);_1e9=_1e9.next;}};this.addCallbacks=function(_1eb,_1ec){this.then(_1eb,_1ec,_1d6);return this;};_1de.then=this.then=function(_1ed,_1ee,_1ef){var _1f0=_1ef==_1d6?this:new _1d8(_1de.cancel);var _1f1={resolved:_1ed,error:_1ee,progress:_1ef,deferred:_1f0};if(_1dd){head=head.next=_1f1;}else{_1dd=head=_1f1;}if(_1db){_1e1();}return _1f0.promise;};var _1f2=this;_1de.cancel=this.cancel=function(){if(!_1db){var _1f3=_1d9&&_1d9(_1f2);if(!_1db){if(!(_1f3 instanceof Error)){_1f3=new _1d5(_1f3);}_1f3.log=false;_1f2.reject(_1f3);}}};_1d7(_1de);};lang.extend(_1d8,{addCallback:function(_1f4){return this.addCallbacks(lang.hitch.apply(dojo,arguments));},addErrback:function(_1f5){return this.addCallbacks(null,lang.hitch.apply(dojo,arguments));},addBoth:function(_1f6){var _1f7=lang.hitch.apply(dojo,arguments);return this.addCallbacks(_1f7,_1f7);},fired:-1});_1d8.when=dojo.when=when;return _1d8;});},"dojo/NodeList-dom":function(){define(["./_base/kernel","./query","./_base/array","./_base/lang","./dom-class","./dom-construct","./dom-geometry","./dom-attr","./dom-style"],function(dojo,_1f8,_1f9,lang,_1fa,_1fb,_1fc,_1fd,_1fe){var _1ff=function(a){return a.length==1&&(typeof a[0]=="string");};var _200=function(node){var p=node.parentNode;if(p){p.removeChild(node);}};var _201=_1f8.NodeList,awc=_201._adaptWithCondition,aafe=_201._adaptAsForEach,aam=_201._adaptAsMap;function _202(_203){return function(node,name,_204){if(arguments.length==2){return _203[typeof name=="string"?"get":"set"](node,name);}return _203.set(node,name,_204);};};lang.extend(_201,{_normalize:function(_205,_206){var _207=_205.parse===true;if(typeof _205.template=="string"){var _208=_205.templateFunc||(dojo.string&&dojo.string.substitute);_205=_208?_208(_205.template,_205):_205;}var type=(typeof _205);if(type=="string"||type=="number"){_205=_1fb.toDom(_205,(_206&&_206.ownerDocument));if(_205.nodeType==11){_205=lang._toArray(_205.childNodes);}else{_205=[_205];}}else{if(!lang.isArrayLike(_205)){_205=[_205];}else{if(!lang.isArray(_205)){_205=lang._toArray(_205);}}}if(_207){_205._runParse=true;}return _205;},_cloneNode:function(node){return node.cloneNode(true);},_place:function(ary,_209,_20a,_20b){if(_209.nodeType!=1&&_20a=="only"){return;}var _20c=_209,_20d;var _20e=ary.length;for(var i=_20e-1;i>=0;i--){var node=(_20b?this._cloneNode(ary[i]):ary[i]);if(ary._runParse&&dojo.parser&&dojo.parser.parse){if(!_20d){_20d=_20c.ownerDocument.createElement("div");}_20d.appendChild(node);dojo.parser.parse(_20d);node=_20d.firstChild;while(_20d.firstChild){_20d.removeChild(_20d.firstChild);}}if(i==_20e-1){_1fb.place(node,_20c,_20a);}else{_20c.parentNode.insertBefore(node,_20c);}_20c=node;}},position:aam(_1fc.position),attr:awc(_202(_1fd),_1ff),style:awc(_202(_1fe),_1ff),addClass:aafe(_1fa.add),removeClass:aafe(_1fa.remove),toggleClass:aafe(_1fa.toggle),replaceClass:aafe(_1fa.replace),empty:aafe(_1fb.empty),removeAttr:aafe(_1fd.remove),marginBox:aam(_1fc.getMarginBox),place:function(_20f,_210){var item=_1f8(_20f)[0];return this.forEach(function(node){_1fb.place(node,item,_210);});},orphan:function(_211){return (_211?_1f8._filterResult(this,_211):this).forEach(_200);},adopt:function(_212,_213){return _1f8(_212).place(this[0],_213)._stash(this);},query:function(_214){if(!_214){return this;}var ret=new _201;this.map(function(node){_1f8(_214,node).forEach(function(_215){if(_215!==undefined){ret.push(_215);}});});return ret._stash(this);},filter:function(_216){var a=arguments,_217=this,_218=0;if(typeof _216=="string"){_217=_1f8._filterResult(this,a[0]);if(a.length==1){return _217._stash(this);}_218=1;}return this._wrap(_1f9.filter(_217,a[_218],a[_218+1]),this);},addContent:function(_219,_21a){_219=this._normalize(_219,this[0]);for(var i=0,node;(node=this[i]);i++){this._place(_219,node,_21a,i>0);}return this;}});return _201;});},"dojo/query":function(){define(["./_base/kernel","./has","./dom","./on","./_base/array","./_base/lang","./selector/_loader","./selector/_loader!default"],function(dojo,has,dom,on,_21b,lang,_21c,_21d){"use strict";has.add("array-extensible",function(){return lang.delegate([],{length:1}).length==1&&!has("bug-for-in-skips-shadowed");});var ap=Array.prototype,aps=ap.slice,apc=ap.concat,_21e=_21b.forEach;var tnl=function(a,_21f,_220){var _221=new (_220||this._NodeListCtor||nl)(a);return _21f?_221._stash(_21f):_221;};var _222=function(f,a,o){a=[0].concat(aps.call(a,0));o=o||dojo.global;return function(node){a[0]=node;return f.apply(o,a);};};var _223=function(f,o){return function(){this.forEach(_222(f,arguments,o));return this;};};var _224=function(f,o){return function(){return this.map(_222(f,arguments,o));};};var _225=function(f,o){return function(){return this.filter(_222(f,arguments,o));};};var _226=function(f,g,o){return function(){var a=arguments,body=_222(f,a,o);if(g.call(o||dojo.global,a)){return this.map(body);}this.forEach(body);return this;};};var _227=function(_228){var _229=this instanceof nl&&has("array-extensible");if(typeof _228=="number"){_228=Array(_228);}var _22a=(_228&&"length" in _228)?_228:arguments;if(_229||!_22a.sort){var _22b=_229?this:[],l=_22b.length=_22a.length;for(var i=0;i<l;i++){_22b[i]=_22a[i];}if(_229){return _22b;}_22a=_22b;}lang._mixin(_22a,nlp);_22a._NodeListCtor=function(_22c){return nl(_22c);};return _22a;};var nl=_227,nlp=nl.prototype=has("array-extensible")?[]:{};nl._wrap=nlp._wrap=tnl;nl._adaptAsMap=_224;nl._adaptAsForEach=_223;nl._adaptAsFilter=_225;nl._adaptWithCondition=_226;_21e(["slice","splice"],function(name){var f=ap[name];nlp[name]=function(){return this._wrap(f.apply(this,arguments),name=="slice"?this:null);};});_21e(["indexOf","lastIndexOf","every","some"],function(name){var f=_21b[name];nlp[name]=function(){return f.apply(dojo,[this].concat(aps.call(arguments,0)));};});lang.extend(_227,{constructor:nl,_NodeListCtor:nl,toString:function(){return this.join(",");},_stash:function(_22d){this._parent=_22d;return this;},on:function(_22e,_22f){var _230=this.map(function(node){return on(node,_22e,_22f);});_230.remove=function(){for(var i=0;i<_230.length;i++){_230[i].remove();}};return _230;},end:function(){if(this._parent){return this._parent;}else{return new this._NodeListCtor(0);}},concat:function(item){var t=aps.call(this,0),m=_21b.map(arguments,function(a){return aps.call(a,0);});return this._wrap(apc.apply(t,m),this);},map:function(func,obj){return this._wrap(_21b.map(this,func,obj),this);},forEach:function(_231,_232){_21e(this,_231,_232);return this;},filter:function(_233){var a=arguments,_234=this,_235=0;if(typeof _233=="string"){_234=_236._filterResult(this,a[0]);if(a.length==1){return _234._stash(this);}_235=1;}return this._wrap(_21b.filter(_234,a[_235],a[_235+1]),this);},instantiate:function(_237,_238){var c=lang.isFunction(_237)?_237:lang.getObject(_237);_238=_238||{};return this.forEach(function(node){new c(_238,node);});},at:function(){var t=new this._NodeListCtor(0);_21e(arguments,function(i){if(i<0){i=this.length+i;}if(this[i]){t.push(this[i]);}},this);return t._stash(this);}});function _239(_23a,_23b){var _23c=function(_23d,root){if(typeof root=="string"){root=dom.byId(root);if(!root){return new _23b([]);}}var _23e=typeof _23d=="string"?_23a(_23d,root):_23d?_23d.orphan?_23d:[_23d]:[];if(_23e.orphan){return _23e;}return new _23b(_23e);};_23c.matches=_23a.match||function(node,_23f,root){return _23c.filter([node],_23f,root).length>0;};_23c.filter=_23a.filter||function(_240,_241,root){return _23c(_241,root).filter(function(node){return _21b.indexOf(_240,node)>-1;});};if(typeof _23a!="function"){var _242=_23a.search;_23a=function(_243,root){return _242(root||document,_243);};}return _23c;};var _236=_239(_21d,_227);dojo.query=_239(_21d,function(_244){return _227(_244);});_236.load=function(id,_245,_246){_21c.load(id,_245,function(_247){_246(_239(_247,_227));});};dojo._filterQueryResult=_236._filterResult=function(_248,_249,root){return new _227(_236.filter(_248,_249,root));};dojo.NodeList=_236.NodeList=_227;return _236;});},"dojo/has":function(){define(["require","module"],function(_24a,_24b){var has=_24a.has||function(){};if(!1){var _24c=typeof window!="undefined"&&typeof location!="undefined"&&typeof document!="undefined"&&window.location==location&&window.document==document,_24d=this,doc=_24c&&document,_24e=doc&&doc.createElement("DiV"),_24f=(_24b.config&&_24b.config())||{};has=function(name){return typeof _24f[name]=="function"?(_24f[name]=_24f[name](_24d,doc,_24e)):_24f[name];};has.cache=_24f;has.add=function(name,test,now,_250){(typeof _24f[name]=="undefined"||_250)&&(_24f[name]=test);return now&&has(name);};1||has.add("host-browser",_24c);1||has.add("dom",_24c);1||has.add("dojo-dom-ready-api",1);1||has.add("dojo-sniff",1);}if(1){has.add("dom-addeventlistener",!!document.addEventListener);has.add("touch","ontouchstart" in document);has.add("device-width",screen.availWidth||innerWidth);var form=document.createElement("form");has.add("dom-attributes-explicit",form.attributes.length==0);has.add("dom-attributes-specified-flag",form.attributes.length>0&&form.attributes.length<40);}has.clearElement=function(_251){_251.innerHTML="";return _251;};has.normalize=function(id,_252){var _253=id.match(/[\?:]|[^:\?]*/g),i=0,get=function(skip){var term=_253[i++];if(term==":"){return 0;}else{if(_253[i++]=="?"){if(!skip&&has(term)){return get();}else{get(true);return get(skip);}}return term||0;}};id=get();return id&&_252(id);};has.load=function(id,_254,_255){if(id){_254([id],_255);}else{_255();}};return has;});},"dojo/_base/loader":function(){define(["./kernel","../has","require","module","./json","./lang","./array"],function(dojo,has,_256,_257,json,lang,_258){if(!1){console.error("cannot load the Dojo v1.x loader with a foreign loader");return 0;}1||has.add("dojo-fast-sync-require",1);var _259=function(id){return {src:_257.id,id:id};},_25a=function(name){return name.replace(/\./g,"/");},_25b=/\/\/>>built/,_25c=[],_25d=[],_25e=function(mid,_25f,_260){_25c.push(_260);_258.forEach(mid.split(","),function(mid){var _261=_262(mid,_25f.module);_25d.push(_261);_263(_261);});_264();},_264=(1?function(){var _265,mid;for(mid in _266){_265=_266[mid];if(_265.noReqPluginCheck===undefined){_265.noReqPluginCheck=/loadInit\!/.test(mid)||/require\!/.test(mid)?1:0;}if(!_265.executed&&!_265.noReqPluginCheck&&_265.injected==_267){return;}}_268(function(){var _269=_25c;_25c=[];_258.forEach(_269,function(cb){cb(1);});});}:(function(){var _26a,_26b=function(m){_26a[m.mid]=1;for(var t,_26c,deps=m.deps||[],i=0;i<deps.length;i++){_26c=deps[i];if(!(t=_26a[_26c.mid])){if(t===0||!_26b(_26c)){_26a[m.mid]=0;return false;}}}return true;};return function(){var _26d,mid;_26a={};for(mid in _266){_26d=_266[mid];if(_26d.executed||_26d.noReqPluginCheck){_26a[mid]=1;}else{if(_26d.noReqPluginCheck!==0){_26d.noReqPluginCheck=/loadInit\!/.test(mid)||/require\!/.test(mid)?1:0;}if(_26d.noReqPluginCheck){_26a[mid]=1;}else{if(_26d.injected!==_299){_26a[mid]=0;}}}}for(var t,i=0,end=_25d.length;i<end;i++){_26d=_25d[i];if(!(t=_26a[_26d.mid])){if(t===0||!_26b(_26d)){return;}}}_268(function(){var _26e=_25c;_25c=[];_258.forEach(_26e,function(cb){cb(1);});});};})()),_26f=function(mid,_270,_271){_270([mid],function(_272){_270(_272.names,function(){for(var _273="",args=[],i=0;i<arguments.length;i++){_273+="var "+_272.names[i]+"= arguments["+i+"]; ";args.push(arguments[i]);}eval(_273);var _274=_270.module,_275=[],_276,_277={provide:function(_278){_278=_25a(_278);var _279=_262(_278,_274);if(_279!==_274){_29f(_279);}},require:function(_27a,_27b){_27a=_25a(_27a);_27b&&(_262(_27a,_274).result=_29a);_275.push(_27a);},requireLocalization:function(_27c,_27d,_27e){if(!_276){_276=["dojo/i18n"];}_27e=(_27e||dojo.locale).toLowerCase();_27c=_25a(_27c)+"/nls/"+(/root/i.test(_27e)?"":_27e+"/")+_25a(_27d);if(_262(_27c,_274).isXd){_276.push("dojo/i18n!"+_27c);}},loadInit:function(f){f();}},hold={},p;try{for(p in _277){hold[p]=dojo[p];dojo[p]=_277[p];}_272.def.apply(null,args);}catch(e){_27f("error",[_259("failedDojoLoadInit"),e]);}finally{for(p in _277){dojo[p]=hold[p];}}if(_276){_275=_275.concat(_276);}if(_275.length){_25e(_275.join(","),_270,_271);}else{_271();}});});},_280=function(text,_281,_282){var _283=/\(|\)/g,_284=1,_285;_283.lastIndex=_281;while((_285=_283.exec(text))){if(_285[0]==")"){_284-=1;}else{_284+=1;}if(_284==0){break;}}if(_284!=0){throw "unmatched paren around character "+_283.lastIndex+" in: "+text;}return [dojo.trim(text.substring(_282,_283.lastIndex))+";\n",_283.lastIndex];},_286=/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,_287=/(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,_288=/(^|\s)(require|define)\s*\(/m,_289=function(text,_28a){var _28b,_28c,_28d,_28e,_28f=[],_290=[],_291=[];_28a=_28a||text.replace(_286,function(_292){_287.lastIndex=_288.lastIndex=0;return (_287.test(_292)||_288.test(_292))?"":_292;});while((_28b=_287.exec(_28a))){_28c=_287.lastIndex;_28d=_28c-_28b[0].length;_28e=_280(_28a,_28c,_28d);if(_28b[2]=="loadInit"){_28f.push(_28e[0]);}else{_290.push(_28e[0]);}_287.lastIndex=_28e[1];}_291=_28f.concat(_290);if(_291.length||!_288.test(_28a)){return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g,"\n0 && dojo.loadInit("),_291.join(""),_291];}else{return 0;}},_293=function(_294,text){var _295,id,_296=[],_297=[];if(_25b.test(text)||!(_295=_289(text))){return 0;}id=_294.mid+"-*loadInit";for(var p in _262("dojo",_294).result.scopeMap){_296.push(p);_297.push("\""+p+"\"");}return "// xdomain rewrite of "+_294.mid+"\n"+"define('"+id+"',{\n"+"\tnames:"+dojo.toJson(_296)+",\n"+"\tdef:function("+_296.join(",")+"){"+_295[1]+"}"+"});\n\n"+"define("+dojo.toJson(_296.concat(["dojo/loadInit!"+id]))+", function("+_296.join(",")+"){\n"+_295[0]+"});";},_298=_256.initSyncLoader(_25e,_264,_293),sync=_298.sync,_267=_298.requested,_299=_298.arrived,_29a=_298.nonmodule,_29b=_298.executing,_29c=_298.executed,_29d=_298.syncExecStack,_266=_298.modules,_29e=_298.execQ,_262=_298.getModule,_263=_298.injectModule,_29f=_298.setArrived,_27f=_298.signal,_2a0=_298.finishExec,_2a1=_298.execModule,_2a2=_298.getLegacyMode,_268=_298.guardCheckComplete;_25e=_298.dojoRequirePlugin;dojo.provide=function(mid){var _2a3=_29d[0],_2a4=lang.mixin(_262(_25a(mid),_256.module),{executed:_29b,result:lang.getObject(mid,true)});_29f(_2a4);if(_2a3){(_2a3.provides||(_2a3.provides=[])).push(function(){_2a4.result=lang.getObject(mid);delete _2a4.provides;_2a4.executed!==_29c&&_2a0(_2a4);});}return _2a4.result;};has.add("config-publishRequireResult",1,0,0);dojo.require=function(_2a5,_2a6){function _2a7(mid,_2a8){var _2a9=_262(_25a(mid),_256.module);if(_29d.length&&_29d[0].finish){_29d[0].finish.push(mid);return undefined;}if(_2a9.executed){return _2a9.result;}_2a8&&(_2a9.result=_29a);var _2aa=_2a2();_263(_2a9);_2aa=_2a2();if(_2a9.executed!==_29c&&_2a9.injected===_299){_298.guardCheckComplete(function(){_2a1(_2a9);});}if(_2a9.executed){return _2a9.result;}if(_2aa==sync){if(_2a9.cjs){_29e.unshift(_2a9);}else{_29d.length&&(_29d[0].finish=[mid]);}}else{_29e.push(_2a9);}return undefined;};var _2ab=_2a7(_2a5,_2a6);if(has("config-publishRequireResult")&&!lang.exists(_2a5)&&_2ab!==undefined){lang.setObject(_2a5,_2ab);}return _2ab;};dojo.loadInit=function(f){f();};dojo.registerModulePath=function(_2ac,_2ad){var _2ae={};_2ae[_2ac.replace(/\./g,"/")]=_2ad;_256({paths:_2ae});};dojo.platformRequire=function(_2af){var _2b0=(_2af.common||[]).concat(_2af[dojo._name]||_2af["default"]||[]),temp;while(_2b0.length){if(lang.isArray(temp=_2b0.shift())){dojo.require.apply(dojo,temp);}else{dojo.require(temp);}}};dojo.requireIf=dojo.requireAfterIf=function(_2b1,_2b2,_2b3){if(_2b1){dojo.require(_2b2,_2b3);}};dojo.requireLocalization=function(_2b4,_2b5,_2b6){_256(["../i18n"],function(i18n){i18n.getLocalization(_2b4,_2b5,_2b6);});};return {extractLegacyApiApplications:_289,require:_25e,loadInit:_26f};});},"dojo/json":function(){define(["./has"],function(has){"use strict";var _2b7=typeof JSON!="undefined";has.add("json-parse",_2b7);has.add("json-stringify",_2b7&&JSON.stringify({a:0},function(k,v){return v||1;})=="{\"a\":1}");if(has("json-stringify")){return JSON;}else{var _2b8=function(str){return ("\""+str.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");};return {parse:has("json-parse")?JSON.parse:function(str,_2b9){if(_2b9&&!/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){throw new SyntaxError("Invalid characters in JSON");}return eval("("+str+")");},stringify:function(_2ba,_2bb,_2bc){var _2bd;if(typeof _2bb=="string"){_2bc=_2bb;_2bb=null;}function _2be(it,_2bf,key){if(_2bb){it=_2bb(key,it);}var val,_2c0=typeof it;if(_2c0=="number"){return isFinite(it)?it+"":"null";}if(_2c0=="boolean"){return it+"";}if(it===null){return "null";}if(typeof it=="string"){return _2b8(it);}if(_2c0=="function"||_2c0=="undefined"){return _2bd;}if(typeof it.toJSON=="function"){return _2be(it.toJSON(key),_2bf,key);}if(it instanceof Date){return "\"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z\"".replace(/\{(\w+)(\+)?\}/g,function(t,prop,plus){var num=it["getUTC"+prop]()+(plus?1:0);return num<10?"0"+num:num;});}if(it.valueOf()!==it){return _2be(it.valueOf(),_2bf,key);}var _2c1=_2bc?(_2bf+_2bc):"";var sep=_2bc?" ":"";var _2c2=_2bc?"\n":"";if(it instanceof Array){var itl=it.length,res=[];for(key=0;key<itl;key++){var obj=it[key];val=_2be(obj,_2c1,key);if(typeof val!="string"){val="null";}res.push(_2c2+_2c1+val);}return "["+res.join(",")+_2c2+_2bf+"]";}var _2c3=[];for(key in it){var _2c4;if(it.hasOwnProperty(key)){if(typeof key=="number"){_2c4="\""+key+"\"";}else{if(typeof key=="string"){_2c4=_2b8(key);}else{continue;}}val=_2be(it[key],_2c1,key);if(typeof val!="string"){continue;}_2c3.push(_2c2+_2c1+_2c4+":"+sep+val);}}return "{"+_2c3.join(",")+_2c2+_2bf+"}";};return _2be(_2ba,"","");}};}});},"dojo/_base/declare":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var mix=lang.mixin,op=Object.prototype,opts=op.toString,xtor=new Function,_2c5=0,_2c6="constructor";function err(msg,cls){throw new Error("declare"+(cls?" "+cls:"")+": "+msg);};function _2c7(_2c8,_2c9){var _2ca=[],_2cb=[{cls:0,refs:[]}],_2cc={},_2cd=1,l=_2c8.length,i=0,j,lin,base,top,_2ce,rec,name,refs;for(;i<l;++i){base=_2c8[i];if(!base){err("mixin #"+i+" is unknown. Did you use dojo.require to pull it in?",_2c9);}else{if(opts.call(base)!="[object Function]"){err("mixin #"+i+" is not a callable constructor.",_2c9);}}lin=base._meta?base._meta.bases:[base];top=0;for(j=lin.length-1;j>=0;--j){_2ce=lin[j].prototype;if(!_2ce.hasOwnProperty("declaredClass")){_2ce.declaredClass="uniqName_"+(_2c5++);}name=_2ce.declaredClass;if(!_2cc.hasOwnProperty(name)){_2cc[name]={count:0,refs:[],cls:lin[j]};++_2cd;}rec=_2cc[name];if(top&&top!==rec){rec.refs.push(top);++top.count;}top=rec;}++top.count;_2cb[0].refs.push(top);}while(_2cb.length){top=_2cb.pop();_2ca.push(top.cls);--_2cd;while(refs=top.refs,refs.length==1){top=refs[0];if(!top||--top.count){top=0;break;}_2ca.push(top.cls);--_2cd;}if(top){for(i=0,l=refs.length;i<l;++i){top=refs[i];if(!--top.count){_2cb.push(top);}}}}if(_2cd){err("can't build consistent linearization",_2c9);}base=_2c8[0];_2ca[0]=base?base._meta&&base===_2ca[_2ca.length-base._meta.bases.length]?base._meta.bases.length:1:0;return _2ca;};function _2cf(args,a,f){var name,_2d0,_2d1,_2d2,meta,base,_2d3,opf,pos,_2d4=this._inherited=this._inherited||{};if(typeof args=="string"){name=args;args=a;a=f;}f=0;_2d2=args.callee;name=name||_2d2.nom;if(!name){err("can't deduce a name to call inherited()",this.declaredClass);}meta=this.constructor._meta;_2d1=meta.bases;pos=_2d4.p;if(name!=_2c6){if(_2d4.c!==_2d2){pos=0;base=_2d1[0];meta=base._meta;if(meta.hidden[name]!==_2d2){_2d0=meta.chains;if(_2d0&&typeof _2d0[name]=="string"){err("calling chained method with inherited: "+name,this.declaredClass);}do{meta=base._meta;_2d3=base.prototype;if(meta&&(_2d3[name]===_2d2&&_2d3.hasOwnProperty(name)||meta.hidden[name]===_2d2)){break;}}while(base=_2d1[++pos]);pos=base?pos:-1;}}base=_2d1[++pos];if(base){_2d3=base.prototype;if(base._meta&&_2d3.hasOwnProperty(name)){f=_2d3[name];}else{opf=op[name];do{_2d3=base.prototype;f=_2d3[name];if(f&&(base._meta?_2d3.hasOwnProperty(name):f!==opf)){break;}}while(base=_2d1[++pos]);}}f=base&&f||op[name];}else{if(_2d4.c!==_2d2){pos=0;meta=_2d1[0]._meta;if(meta&&meta.ctor!==_2d2){_2d0=meta.chains;if(!_2d0||_2d0.constructor!=="manual"){err("calling chained constructor with inherited",this.declaredClass);}while(base=_2d1[++pos]){meta=base._meta;if(meta&&meta.ctor===_2d2){break;}}pos=base?pos:-1;}}while(base=_2d1[++pos]){meta=base._meta;f=meta?meta.ctor:base;if(f){break;}}f=base&&f;}_2d4.c=f;_2d4.p=pos;if(f){return a===true?f:f.apply(this,a||args);}};function _2d5(name,args){if(typeof name=="string"){return this.__inherited(name,args,true);}return this.__inherited(name,true);};function _2d6(args,a1,a2){var f=this.getInherited(args,a1);if(f){return f.apply(this,a2||a1||args);}};var _2d7=dojo.config.isDebug?_2d6:_2cf;function _2d8(cls){var _2d9=this.constructor._meta.bases;for(var i=0,l=_2d9.length;i<l;++i){if(_2d9[i]===cls){return true;}}return this instanceof cls;};function _2da(_2db,_2dc){for(var name in _2dc){if(name!=_2c6&&_2dc.hasOwnProperty(name)){_2db[name]=_2dc[name];}}if(has("bug-for-in-skips-shadowed")){for(var _2dd=lang._extraNames,i=_2dd.length;i;){name=_2dd[--i];if(name!=_2c6&&_2dc.hasOwnProperty(name)){_2db[name]=_2dc[name];}}}};function _2de(_2df,_2e0){var name,t;for(name in _2e0){t=_2e0[name];if((t!==op[name]||!(name in op))&&name!=_2c6){if(opts.call(t)=="[object Function]"){t.nom=name;}_2df[name]=t;}}if(has("bug-for-in-skips-shadowed")){for(var _2e1=lang._extraNames,i=_2e1.length;i;){name=_2e1[--i];t=_2e0[name];if((t!==op[name]||!(name in op))&&name!=_2c6){if(opts.call(t)=="[object Function]"){t.nom=name;}_2df[name]=t;}}}return _2df;};function _2e2(_2e3){_2e4.safeMixin(this.prototype,_2e3);return this;};function _2e5(_2e6){return _2e4([this].concat(_2e6));};function _2e7(_2e8,_2e9){return function(){var a=arguments,args=a,a0=a[0],f,i,m,l=_2e8.length,_2ea;if(!(this instanceof a.callee)){return _2eb(a);}if(_2e9&&(a0&&a0.preamble||this.preamble)){_2ea=new Array(_2e8.length);_2ea[0]=a;for(i=0;;){a0=a[0];if(a0){f=a0.preamble;if(f){a=f.apply(this,a)||a;}}f=_2e8[i].prototype;f=f.hasOwnProperty("preamble")&&f.preamble;if(f){a=f.apply(this,a)||a;}if(++i==l){break;}_2ea[i]=a;}}for(i=l-1;i>=0;--i){f=_2e8[i];m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,_2ea?_2ea[i]:a);}}f=this.postscript;if(f){f.apply(this,args);}};};function _2ec(ctor,_2ed){return function(){var a=arguments,t=a,a0=a[0],f;if(!(this instanceof a.callee)){return _2eb(a);}if(_2ed){if(a0){f=a0.preamble;if(f){t=f.apply(this,t)||t;}}f=this.preamble;if(f){f.apply(this,t);}}if(ctor){ctor.apply(this,a);}f=this.postscript;if(f){f.apply(this,a);}};};function _2ee(_2ef){return function(){var a=arguments,i=0,f,m;if(!(this instanceof a.callee)){return _2eb(a);}for(;f=_2ef[i];++i){m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,a);break;}}f=this.postscript;if(f){f.apply(this,a);}};};function _2f0(name,_2f1,_2f2){return function(){var b,m,f,i=0,step=1;if(_2f2){i=_2f1.length-1;step=-1;}for(;b=_2f1[i];i+=step){m=b._meta;f=(m?m.hidden:b.prototype)[name];if(f){f.apply(this,arguments);}}};};function _2f3(ctor){xtor.prototype=ctor.prototype;var t=new xtor;xtor.prototype=null;return t;};function _2eb(args){var ctor=args.callee,t=_2f3(ctor);ctor.apply(t,args);return t;};function _2e4(_2f4,_2f5,_2f6){if(typeof _2f4!="string"){_2f6=_2f5;_2f5=_2f4;_2f4="";}_2f6=_2f6||{};var _2f7,i,t,ctor,name,_2f8,_2f9,_2fa=1,_2fb=_2f5;if(opts.call(_2f5)=="[object Array]"){_2f8=_2c7(_2f5,_2f4);t=_2f8[0];_2fa=_2f8.length-t;_2f5=_2f8[_2fa];}else{_2f8=[0];if(_2f5){if(opts.call(_2f5)=="[object Function]"){t=_2f5._meta;_2f8=_2f8.concat(t?t.bases:_2f5);}else{err("base class is not a callable constructor.",_2f4);}}else{if(_2f5!==null){err("unknown base class. Did you use dojo.require to pull it in?",_2f4);}}}if(_2f5){for(i=_2fa-1;;--i){_2f7=_2f3(_2f5);if(!i){break;}t=_2f8[i];(t._meta?_2da:mix)(_2f7,t.prototype);ctor=new Function;ctor.superclass=_2f5;ctor.prototype=_2f7;_2f5=_2f7.constructor=ctor;}}else{_2f7={};}_2e4.safeMixin(_2f7,_2f6);t=_2f6.constructor;if(t!==op.constructor){t.nom=_2c6;_2f7.constructor=t;}for(i=_2fa-1;i;--i){t=_2f8[i]._meta;if(t&&t.chains){_2f9=mix(_2f9||{},t.chains);}}if(_2f7["-chains-"]){_2f9=mix(_2f9||{},_2f7["-chains-"]);}t=!_2f9||!_2f9.hasOwnProperty(_2c6);_2f8[0]=ctor=(_2f9&&_2f9.constructor==="manual")?_2ee(_2f8):(_2f8.length==1?_2ec(_2f6.constructor,t):_2e7(_2f8,t));ctor._meta={bases:_2f8,hidden:_2f6,chains:_2f9,parents:_2fb,ctor:_2f6.constructor};ctor.superclass=_2f5&&_2f5.prototype;ctor.extend=_2e2;ctor.createSubclass=_2e5;ctor.prototype=_2f7;_2f7.constructor=ctor;_2f7.getInherited=_2d5;_2f7.isInstanceOf=_2d8;_2f7.inherited=_2d7;_2f7.__inherited=_2cf;if(_2f4){_2f7.declaredClass=_2f4;lang.setObject(_2f4,ctor);}if(_2f9){for(name in _2f9){if(_2f7[name]&&typeof _2f9[name]=="string"&&name!=_2c6){t=_2f7[name]=_2f0(name,_2f8,_2f9[name]==="after");t.nom=name;}}}return ctor;};dojo.safeMixin=_2e4.safeMixin=_2de;dojo.declare=_2e4;return _2e4;});},"dojo/dom":function(){define(["./sniff","./_base/lang","./_base/window"],function(has,lang,win){if(has("ie")<=7){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}}var dom={};if(has("ie")){dom.byId=function(id,doc){if(typeof id!="string"){return id;}var _2fc=doc||win.doc,te=id&&_2fc.getElementById(id);if(te&&(te.attributes.id.value==id||te.id==id)){return te;}else{var eles=_2fc.all[id];if(!eles||eles.nodeName){eles=[eles];}var i=0;while((te=eles[i++])){if((te.attributes&&te.attributes.id&&te.attributes.id.value==id)||te.id==id){return te;}}}};}else{dom.byId=function(id,doc){return ((typeof id=="string")?(doc||win.doc).getElementById(id):id)||null;};}dom.isDescendant=function(node,_2fd){try{node=dom.byId(node);_2fd=dom.byId(_2fd);while(node){if(node==_2fd){return true;}node=node.parentNode;}}catch(e){}return false;};dom.setSelectable=function(node,_2fe){node=dom.byId(node);if(has("mozilla")){node.style.MozUserSelect=_2fe?"":"none";}else{if(has("khtml")||has("webkit")){node.style.KhtmlUserSelect=_2fe?"auto":"none";}else{if(has("ie")){var v=(node.unselectable=_2fe?"":"on"),cs=node.getElementsByTagName("*"),i=0,l=cs.length;for(;i<l;++i){cs.item(i).unselectable=v;}}}}};return dom;});},"dojo/_base/browser":function(){if(require.has){require.has.add("config-selectorEngine","acme");}define(["../ready","./kernel","./connect","./unload","./window","./event","./html","./NodeList","../query","./xhr","./fx"],function(dojo){return dojo;});},"dojo/selector/acme":function(){define(["../dom","../sniff","../_base/array","../_base/lang","../_base/window"],function(dom,has,_2ff,lang,win){var trim=lang.trim;var each=_2ff.forEach;var _300=function(){return win.doc;};var _301=(_300().compatMode)=="BackCompat";var _302=">~+";var _303=false;var _304=function(){return true;};var _305=function(_306){if(_302.indexOf(_306.slice(-1))>=0){_306+=" * ";}else{_306+=" ";}var ts=function(s,e){return trim(_306.slice(s,e));};var _307=[];var _308=-1,_309=-1,_30a=-1,_30b=-1,_30c=-1,inId=-1,_30d=-1,_30e,lc="",cc="",_30f;var x=0,ql=_306.length,_310=null,_311=null;var _312=function(){if(_30d>=0){var tv=(_30d==x)?null:ts(_30d,x);_310[(_302.indexOf(tv)<0)?"tag":"oper"]=tv;_30d=-1;}};var _313=function(){if(inId>=0){_310.id=ts(inId,x).replace(/\\/g,"");inId=-1;}};var _314=function(){if(_30c>=0){_310.classes.push(ts(_30c+1,x).replace(/\\/g,""));_30c=-1;}};var _315=function(){_313();_312();_314();};var _316=function(){_315();if(_30b>=0){_310.pseudos.push({name:ts(_30b+1,x)});}_310.loops=(_310.pseudos.length||_310.attrs.length||_310.classes.length);_310.oquery=_310.query=ts(_30f,x);_310.otag=_310.tag=(_310["oper"])?null:(_310.tag||"*");if(_310.tag){_310.tag=_310.tag.toUpperCase();}if(_307.length&&(_307[_307.length-1].oper)){_310.infixOper=_307.pop();_310.query=_310.infixOper.query+" "+_310.query;}_307.push(_310);_310=null;};for(;lc=cc,cc=_306.charAt(x),x<ql;x++){if(lc=="\\"){continue;}if(!_310){_30f=x;_310={query:null,pseudos:[],attrs:[],classes:[],tag:null,oper:null,id:null,getTag:function(){return _303?this.otag:this.tag;}};_30d=x;}if(_30e){if(cc==_30e){_30e=null;}continue;}else{if(cc=="'"||cc=="\""){_30e=cc;continue;}}if(_308>=0){if(cc=="]"){if(!_311.attr){_311.attr=ts(_308+1,x);}else{_311.matchFor=ts((_30a||_308+1),x);}var cmf=_311.matchFor;if(cmf){if((cmf.charAt(0)=="\"")||(cmf.charAt(0)=="'")){_311.matchFor=cmf.slice(1,-1);}}if(_311.matchFor){_311.matchFor=_311.matchFor.replace(/\\/g,"");}_310.attrs.push(_311);_311=null;_308=_30a=-1;}else{if(cc=="="){var _317=("|~^$*".indexOf(lc)>=0)?lc:"";_311.type=_317+cc;_311.attr=ts(_308+1,x-_317.length);_30a=x+1;}}}else{if(_309>=0){if(cc==")"){if(_30b>=0){_311.value=ts(_309+1,x);}_30b=_309=-1;}}else{if(cc=="#"){_315();inId=x+1;}else{if(cc=="."){_315();_30c=x;}else{if(cc==":"){_315();_30b=x;}else{if(cc=="["){_315();_308=x;_311={};}else{if(cc=="("){if(_30b>=0){_311={name:ts(_30b+1,x),value:null};_310.pseudos.push(_311);}_309=x;}else{if((cc==" ")&&(lc!=cc)){_316();}}}}}}}}}return _307;};var _318=function(_319,_31a){if(!_319){return _31a;}if(!_31a){return _319;}return function(){return _319.apply(window,arguments)&&_31a.apply(window,arguments);};};var _31b=function(i,arr){var r=arr||[];if(i){r.push(i);}return r;};var _31c=function(n){return (1==n.nodeType);};var _31d="";var _31e=function(elem,attr){if(!elem){return _31d;}if(attr=="class"){return elem.className||_31d;}if(attr=="for"){return elem.htmlFor||_31d;}if(attr=="style"){return elem.style.cssText||_31d;}return (_303?elem.getAttribute(attr):elem.getAttribute(attr,2))||_31d;};var _31f={"*=":function(attr,_320){return function(elem){return (_31e(elem,attr).indexOf(_320)>=0);};},"^=":function(attr,_321){return function(elem){return (_31e(elem,attr).indexOf(_321)==0);};},"$=":function(attr,_322){return function(elem){var ea=" "+_31e(elem,attr);var _323=ea.lastIndexOf(_322);return _323>-1&&(_323==(ea.length-_322.length));};},"~=":function(attr,_324){var tval=" "+_324+" ";return function(elem){var ea=" "+_31e(elem,attr)+" ";return (ea.indexOf(tval)>=0);};},"|=":function(attr,_325){var _326=_325+"-";return function(elem){var ea=_31e(elem,attr);return ((ea==_325)||(ea.indexOf(_326)==0));};},"=":function(attr,_327){return function(elem){return (_31e(elem,attr)==_327);};}};var _328=(typeof _300().firstChild.nextElementSibling=="undefined");var _329=!_328?"nextElementSibling":"nextSibling";var _32a=!_328?"previousElementSibling":"previousSibling";var _32b=(_328?_31c:_304);var _32c=function(node){while(node=node[_32a]){if(_32b(node)){return false;}}return true;};var _32d=function(node){while(node=node[_329]){if(_32b(node)){return false;}}return true;};var _32e=function(node){var root=node.parentNode;root=root.nodeType!=7?root:root.nextSibling;var i=0,tret=root.children||root.childNodes,ci=(node["_i"]||node.getAttribute("_i")||-1),cl=(root["_l"]||(typeof root.getAttribute!=="undefined"?root.getAttribute("_l"):-1));if(!tret){return -1;}var l=tret.length;if(cl==l&&ci>=0&&cl>=0){return ci;}if(has("ie")&&typeof root.setAttribute!=="undefined"){root.setAttribute("_l",l);}else{root["_l"]=l;}ci=-1;for(var te=root["firstElementChild"]||root["firstChild"];te;te=te[_329]){if(_32b(te)){if(has("ie")){te.setAttribute("_i",++i);}else{te["_i"]=++i;}if(node===te){ci=i;}}}return ci;};var _32f=function(elem){return !((_32e(elem))%2);};var _330=function(elem){return ((_32e(elem))%2);};var _331={"checked":function(name,_332){return function(elem){return !!("checked" in elem?elem.checked:elem.selected);};},"disabled":function(name,_333){return function(elem){return elem.disabled;};},"enabled":function(name,_334){return function(elem){return !elem.disabled;};},"first-child":function(){return _32c;},"last-child":function(){return _32d;},"only-child":function(name,_335){return function(node){return _32c(node)&&_32d(node);};},"empty":function(name,_336){return function(elem){var cn=elem.childNodes;var cnl=elem.childNodes.length;for(var x=cnl-1;x>=0;x--){var nt=cn[x].nodeType;if((nt===1)||(nt==3)){return false;}}return true;};},"contains":function(name,_337){var cz=_337.charAt(0);if(cz=="\""||cz=="'"){_337=_337.slice(1,-1);}return function(elem){return (elem.innerHTML.indexOf(_337)>=0);};},"not":function(name,_338){var p=_305(_338)[0];var _339={el:1};if(p.tag!="*"){_339.tag=1;}if(!p.classes.length){_339.classes=1;}var ntf=_33a(p,_339);return function(elem){return (!ntf(elem));};},"nth-child":function(name,_33b){var pi=parseInt;if(_33b=="odd"){return _330;}else{if(_33b=="even"){return _32f;}}if(_33b.indexOf("n")!=-1){var _33c=_33b.split("n",2);var pred=_33c[0]?((_33c[0]=="-")?-1:pi(_33c[0])):1;var idx=_33c[1]?pi(_33c[1]):0;var lb=0,ub=-1;if(pred>0){if(idx<0){idx=(idx%pred)&&(pred+(idx%pred));}else{if(idx>0){if(idx>=pred){lb=idx-idx%pred;}idx=idx%pred;}}}else{if(pred<0){pred*=-1;if(idx>0){ub=idx;idx=idx%pred;}}}if(pred>0){return function(elem){var i=_32e(elem);return (i>=lb)&&(ub<0||i<=ub)&&((i%pred)==idx);};}else{_33b=idx;}}var _33d=pi(_33b);return function(elem){return (_32e(elem)==_33d);};}};var _33e=(has("ie")&&(has("ie")<9||has("quirks")))?function(cond){var clc=cond.toLowerCase();if(clc=="class"){cond="className";}return function(elem){return (_303?elem.getAttribute(cond):elem[cond]||elem[clc]);};}:function(cond){return function(elem){return (elem&&elem.getAttribute&&elem.hasAttribute(cond));};};var _33a=function(_33f,_340){if(!_33f){return _304;}_340=_340||{};var ff=null;if(!("el" in _340)){ff=_318(ff,_31c);}if(!("tag" in _340)){if(_33f.tag!="*"){ff=_318(ff,function(elem){return (elem&&((_303?elem.tagName:elem.tagName.toUpperCase())==_33f.getTag()));});}}if(!("classes" in _340)){each(_33f.classes,function(_341,idx,arr){var re=new RegExp("(?:^|\\s)"+_341+"(?:\\s|$)");ff=_318(ff,function(elem){return re.test(elem.className);});ff.count=idx;});}if(!("pseudos" in _340)){each(_33f.pseudos,function(_342){var pn=_342.name;if(_331[pn]){ff=_318(ff,_331[pn](pn,_342.value));}});}if(!("attrs" in _340)){each(_33f.attrs,function(attr){var _343;var a=attr.attr;if(attr.type&&_31f[attr.type]){_343=_31f[attr.type](a,attr.matchFor);}else{if(a.length){_343=_33e(a);}}if(_343){ff=_318(ff,_343);}});}if(!("id" in _340)){if(_33f.id){ff=_318(ff,function(elem){return (!!elem&&(elem.id==_33f.id));});}}if(!ff){if(!("default" in _340)){ff=_304;}}return ff;};var _344=function(_345){return function(node,ret,bag){while(node=node[_329]){if(_328&&(!_31c(node))){continue;}if((!bag||_346(node,bag))&&_345(node)){ret.push(node);}break;}return ret;};};var _347=function(_348){return function(root,ret,bag){var te=root[_329];while(te){if(_32b(te)){if(bag&&!_346(te,bag)){break;}if(_348(te)){ret.push(te);}}te=te[_329];}return ret;};};var _349=function(_34a){_34a=_34a||_304;return function(root,ret,bag){var te,x=0,tret=root.children||root.childNodes;while(te=tret[x++]){if(_32b(te)&&(!bag||_346(te,bag))&&(_34a(te,x))){ret.push(te);}}return ret;};};var _34b=function(node,root){var pn=node.parentNode;while(pn){if(pn==root){break;}pn=pn.parentNode;}return !!pn;};var _34c={};var _34d=function(_34e){var _34f=_34c[_34e.query];if(_34f){return _34f;}var io=_34e.infixOper;var oper=(io?io.oper:"");var _350=_33a(_34e,{el:1});var qt=_34e.tag;var _351=("*"==qt);var ecs=_300()["getElementsByClassName"];if(!oper){if(_34e.id){_350=(!_34e.loops&&_351)?_304:_33a(_34e,{el:1,id:1});_34f=function(root,arr){var te=dom.byId(_34e.id,(root.ownerDocument||root));if(!te||!_350(te)){return;}if(9==root.nodeType){return _31b(te,arr);}else{if(_34b(te,root)){return _31b(te,arr);}}};}else{if(ecs&&/\{\s*\[native code\]\s*\}/.test(String(ecs))&&_34e.classes.length&&!_301){_350=_33a(_34e,{el:1,classes:1,id:1});var _352=_34e.classes.join(" ");_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tret=root.getElementsByClassName(_352);while((te=tret[x++])){if(_350(te,root)&&_346(te,bag)){ret.push(te);}}return ret;};}else{if(!_351&&!_34e.loops){_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tag=_34e.getTag(),tret=tag?root.getElementsByTagName(tag):[];while((te=tret[x++])){if(_346(te,bag)){ret.push(te);}}return ret;};}else{_350=_33a(_34e,{el:1,tag:1,id:1});_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tag=_34e.getTag(),tret=tag?root.getElementsByTagName(tag):[];while((te=tret[x++])){if(_350(te,root)&&_346(te,bag)){ret.push(te);}}return ret;};}}}}else{var _353={el:1};if(_351){_353.tag=1;}_350=_33a(_34e,_353);if("+"==oper){_34f=_344(_350);}else{if("~"==oper){_34f=_347(_350);}else{if(">"==oper){_34f=_349(_350);}}}}return _34c[_34e.query]=_34f;};var _354=function(root,_355){var _356=_31b(root),qp,x,te,qpl=_355.length,bag,ret;for(var i=0;i<qpl;i++){ret=[];qp=_355[i];x=_356.length-1;if(x>0){bag={};ret.nozip=true;}var gef=_34d(qp);for(var j=0;(te=_356[j]);j++){gef(te,ret,bag);}if(!ret.length){break;}_356=ret;}return ret;};var _357={},_358={};var _359=function(_35a){var _35b=_305(trim(_35a));if(_35b.length==1){var tef=_34d(_35b[0]);return function(root){var r=tef(root,[]);if(r){r.nozip=true;}return r;};}return function(root){return _354(root,_35b);};};var _35c=has("ie")?"commentStrip":"nozip";var qsa="querySelectorAll";var _35d=!!_300()[qsa];var _35e=/\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g;var _35f=function(_360,pre,ch,post){return ch?(pre?pre+" ":"")+ch+(post?" "+post:""):_360;};var _361=/([^[]*)([^\]]*])?/g;var _362=function(_363,_364,att){return _364.replace(_35e,_35f)+(att||"");};var _365=function(_366,_367){_366=_366.replace(_361,_362);if(_35d){var _368=_358[_366];if(_368&&!_367){return _368;}}var _369=_357[_366];if(_369){return _369;}var qcz=_366.charAt(0);var _36a=(-1==_366.indexOf(" "));if((_366.indexOf("#")>=0)&&(_36a)){_367=true;}var _36b=(_35d&&(!_367)&&(_302.indexOf(qcz)==-1)&&(!has("ie")||(_366.indexOf(":")==-1))&&(!(_301&&(_366.indexOf(".")>=0)))&&(_366.indexOf(":contains")==-1)&&(_366.indexOf(":checked")==-1)&&(_366.indexOf("|=")==-1));if(_36b){var tq=(_302.indexOf(_366.charAt(_366.length-1))>=0)?(_366+" *"):_366;return _358[_366]=function(root){try{if(!((9==root.nodeType)||_36a)){throw "";}var r=root[qsa](tq);r[_35c]=true;return r;}catch(e){return _365(_366,true)(root);}};}else{var _36c=_366.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g);return _357[_366]=((_36c.length<2)?_359(_366):function(root){var _36d=0,ret=[],tp;while((tp=_36c[_36d++])){ret=ret.concat(_359(tp)(root));}return ret;});}};var _36e=0;var _36f=has("ie")?function(node){if(_303){return (node.getAttribute("_uid")||node.setAttribute("_uid",++_36e)||_36e);}else{return node.uniqueID;}}:function(node){return (node._uid||(node._uid=++_36e));};var _346=function(node,bag){if(!bag){return 1;}var id=_36f(node);if(!bag[id]){return bag[id]=1;}return 0;};var _370="_zipIdx";var _371=function(arr){if(arr&&arr.nozip){return arr;}var ret=[];if(!arr||!arr.length){return ret;}if(arr[0]){ret.push(arr[0]);}if(arr.length<2){return ret;}_36e++;var x,te;if(has("ie")&&_303){var _372=_36e+"";arr[0].setAttribute(_370,_372);for(x=1;te=arr[x];x++){if(arr[x].getAttribute(_370)!=_372){ret.push(te);}te.setAttribute(_370,_372);}}else{if(has("ie")&&arr.commentStrip){try{for(x=1;te=arr[x];x++){if(_31c(te)){ret.push(te);}}}catch(e){}}else{if(arr[0]){arr[0][_370]=_36e;}for(x=1;te=arr[x];x++){if(arr[x][_370]!=_36e){ret.push(te);}te[_370]=_36e;}}}return ret;};var _373=function(_374,root){root=root||_300();var od=root.ownerDocument||root;_303=(od.createElement("div").tagName==="div");var r=_365(_374)(root);if(r&&r.nozip){return r;}return _371(r);};_373.filter=function(_375,_376,root){var _377=[],_378=_305(_376),_379=(_378.length==1&&!/[^\w#\.]/.test(_376))?_33a(_378[0]):function(node){return _2ff.indexOf(_373(_376,dom.byId(root)),node)!=-1;};for(var x=0,te;te=_375[x];x++){if(_379(te)){_377.push(te);}}return _377;};return _373;});},"dojo/errors/RequestTimeoutError":function(){define("dojo/errors/RequestTimeoutError",["./create","./RequestError"],function(_37a,_37b){return _37a("RequestTimeoutError",null,_37b,{dojoType:"timeout"});});},"dojo/dom-geometry":function(){define(["./sniff","./_base/window","./dom","./dom-style"],function(has,win,dom,_37c){var geom={};geom.boxModel="content-box";if(has("ie")){geom.boxModel=document.compatMode=="BackCompat"?"border-box":"content-box";}geom.getPadExtents=function getPadExtents(node,_37d){node=dom.byId(node);var s=_37d||_37c.getComputedStyle(node),px=_37c.toPixelValue,l=px(node,s.paddingLeft),t=px(node,s.paddingTop),r=px(node,s.paddingRight),b=px(node,s.paddingBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};var none="none";geom.getBorderExtents=function getBorderExtents(node,_37e){node=dom.byId(node);var px=_37c.toPixelValue,s=_37e||_37c.getComputedStyle(node),l=s.borderLeftStyle!=none?px(node,s.borderLeftWidth):0,t=s.borderTopStyle!=none?px(node,s.borderTopWidth):0,r=s.borderRightStyle!=none?px(node,s.borderRightWidth):0,b=s.borderBottomStyle!=none?px(node,s.borderBottomWidth):0;return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getPadBorderExtents=function getPadBorderExtents(node,_37f){node=dom.byId(node);var s=_37f||_37c.getComputedStyle(node),p=geom.getPadExtents(node,s),b=geom.getBorderExtents(node,s);return {l:p.l+b.l,t:p.t+b.t,r:p.r+b.r,b:p.b+b.b,w:p.w+b.w,h:p.h+b.h};};geom.getMarginExtents=function getMarginExtents(node,_380){node=dom.byId(node);var s=_380||_37c.getComputedStyle(node),px=_37c.toPixelValue,l=px(node,s.marginLeft),t=px(node,s.marginTop),r=px(node,s.marginRight),b=px(node,s.marginBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getMarginBox=function getMarginBox(node,_381){node=dom.byId(node);var s=_381||_37c.getComputedStyle(node),me=geom.getMarginExtents(node,s),l=node.offsetLeft-me.l,t=node.offsetTop-me.t,p=node.parentNode,px=_37c.toPixelValue,pcs;if(has("mozilla")){var sl=parseFloat(s.left),st=parseFloat(s.top);if(!isNaN(sl)&&!isNaN(st)){l=sl;t=st;}else{if(p&&p.style){pcs=_37c.getComputedStyle(p);if(pcs.overflow!="visible"){l+=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t+=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}}else{if(has("opera")||(has("ie")==8&&!has("quirks"))){if(p){pcs=_37c.getComputedStyle(p);l-=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t-=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}return {l:l,t:t,w:node.offsetWidth+me.w,h:node.offsetHeight+me.h};};geom.getContentBox=function getContentBox(node,_382){node=dom.byId(node);var s=_382||_37c.getComputedStyle(node),w=node.clientWidth,h,pe=geom.getPadExtents(node,s),be=geom.getBorderExtents(node,s);if(!w){w=node.offsetWidth;h=node.offsetHeight;}else{h=node.clientHeight;be.w=be.h=0;}if(has("opera")){pe.l+=be.l;pe.t+=be.t;}return {l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h};};function _383(node,l,t,w,h,u){u=u||"px";var s=node.style;if(!isNaN(l)){s.left=l+u;}if(!isNaN(t)){s.top=t+u;}if(w>=0){s.width=w+u;}if(h>=0){s.height=h+u;}};function _384(node){return node.tagName.toLowerCase()=="button"||node.tagName.toLowerCase()=="input"&&(node.getAttribute("type")||"").toLowerCase()=="button";};function _385(node){return geom.boxModel=="border-box"||node.tagName.toLowerCase()=="table"||_384(node);};geom.setContentSize=function setContentSize(node,box,_386){node=dom.byId(node);var w=box.w,h=box.h;if(_385(node)){var pb=geom.getPadBorderExtents(node,_386);if(w>=0){w+=pb.w;}if(h>=0){h+=pb.h;}}_383(node,NaN,NaN,w,h);};var _387={l:0,t:0,w:0,h:0};geom.setMarginBox=function setMarginBox(node,box,_388){node=dom.byId(node);var s=_388||_37c.getComputedStyle(node),w=box.w,h=box.h,pb=_385(node)?_387:geom.getPadBorderExtents(node,s),mb=geom.getMarginExtents(node,s);if(has("webkit")){if(_384(node)){var ns=node.style;if(w>=0&&!ns.width){ns.width="4px";}if(h>=0&&!ns.height){ns.height="4px";}}}if(w>=0){w=Math.max(w-pb.w-mb.w,0);}if(h>=0){h=Math.max(h-pb.h-mb.h,0);}_383(node,box.l,box.t,w,h);};geom.isBodyLtr=function isBodyLtr(doc){doc=doc||win.doc;return (win.body(doc).dir||doc.documentElement.dir||"ltr").toLowerCase()=="ltr";};geom.docScroll=function docScroll(doc){doc=doc||win.doc;var node=win.doc.parentWindow||win.doc.defaultView;return "pageXOffset" in node?{x:node.pageXOffset,y:node.pageYOffset}:(node=has("quirks")?win.body(doc):doc.documentElement)&&{x:geom.fixIeBiDiScrollLeft(node.scrollLeft||0,doc),y:node.scrollTop||0};};if(has("ie")){geom.getIeDocumentElementOffset=function getIeDocumentElementOffset(doc){doc=doc||win.doc;var de=doc.documentElement;if(has("ie")<8){var r=de.getBoundingClientRect(),l=r.left,t=r.top;if(has("ie")<7){l+=de.clientLeft;t+=de.clientTop;}return {x:l<0?0:l,y:t<0?0:t};}else{return {x:0,y:0};}};}geom.fixIeBiDiScrollLeft=function fixIeBiDiScrollLeft(_389,doc){doc=doc||win.doc;var ie=has("ie");if(ie&&!geom.isBodyLtr(doc)){var qk=has("quirks"),de=qk?win.body(doc):doc.documentElement,pwin=win.global;if(ie==6&&!qk&&pwin.frameElement&&de.scrollHeight>de.clientHeight){_389+=de.clientLeft;}return (ie<8||qk)?(_389+de.clientWidth-de.scrollWidth):-_389;}return _389;};geom.position=function(node,_38a){node=dom.byId(node);var db=win.body(node.ownerDocument),ret=node.getBoundingClientRect();ret={x:ret.left,y:ret.top,w:ret.right-ret.left,h:ret.bottom-ret.top};if(has("ie")){var _38b=geom.getIeDocumentElementOffset(node.ownerDocument);ret.x-=_38b.x+(has("quirks")?db.clientLeft+db.offsetLeft:0);ret.y-=_38b.y+(has("quirks")?db.clientTop+db.offsetTop:0);}if(_38a){var _38c=geom.docScroll(node.ownerDocument);ret.x+=_38c.x;ret.y+=_38c.y;}return ret;};geom.getMarginSize=function getMarginSize(node,_38d){node=dom.byId(node);var me=geom.getMarginExtents(node,_38d||_37c.getComputedStyle(node));var size=node.getBoundingClientRect();return {w:(size.right-size.left)+me.w,h:(size.bottom-size.top)+me.h};};geom.normalizeEvent=function(_38e){if(!("layerX" in _38e)){_38e.layerX=_38e.offsetX;_38e.layerY=_38e.offsetY;}if(!has("dom-addeventlistener")){var se=_38e.target;var doc=(se&&se.ownerDocument)||document;var _38f=has("quirks")?doc.body:doc.documentElement;var _390=geom.getIeDocumentElementOffset(doc);_38e.pageX=_38e.clientX+geom.fixIeBiDiScrollLeft(_38f.scrollLeft||0,doc)-_390.x;_38e.pageY=_38e.clientY+(_38f.scrollTop||0)-_390.y;}};return geom;});},"dojo/dom-style":function(){define("dojo/dom-style",["./sniff","./dom"],function(has,dom){var _391,_392={};if(has("webkit")){_391=function(node){var s;if(node.nodeType==1){var dv=node.ownerDocument.defaultView;s=dv.getComputedStyle(node,null);if(!s&&node.style){node.style.display="";s=dv.getComputedStyle(node,null);}}return s||{};};}else{if(has("ie")&&(has("ie")<9||has("quirks"))){_391=function(node){return node.nodeType==1&&node.currentStyle?node.currentStyle:{};};}else{_391=function(node){return node.nodeType==1?node.ownerDocument.defaultView.getComputedStyle(node,null):{};};}}_392.getComputedStyle=_391;var _393;if(!has("ie")){_393=function(_394,_395){return parseFloat(_395)||0;};}else{_393=function(_396,_397){if(!_397){return 0;}if(_397=="medium"){return 4;}if(_397.slice&&_397.slice(-2)=="px"){return parseFloat(_397);}var s=_396.style,rs=_396.runtimeStyle,cs=_396.currentStyle,_398=s.left,_399=rs.left;rs.left=cs.left;try{s.left=_397;_397=s.pixelLeft;}catch(e){_397=0;}s.left=_398;rs.left=_399;return _397;};}_392.toPixelValue=_393;var astr="DXImageTransform.Microsoft.Alpha";var af=function(n,f){try{return n.filters.item(astr);}catch(e){return f?{}:null;}};var _39a=has("ie")<9||(has("ie")&&has("quirks"))?function(node){try{return af(node).Opacity/100;}catch(e){return 1;}}:function(node){return _391(node).opacity;};var _39b=has("ie")<9||(has("ie")&&has("quirks"))?function(node,_39c){var ov=_39c*100,_39d=_39c==1;node.style.zoom=_39d?"":1;if(!af(node)){if(_39d){return _39c;}node.style.filter+=" progid:"+astr+"(Opacity="+ov+")";}else{af(node,1).Opacity=ov;}af(node,1).Enabled=!_39d;if(node.tagName.toLowerCase()=="tr"){for(var td=node.firstChild;td;td=td.nextSibling){if(td.tagName.toLowerCase()=="td"){_39b(td,_39c);}}}return _39c;}:function(node,_39e){return node.style.opacity=_39e;};var _39f={left:true,top:true};var _3a0=/margin|padding|width|height|max|min|offset/;function _3a1(node,type,_3a2){type=type.toLowerCase();if(has("ie")){if(_3a2=="auto"){if(type=="height"){return node.offsetHeight;}if(type=="width"){return node.offsetWidth;}}if(type=="fontweight"){switch(_3a2){case 700:return "bold";case 400:default:return "normal";}}}if(!(type in _39f)){_39f[type]=_3a0.test(type);}return _39f[type]?_393(node,_3a2):_3a2;};var _3a3=has("ie")?"styleFloat":"cssFloat",_3a4={"cssFloat":_3a3,"styleFloat":_3a3,"float":_3a3};_392.get=function getStyle(node,name){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");if(l==2&&op){return _39a(n);}name=_3a4[name]||name;var s=_392.getComputedStyle(n);return (l==1)?s:_3a1(n,name,s[name]||n.style[name]);};_392.set=function setStyle(node,name,_3a5){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");name=_3a4[name]||name;if(l==3){return op?_39b(n,_3a5):n.style[name]=_3a5;}for(var x in name){_392.set(node,x,name[x]);}return _392.getComputedStyle(n);};return _392;});},"dojo/dom-prop":function(){define(["exports","./_base/kernel","./sniff","./_base/lang","./dom","./dom-style","./dom-construct","./_base/connect"],function(_3a6,dojo,has,lang,dom,_3a7,ctr,conn){var _3a8={},_3a9=0,_3aa=dojo._scopeName+"attrid";_3a6.names={"class":"className","for":"htmlFor",tabindex:"tabIndex",readonly:"readOnly",colspan:"colSpan",frameborder:"frameBorder",rowspan:"rowSpan",valuetype:"valueType"};_3a6.get=function getProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3ab=_3a6.names[lc]||name;return node[_3ab];};_3a6.set=function setProp(node,name,_3ac){node=dom.byId(node);var l=arguments.length;if(l==2&&typeof name!="string"){for(var x in name){_3a6.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_3ad=_3a6.names[lc]||name;if(_3ad=="style"&&typeof _3ac!="string"){_3a7.set(node,_3ac);return node;}if(_3ad=="innerHTML"){if(has("ie")&&node.tagName.toLowerCase() in {col:1,colgroup:1,table:1,tbody:1,tfoot:1,thead:1,tr:1,title:1}){ctr.empty(node);node.appendChild(ctr.toDom(_3ac,node.ownerDocument));}else{node[_3ad]=_3ac;}return node;}if(lang.isFunction(_3ac)){var _3ae=node[_3aa];if(!_3ae){_3ae=_3a9++;node[_3aa]=_3ae;}if(!_3a8[_3ae]){_3a8[_3ae]={};}var h=_3a8[_3ae][_3ad];if(h){conn.disconnect(h);}else{try{delete node[_3ad];}catch(e){}}if(_3ac){_3a8[_3ae][_3ad]=conn.connect(node,_3ad,_3ac);}else{node[_3ad]=null;}return node;}node[_3ad]=_3ac;return node;};});},"dojo/when":function(){define(["./Deferred","./promise/Promise"],function(_3af,_3b0){"use strict";return function when(_3b1,_3b2,_3b3,_3b4){var _3b5=_3b1&&typeof _3b1.then==="function";var _3b6=_3b5&&_3b1 instanceof _3b0;if(!_3b5){if(_3b2){return _3b2(_3b1);}else{return new _3af().resolve(_3b1);}}else{if(!_3b6){var _3b7=new _3af(_3b1.cancel);_3b1.then(_3b7.resolve,_3b7.reject,_3b7.progress);_3b1=_3b7.promise;}}if(_3b2||_3b3||_3b4){return _3b1.then(_3b2,_3b3,_3b4);}return _3b1;};});},"dojo/dom-attr":function(){define(["exports","./sniff","./_base/lang","./dom","./dom-style","./dom-prop"],function(_3b8,has,lang,dom,_3b9,prop){var _3ba={innerHTML:1,className:1,htmlFor:has("ie"),value:1},_3bb={classname:"class",htmlfor:"for",tabindex:"tabIndex",readonly:"readOnly"};function _3bc(node,name){var attr=node.getAttributeNode&&node.getAttributeNode(name);return attr&&attr.specified;};_3b8.has=function hasAttr(node,name){var lc=name.toLowerCase();return _3ba[prop.names[lc]||name]||_3bc(dom.byId(node),_3bb[lc]||name);};_3b8.get=function getAttr(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3bd=prop.names[lc]||name,_3be=_3ba[_3bd],_3bf=node[_3bd];if(_3be&&typeof _3bf!="undefined"){return _3bf;}if(_3bd!="href"&&(typeof _3bf=="boolean"||lang.isFunction(_3bf))){return _3bf;}var _3c0=_3bb[lc]||name;return _3bc(node,_3c0)?node.getAttribute(_3c0):null;};_3b8.set=function setAttr(node,name,_3c1){node=dom.byId(node);if(arguments.length==2){for(var x in name){_3b8.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_3c2=prop.names[lc]||name,_3c3=_3ba[_3c2];if(_3c2=="style"&&typeof _3c1!="string"){_3b9.set(node,_3c1);return node;}if(_3c3||typeof _3c1=="boolean"||lang.isFunction(_3c1)){return prop.set(node,name,_3c1);}node.setAttribute(_3bb[lc]||name,_3c1);return node;};_3b8.remove=function removeAttr(node,name){dom.byId(node).removeAttribute(_3bb[name.toLowerCase()]||name);};_3b8.getNodeProp=function getNodeProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3c4=prop.names[lc]||name;if((_3c4 in node)&&_3c4!="href"){return node[_3c4];}var _3c5=_3bb[lc]||name;return _3bc(node,_3c5)?node.getAttribute(_3c5):null;};});},"dojo/dom-construct":function(){define(["exports","./_base/kernel","./sniff","./_base/window","./dom","./dom-attr","./on"],function(_3c6,dojo,has,win,dom,attr,on){var _3c7={option:["select"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","thead","tr"],legend:["fieldset"],caption:["table"],colgroup:["table"],col:["table","colgroup"],li:["ul"]},_3c8=/<\s*([\w\:]+)/,_3c9={},_3ca=0,_3cb="__"+dojo._scopeName+"ToDomId";for(var _3cc in _3c7){if(_3c7.hasOwnProperty(_3cc)){var tw=_3c7[_3cc];tw.pre=_3cc=="option"?"<select multiple=\"multiple\">":"<"+tw.join("><")+">";tw.post="</"+tw.reverse().join("></")+">";}}function _3cd(node,ref){var _3ce=ref.parentNode;if(_3ce){_3ce.insertBefore(node,ref);}};function _3cf(node,ref){var _3d0=ref.parentNode;if(_3d0){if(_3d0.lastChild==ref){_3d0.appendChild(node);}else{_3d0.insertBefore(node,ref.nextSibling);}}};var _3d1=null,_3d2;on(window,"unload",function(){_3d1=null;});_3c6.toDom=function toDom(frag,doc){doc=doc||win.doc;var _3d3=doc[_3cb];if(!_3d3){doc[_3cb]=_3d3=++_3ca+"";_3c9[_3d3]=doc.createElement("div");}frag+="";var _3d4=frag.match(_3c8),tag=_3d4?_3d4[1].toLowerCase():"",_3d5=_3c9[_3d3],wrap,i,fc,df;if(_3d4&&_3c7[tag]){wrap=_3c7[tag];_3d5.innerHTML=wrap.pre+frag+wrap.post;for(i=wrap.length;i;--i){_3d5=_3d5.firstChild;}}else{_3d5.innerHTML=frag;}if(_3d5.childNodes.length==1){return _3d5.removeChild(_3d5.firstChild);}df=doc.createDocumentFragment();while(fc=_3d5.firstChild){df.appendChild(fc);}return df;};_3c6.place=function place(node,_3d6,_3d7){_3d6=dom.byId(_3d6);if(typeof node=="string"){node=/^\s*</.test(node)?_3c6.toDom(node,_3d6.ownerDocument):dom.byId(node);}if(typeof _3d7=="number"){var cn=_3d6.childNodes;if(!cn.length||cn.length<=_3d7){_3d6.appendChild(node);}else{_3cd(node,cn[_3d7<0?0:_3d7]);}}else{switch(_3d7){case "before":_3cd(node,_3d6);break;case "after":_3cf(node,_3d6);break;case "replace":_3d6.parentNode.replaceChild(node,_3d6);break;case "only":_3c6.empty(_3d6);_3d6.appendChild(node);break;case "first":if(_3d6.firstChild){_3cd(node,_3d6.firstChild);break;}default:_3d6.appendChild(node);}}return node;};_3c6.create=function create(tag,_3d8,_3d9,pos){var doc=win.doc;if(_3d9){_3d9=dom.byId(_3d9);doc=_3d9.ownerDocument;}if(typeof tag=="string"){tag=doc.createElement(tag);}if(_3d8){attr.set(tag,_3d8);}if(_3d9){_3c6.place(tag,_3d9,pos);}return tag;};_3c6.empty=has("ie")?function(node){node=dom.byId(node);for(var c;c=node.lastChild;){_3c6.destroy(c);}}:function(node){dom.byId(node).innerHTML="";};_3c6.destroy=function destroy(node){node=dom.byId(node);try{var doc=node.ownerDocument;if(!_3d1||_3d2!=doc){_3d1=doc.createElement("div");_3d2=doc;}_3d1.appendChild(node.parentNode?node.parentNode.removeChild(node):node);_3d1.innerHTML="";}catch(e){}};});},"dojo/request/xhr":function(){define("dojo/request/xhr",["../errors/RequestError","./watch","./handlers","./util","../has"],function(_3da,_3db,_3dc,util,has){has.add("native-xhr",function(){return typeof XMLHttpRequest!=="undefined";});has.add("dojo-force-activex-xhr",function(){return has("activex")&&!document.addEventListener&&window.location.protocol==="file:";});has.add("native-xhr2",function(){if(!has("native-xhr")){return;}var x=new XMLHttpRequest();return typeof x["addEventListener"]!=="undefined"&&(typeof opera==="undefined"||typeof x["upload"]!=="undefined");});has.add("native-formdata",function(){return typeof FormData==="function";});function _3dd(_3de,_3df){var _3e0=_3de.xhr;_3de.status=_3de.xhr.status;_3de.text=_3e0.responseText;if(_3de.options.handleAs==="xml"){_3de.data=_3e0.responseXML;}if(!_3df){try{_3dc(_3de);}catch(e){_3df=e;}}if(_3df){this.reject(_3df);}else{if(util.checkStatus(_3e0.status)){this.resolve(_3de);}else{_3df=new _3da("Unable to load "+_3de.url+" status: "+_3e0.status,_3de);this.reject(_3df);}}};var _3e1,_3e2,_3e3,_3e4;if(has("native-xhr2")){_3e1=function(_3e5){return !this.isFulfilled();};_3e4=function(dfd,_3e6){_3e6.xhr.abort();};_3e3=function(_3e7,dfd,_3e8){function _3e9(evt){dfd.handleResponse(_3e8);};function _3ea(evt){var _3eb=evt.target;var _3ec=new _3da("Unable to load "+_3e8.url+" status: "+_3eb.status,_3e8);dfd.handleResponse(_3e8,_3ec);};function _3ed(evt){if(evt.lengthComputable){_3e8.loaded=evt.loaded;_3e8.total=evt.total;dfd.progress(_3e8);}};_3e7.addEventListener("load",_3e9,false);_3e7.addEventListener("error",_3ea,false);_3e7.addEventListener("progress",_3ed,false);return function(){_3e7.removeEventListener("load",_3e9,false);_3e7.removeEventListener("error",_3ea,false);_3e7.removeEventListener("progress",_3ed,false);};};}else{_3e1=function(_3ee){return _3ee.xhr.readyState;};_3e2=function(_3ef){return 4===_3ef.xhr.readyState;};_3e4=function(dfd,_3f0){var xhr=_3f0.xhr;var _3f1=typeof xhr.abort;if(_3f1==="function"||_3f1==="object"||_3f1==="unknown"){xhr.abort();}};}var _3f2,_3f3={data:null,query:null,sync:false,method:"GET",headers:{"Content-Type":"application/x-www-form-urlencoded"}};function xhr(url,_3f4,_3f5){var _3f6=util.parseArgs(url,util.deepCreate(_3f3,_3f4),has("native-formdata")&&_3f4&&_3f4.data&&_3f4.data instanceof FormData);url=_3f6.url;_3f4=_3f6.options;var _3f7,last=function(){_3f7&&_3f7();};var dfd=util.deferred(_3f6,_3e4,_3e1,_3e2,_3dd,last);var _3f8=_3f6.xhr=xhr._create();if(!_3f8){dfd.cancel(new _3da("XHR was not created"));return _3f5?dfd:dfd.promise;}_3f6.getHeader=function(_3f9){return this.xhr.getResponseHeader(_3f9);};if(_3e3){_3f7=_3e3(_3f8,dfd,_3f6);}var data=_3f4.data,_3fa=!_3f4.sync,_3fb=_3f4.method;try{_3f8.open(_3fb,url,_3fa,_3f4.user||_3f2,_3f4.password||_3f2);if(_3f4.withCredentials){_3f8.withCredentials=_3f4.withCredentials;}var _3fc=_3f4.headers,_3fd;if(_3fc){for(var hdr in _3fc){if(hdr.toLowerCase()==="content-type"){_3fd=_3fc[hdr];}else{if(_3fc[hdr]){_3f8.setRequestHeader(hdr,_3fc[hdr]);}}}}if(_3fd&&_3fd!==false){_3f8.setRequestHeader("Content-Type",_3fd);}if(!_3fc||!("X-Requested-With" in _3fc)){_3f8.setRequestHeader("X-Requested-With","XMLHttpRequest");}if(util.notify){util.notify.emit("send",_3f6,dfd.promise.cancel);}_3f8.send(data);}catch(e){dfd.reject(e);}_3db(dfd);_3f8=null;return _3f5?dfd:dfd.promise;};xhr._create=function(){throw new Error("XMLHTTP not available");};if(has("native-xhr")&&!has("dojo-force-activex-xhr")){xhr._create=function(){return new XMLHttpRequest();};}else{if(has("activex")){try{new ActiveXObject("Msxml2.XMLHTTP");xhr._create=function(){return new ActiveXObject("Msxml2.XMLHTTP");};}catch(e){try{new ActiveXObject("Microsoft.XMLHTTP");xhr._create=function(){return new ActiveXObject("Microsoft.XMLHTTP");};}catch(e){}}}}util.addCommonMethods(xhr);return xhr;});},"dojo/text":function(){define(["./_base/kernel","require","./has","./_base/xhr"],function(dojo,_3fe,has,xhr){var _3ff;if(1){_3ff=function(url,sync,load){xhr("GET",{url:url,sync:!!sync,load:load,headers:dojo.config.textPluginHeaders||{}});};}else{if(_3fe.getText){_3ff=_3fe.getText;}else{console.error("dojo/text plugin failed to load because loader does not support getText");}}var _400={},_401=function(text){if(text){text=text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");var _402=text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(_402){text=_402[1];}}else{text="";}return text;},_403={},_404={};dojo.cache=function(_405,url,_406){var key;if(typeof _405=="string"){if(/\//.test(_405)){key=_405;_406=url;}else{key=_3fe.toUrl(_405.replace(/\./g,"/")+(url?("/"+url):""));}}else{key=_405+"";_406=url;}var val=(_406!=undefined&&typeof _406!="string")?_406.value:_406,_407=_406&&_406.sanitize;if(typeof val=="string"){_400[key]=val;return _407?_401(val):val;}else{if(val===null){delete _400[key];return null;}else{if(!(key in _400)){_3ff(key,true,function(text){_400[key]=text;});}return _407?_401(_400[key]):_400[key];}}};return {dynamic:true,normalize:function(id,_408){var _409=id.split("!"),url=_409[0];return (/^\./.test(url)?_408(url):url)+(_409[1]?"!"+_409[1]:"");},load:function(id,_40a,load){var _40b=id.split("!"),_40c=_40b.length>1,_40d=_40b[0],url=_40a.toUrl(_40b[0]),_40e="url:"+url,text=_403,_40f=function(text){load(_40c?_401(text):text);};if(_40d in _400){text=_400[_40d];}else{if(_40e in _40a.cache){text=_40a.cache[_40e];}else{if(url in _400){text=_400[url];}}}if(text===_403){if(_404[url]){_404[url].push(_40f);}else{var _410=_404[url]=[_40f];_3ff(url,!_40a.async,function(text){_400[_40d]=_400[url]=text;for(var i=0;i<_410.length;){_410[i++](text);}delete _404[url];});}}else{_40f(text);}}};});},"dojo/keys":function(){define("dojo/keys",["./_base/kernel","./sniff"],function(dojo,has){return dojo.keys={BACKSPACE:8,TAB:9,CLEAR:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,META:has("webkit")?91:224,PAUSE:19,CAPS_LOCK:20,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,INSERT:45,DELETE:46,HELP:47,LEFT_WINDOW:91,RIGHT_WINDOW:92,SELECT:93,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,NUMPAD_MULTIPLY:106,NUMPAD_PLUS:107,NUMPAD_ENTER:108,NUMPAD_MINUS:109,NUMPAD_PERIOD:110,NUMPAD_DIVIDE:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,NUM_LOCK:144,SCROLL_LOCK:145,UP_DPAD:175,DOWN_DPAD:176,LEFT_DPAD:177,RIGHT_DPAD:178,copyKey:has("mac")&&!has("air")?(has("safari")?91:224):17};});},"dojo/domReady":function(){define(["./has"],function(has){var _411=this,doc=document,_412={"loaded":1,"complete":1},_413=typeof doc.readyState!="string",_414=!!_412[doc.readyState];if(_413){doc.readyState="loading";}if(!_414){var _415=[],_416=[],_417=function(evt){evt=evt||_411.event;if(_414||(evt.type=="readystatechange"&&!_412[doc.readyState])){return;}_414=1;if(_413){doc.readyState="complete";}while(_415.length){(_415.shift())(doc);}},on=function(node,_418){node.addEventListener(_418,_417,false);_415.push(function(){node.removeEventListener(_418,_417,false);});};if(!has("dom-addeventlistener")){on=function(node,_419){_419="on"+_419;node.attachEvent(_419,_417);_415.push(function(){node.detachEvent(_419,_417);});};var div=doc.createElement("div");try{if(div.doScroll&&_411.frameElement===null){_416.push(function(){try{div.doScroll("left");return 1;}catch(e){}});}}catch(e){}}on(doc,"DOMContentLoaded");on(_411,"load");if("onreadystatechange" in doc){on(doc,"readystatechange");}else{if(!_413){_416.push(function(){return _412[doc.readyState];});}}if(_416.length){var _41a=function(){if(_414){return;}var i=_416.length;while(i--){if(_416[i]()){_417("poller");return;}}setTimeout(_41a,30);};_41a();}}function _41b(_41c){if(_414){_41c(doc);}else{_415.push(_41c);}};_41b.load=function(id,req,load){_41b(load);};return _41b;});},"dojo/_base/lang":function(){define("dojo/_base/lang",["./kernel","../has","../sniff"],function(dojo,has){has.add("bug-for-in-skips-shadowed",function(){for(var i in {toString:1}){return 0;}return 1;});var _41d=has("bug-for-in-skips-shadowed")?"hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split("."):[],_41e=_41d.length,_41f=function(_420,_421,_422){var p,i=0,_423=dojo.global;if(!_422){if(!_420.length){return _423;}else{p=_420[i++];try{_422=dojo.scopeMap[p]&&dojo.scopeMap[p][1];}catch(e){}_422=_422||(p in _423?_423[p]:(_421?_423[p]={}:undefined));}}while(_422&&(p=_420[i++])){_422=(p in _422?_422[p]:(_421?_422[p]={}:undefined));}return _422;},opts=Object.prototype.toString,_424=function(obj,_425,_426){return (_426||[]).concat(Array.prototype.slice.call(obj,_425||0));},_427=/\{([^\}]+)\}/g;var lang={_extraNames:_41d,_mixin:function(dest,_428,_429){var name,s,i,_42a={};for(name in _428){s=_428[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _42a)||_42a[name]!==s))){dest[name]=_429?_429(s):s;}}if(has("bug-for-in-skips-shadowed")){if(_428){for(i=0;i<_41e;++i){name=_41d[i];s=_428[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _42a)||_42a[name]!==s))){dest[name]=_429?_429(s):s;}}}}return dest;},mixin:function(dest,_42b){if(!dest){dest={};}for(var i=1,l=arguments.length;i<l;i++){lang._mixin(dest,arguments[i]);}return dest;},setObject:function(name,_42c,_42d){var _42e=name.split("."),p=_42e.pop(),obj=_41f(_42e,true,_42d);return obj&&p?(obj[p]=_42c):undefined;},getObject:function(name,_42f,_430){return _41f(name.split("."),_42f,_430);},exists:function(name,obj){return lang.getObject(name,false,obj)!==undefined;},isString:function(it){return (typeof it=="string"||it instanceof String);},isArray:function(it){return it&&(it instanceof Array||typeof it=="array");},isFunction:function(it){return opts.call(it)==="[object Function]";},isObject:function(it){return it!==undefined&&(it===null||typeof it=="object"||lang.isArray(it)||lang.isFunction(it));},isArrayLike:function(it){return it&&it!==undefined&&!lang.isString(it)&&!lang.isFunction(it)&&!(it.tagName&&it.tagName.toLowerCase()=="form")&&(lang.isArray(it)||isFinite(it.length));},isAlien:function(it){return it&&!lang.isFunction(it)&&/\{\s*\[native code\]\s*\}/.test(String(it));},extend:function(ctor,_431){for(var i=1,l=arguments.length;i<l;i++){lang._mixin(ctor.prototype,arguments[i]);}return ctor;},_hitchArgs:function(_432,_433){var pre=lang._toArray(arguments,2);var _434=lang.isString(_433);return function(){var args=lang._toArray(arguments);var f=_434?(_432||dojo.global)[_433]:_433;return f&&f.apply(_432||this,pre.concat(args));};},hitch:function(_435,_436){if(arguments.length>2){return lang._hitchArgs.apply(dojo,arguments);}if(!_436){_436=_435;_435=null;}if(lang.isString(_436)){_435=_435||dojo.global;if(!_435[_436]){throw (["lang.hitch: scope[\"",_436,"\"] is null (scope=\"",_435,"\")"].join(""));}return function(){return _435[_436].apply(_435,arguments||[]);};}return !_435?_436:function(){return _436.apply(_435,arguments||[]);};},delegate:(function(){function TMP(){};return function(obj,_437){TMP.prototype=obj;var tmp=new TMP();TMP.prototype=null;if(_437){lang._mixin(tmp,_437);}return tmp;};})(),_toArray:has("ie")?(function(){function slow(obj,_438,_439){var arr=_439||[];for(var x=_438||0;x<obj.length;x++){arr.push(obj[x]);}return arr;};return function(obj){return ((obj.item)?slow:_424).apply(this,arguments);};})():_424,partial:function(_43a){var arr=[null];return lang.hitch.apply(dojo,arr.concat(lang._toArray(arguments)));},clone:function(src){if(!src||typeof src!="object"||lang.isFunction(src)){return src;}if(src.nodeType&&"cloneNode" in src){return src.cloneNode(true);}if(src instanceof Date){return new Date(src.getTime());}if(src instanceof RegExp){return new RegExp(src);}var r,i,l;if(lang.isArray(src)){r=[];for(i=0,l=src.length;i<l;++i){if(i in src){r.push(lang.clone(src[i]));}}}else{r=src.constructor?new src.constructor():{};}return lang._mixin(r,src,lang.clone);},trim:String.prototype.trim?function(str){return str.trim();}:function(str){return str.replace(/^\s\s*/,"").replace(/\s\s*$/,"");},replace:function(tmpl,map,_43b){return tmpl.replace(_43b||_427,lang.isFunction(map)?map:function(_43c,k){return lang.getObject(k,false,map);});}};1&&lang.mixin(dojo,lang);return lang;});},"dojo/request/util":function(){define("dojo/request/util",["exports","../errors/RequestError","../errors/CancelError","../Deferred","../io-query","../_base/array","../_base/lang"],function(_43d,_43e,_43f,_440,_441,_442,lang){_43d.deepCopy=function deepCopy(_443,_444){for(var name in _444){var tval=_443[name],sval=_444[name];if(tval!==sval){if(tval&&typeof tval==="object"&&sval&&typeof sval==="object"){_43d.deepCopy(tval,sval);}else{_443[name]=sval;}}}return _443;};_43d.deepCreate=function deepCreate(_445,_446){_446=_446||{};var _447=lang.delegate(_445),name,_448;for(name in _445){_448=_445[name];if(_448&&typeof _448==="object"){_447[name]=_43d.deepCreate(_448,_446[name]);}}return _43d.deepCopy(_447,_446);};var _449=Object.freeze||function(obj){return obj;};function _44a(_44b){return _449(_44b);};_43d.deferred=function deferred(_44c,_44d,_44e,_44f,_450,last){var def=new _440(function(_451){_44d&&_44d(def,_44c);if(!_451||!(_451 instanceof _43e)&&!(_451 instanceof _43f)){return new _43f("Request canceled",_44c);}return _451;});def.response=_44c;def.isValid=_44e;def.isReady=_44f;def.handleResponse=_450;function _452(_453){_453.response=_44c;throw _453;};var _454=def.then(_44a).otherwise(_452);if(_43d.notify){_454.then(lang.hitch(_43d.notify,"emit","load"),lang.hitch(_43d.notify,"emit","error"));}var _455=_454.then(function(_456){return _456.data||_456.text;});var _457=_449(lang.delegate(_455,{response:_454}));if(last){def.then(function(_458){last.call(def,_458);},function(_459){last.call(def,_44c,_459);});}def.promise=_457;def.then=_457.then;return def;};_43d.addCommonMethods=function addCommonMethods(_45a,_45b){_442.forEach(_45b||["GET","POST","PUT","DELETE"],function(_45c){_45a[(_45c==="DELETE"?"DEL":_45c).toLowerCase()]=function(url,_45d){_45d=lang.delegate(_45d||{});_45d.method=_45c;return _45a(url,_45d);};});};_43d.parseArgs=function parseArgs(url,_45e,_45f){var data=_45e.data,_460=_45e.query;if(data&&!_45f){if(typeof data==="object"){_45e.data=_441.objectToQuery(data);}}if(_460){if(typeof _460==="object"){_460=_441.objectToQuery(_460);}if(_45e.preventCache){_460+=(_460?"&":"")+"request.preventCache="+(+(new Date));}}else{if(_45e.preventCache){_460="request.preventCache="+(+(new Date));}}if(url&&_460){url+=(~url.indexOf("?")?"&":"?")+_460;}return {url:url,options:_45e,getHeader:function(_461){return null;}};};_43d.checkStatus=function(stat){stat=stat||0;return (stat>=200&&stat<300)||stat===304||stat===1223||!stat;};});},"dojo/Evented":function(){define("dojo/Evented",["./aspect","./on"],function(_462,on){"use strict";var _463=_462.after;function _464(){};_464.prototype={on:function(type,_465){return on.parse(this,type,_465,function(_466,type){return _463(_466,"on"+type,_465,true);});},emit:function(type,_467){var args=[this];args.push.apply(args,arguments);return on.emit.apply(on,args);}};return _464;});},"dojo/mouse":function(){define("dojo/mouse",["./_base/kernel","./on","./has","./dom","./_base/window"],function(dojo,on,has,dom,win){has.add("dom-quirks",win.doc&&win.doc.compatMode=="BackCompat");has.add("events-mouseenter",win.doc&&"onmouseenter" in win.doc.createElement("div"));has.add("events-mousewheel",win.doc&&"onmousewheel" in win.doc);var _468;if(has("dom-quirks")||!has("dom-addeventlistener")){_468={LEFT:1,MIDDLE:4,RIGHT:2,isButton:function(e,_469){return e.button&_469;},isLeft:function(e){return e.button&1;},isMiddle:function(e){return e.button&4;},isRight:function(e){return e.button&2;}};}else{_468={LEFT:0,MIDDLE:1,RIGHT:2,isButton:function(e,_46a){return e.button==_46a;},isLeft:function(e){return e.button==0;},isMiddle:function(e){return e.button==1;},isRight:function(e){return e.button==2;}};}dojo.mouseButtons=_468;function _46b(type,_46c){var _46d=function(node,_46e){return on(node,type,function(evt){if(_46c){return _46c(evt,_46e);}if(!dom.isDescendant(evt.relatedTarget,node)){return _46e.call(this,evt);}});};_46d.bubble=function(_46f){return _46b(type,function(evt,_470){var _471=_46f(evt.target);var _472=evt.relatedTarget;if(_471&&(_471!=(_472&&_472.nodeType==1&&_46f(_472)))){return _470.call(_471,evt);}});};return _46d;};var _473;if(has("events-mousewheel")){_473="mousewheel";}else{_473=function(node,_474){return on(node,"DOMMouseScroll",function(evt){evt.wheelDelta=-evt.detail;_474.call(this,evt);});};}return {_eventHandler:_46b,enter:_46b("mouseover"),leave:_46b("mouseout"),wheel:_473,isLeft:_468.isLeft,isMiddle:_468.isMiddle,isRight:_468.isRight};});},"dojo/_base/xhr":function(){define("dojo/_base/xhr",["./kernel","./sniff","require","../io-query","../dom","../dom-form","./Deferred","./config","./json","./lang","./array","../on","../aspect","../request/watch","../request/xhr","../request/util"],function(dojo,has,_475,ioq,dom,_476,_477,_478,json,lang,_479,on,_47a,_47b,_47c,util){dojo._xhrObj=_47c._create;var cfg=dojo.config;dojo.objectToQuery=ioq.objectToQuery;dojo.queryToObject=ioq.queryToObject;dojo.fieldToObject=_476.fieldToObject;dojo.formToObject=_476.toObject;dojo.formToQuery=_476.toQuery;dojo.formToJson=_476.toJson;dojo._blockAsync=false;var _47d=dojo._contentHandlers=dojo.contentHandlers={"text":function(xhr){return xhr.responseText;},"json":function(xhr){return json.fromJson(xhr.responseText||null);},"json-comment-filtered":function(xhr){if(!_478.useCommentedJson){console.warn("Consider using the standard mimetype:application/json."+" json-commenting can introduce security issues. To"+" decrease the chances of hijacking, use the standard the 'json' handler and"+" prefix your json with: {}&&\n"+"Use djConfig.useCommentedJson=true to turn off this message.");}var _47e=xhr.responseText;var _47f=_47e.indexOf("/*");var _480=_47e.lastIndexOf("*/");if(_47f==-1||_480==-1){throw new Error("JSON was not comment filtered");}return json.fromJson(_47e.substring(_47f+2,_480));},"javascript":function(xhr){return dojo.eval(xhr.responseText);},"xml":function(xhr){var _481=xhr.responseXML;if(has("ie")){if((!_481||!_481.documentElement)){var ms=function(n){return "MSXML"+n+".DOMDocument";};var dp=["Microsoft.XMLDOM",ms(6),ms(4),ms(3),ms(2)];_479.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(xhr.responseText);_481=dom;}catch(e){return false;}return true;});}}return _481;},"json-comment-optional":function(xhr){if(xhr.responseText&&/^[^{\[]*\/\*/.test(xhr.responseText)){return _47d["json-comment-filtered"](xhr);}else{return _47d["json"](xhr);}}};dojo._ioSetArgs=function(args,_482,_483,_484){var _485={args:args,url:args.url};var _486=null;if(args.form){var form=dom.byId(args.form);var _487=form.getAttributeNode("action");_485.url=_485.url||(_487?_487.value:null);_486=_476.toObject(form);}var _488=[{}];if(_486){_488.push(_486);}if(args.content){_488.push(args.content);}if(args.preventCache){_488.push({"dojo.preventCache":new Date().valueOf()});}_485.query=ioq.objectToQuery(lang.mixin.apply(null,_488));_485.handleAs=args.handleAs||"text";var d=new _477(function(dfd){dfd.canceled=true;_482&&_482(dfd);var err=dfd.ioArgs.error;if(!err){err=new Error("request cancelled");err.dojoType="cancel";dfd.ioArgs.error=err;}return err;});d.addCallback(_483);var ld=args.load;if(ld&&lang.isFunction(ld)){d.addCallback(function(_489){return ld.call(args,_489,_485);});}var err=args.error;if(err&&lang.isFunction(err)){d.addErrback(function(_48a){return err.call(args,_48a,_485);});}var _48b=args.handle;if(_48b&&lang.isFunction(_48b)){d.addBoth(function(_48c){return _48b.call(args,_48c,_485);});}d.addErrback(function(_48d){return _484(_48d,d);});if(cfg.ioPublish&&dojo.publish&&_485.args.ioPublish!==false){d.addCallbacks(function(res){dojo.publish("/dojo/io/load",[d,res]);return res;},function(res){dojo.publish("/dojo/io/error",[d,res]);return res;});d.addBoth(function(res){dojo.publish("/dojo/io/done",[d,res]);return res;});}d.ioArgs=_485;return d;};var _48e=function(dfd){var ret=_47d[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);return ret===undefined?null:ret;};var _48f=function(_490,dfd){if(!dfd.ioArgs.args.failOk){console.error(_490);}return _490;};var _491=function(dfd){if(_492<=0){_492=0;if(cfg.ioPublish&&dojo.publish&&(!dfd||dfd&&dfd.ioArgs.args.ioPublish!==false)){dojo.publish("/dojo/io/stop");}}};var _492=0;_47a.after(_47b,"_onAction",function(){_492-=1;});_47a.after(_47b,"_onInFlight",_491);dojo._ioCancelAll=_47b.cancelAll;dojo._ioNotifyStart=function(dfd){if(cfg.ioPublish&&dojo.publish&&dfd.ioArgs.args.ioPublish!==false){if(!_492){dojo.publish("/dojo/io/start");}_492+=1;dojo.publish("/dojo/io/send",[dfd]);}};dojo._ioWatch=function(dfd,_493,_494,_495){var args=dfd.ioArgs.options=dfd.ioArgs.args;lang.mixin(dfd,{response:dfd.ioArgs,isValid:function(_496){return _493(dfd);},isReady:function(_497){return _494(dfd);},handleResponse:function(_498){return _495(dfd);}});_47b(dfd);_491(dfd);};var _499="application/x-www-form-urlencoded";dojo._ioAddQueryToUrl=function(_49a){if(_49a.query.length){_49a.url+=(_49a.url.indexOf("?")==-1?"?":"&")+_49a.query;_49a.query=null;}};dojo.xhr=function(_49b,args,_49c){var rDfd;var dfd=dojo._ioSetArgs(args,function(dfd){rDfd&&rDfd.cancel();},_48e,_48f);var _49d=dfd.ioArgs;if("postData" in args){_49d.query=args.postData;}else{if("putData" in args){_49d.query=args.putData;}else{if("rawBody" in args){_49d.query=args.rawBody;}else{if((arguments.length>2&&!_49c)||"POST|PUT".indexOf(_49b.toUpperCase())===-1){dojo._ioAddQueryToUrl(_49d);}}}}var _49e={method:_49b,handleAs:"text",timeout:args.timeout,withCredentials:args.withCredentials,ioArgs:_49d};if(typeof args.headers!=="undefined"){_49e.headers=args.headers;}if(typeof args.contentType!=="undefined"){if(!_49e.headers){_49e.headers={};}_49e.headers["Content-Type"]=args.contentType;}if(typeof _49d.query!=="undefined"){_49e.data=_49d.query;}if(typeof args.sync!=="undefined"){_49e.sync=args.sync;}dojo._ioNotifyStart(dfd);try{rDfd=_47c(_49d.url,_49e,true);}catch(e){dfd.cancel();return dfd;}dfd.ioArgs.xhr=rDfd.response.xhr;rDfd.then(function(){dfd.resolve(dfd);}).otherwise(function(_49f){_49d.error=_49f;dfd.reject(_49f);});return dfd;};dojo.xhrGet=function(args){return dojo.xhr("GET",args);};dojo.rawXhrPost=dojo.xhrPost=function(args){return dojo.xhr("POST",args,true);};dojo.rawXhrPut=dojo.xhrPut=function(args){return dojo.xhr("PUT",args,true);};dojo.xhrDelete=function(args){return dojo.xhr("DELETE",args);};dojo._isDocumentOk=function(x){return util.checkStatus(x.status);};dojo._getText=function(url){var _4a0;dojo.xhrGet({url:url,sync:true,load:function(text){_4a0=text;}});return _4a0;};lang.mixin(dojo.xhr,{_xhrObj:dojo._xhrObj,fieldToObject:_476.fieldToObject,formToObject:_476.toObject,objectToQuery:ioq.objectToQuery,formToQuery:_476.toQuery,formToJson:_476.toJson,queryToObject:ioq.queryToObject,contentHandlers:_47d,_ioSetArgs:dojo._ioSetArgs,_ioCancelAll:dojo._ioCancelAll,_ioNotifyStart:dojo._ioNotifyStart,_ioWatch:dojo._ioWatch,_ioAddQueryToUrl:dojo._ioAddQueryToUrl,_isDocumentOk:dojo._isDocumentOk,_getText:dojo._getText,get:dojo.xhrGet,post:dojo.xhrPost,put:dojo.xhrPut,del:dojo.xhrDelete});return dojo.xhr;});},"dojo/topic":function(){define("dojo/topic",["./Evented"],function(_4a1){var hub=new _4a1;return {publish:function(_4a2,_4a3){return hub.emit.apply(hub,arguments);},subscribe:function(_4a4,_4a5){return hub.on.apply(hub,arguments);}};});},"dojo/loadInit":function(){define("dojo/loadInit",["./_base/loader"],function(_4a6){return {dynamic:0,normalize:function(id){return id;},load:_4a6.loadInit};});},"dojo/_base/unload":function(){define(["./kernel","./lang","../on"],function(dojo,lang,on){var win=window;var _4a7={addOnWindowUnload:function(obj,_4a8){if(!dojo.windowUnloaded){on(win,"unload",(dojo.windowUnloaded=function(){}));}on(win,"unload",lang.hitch(obj,_4a8));},addOnUnload:function(obj,_4a9){on(win,"beforeunload",lang.hitch(obj,_4a9));}};dojo.addOnWindowUnload=_4a7.addOnWindowUnload;dojo.addOnUnload=_4a7.addOnUnload;return _4a7;});},"dojo/Deferred":function(){define(["./has","./_base/lang","./errors/CancelError","./promise/Promise","./promise/instrumentation"],function(has,lang,_4aa,_4ab,_4ac){"use strict";var _4ad=0,_4ae=1,_4af=2;var _4b0="This deferred has already been fulfilled.";var _4b1=Object.freeze||function(){};var _4b2=function(_4b3,type,_4b4,_4b5,_4b6){if(1){if(type===_4af&&_4b7.instrumentRejected&&_4b3.length===0){_4b7.instrumentRejected(_4b4,false,_4b5,_4b6);}}for(var i=0;i<_4b3.length;i++){_4b8(_4b3[i],type,_4b4,_4b5);}};var _4b8=function(_4b9,type,_4ba,_4bb){var func=_4b9[type];var _4bc=_4b9.deferred;if(func){try{var _4bd=func(_4ba);if(_4bd&&typeof _4bd.then==="function"){_4b9.cancel=_4bd.cancel;_4bd.then(_4be(_4bc,_4ae),_4be(_4bc,_4af),_4be(_4bc,_4ad));return;}_4bf(_4bc,_4ae,_4bd);}catch(error){_4bf(_4bc,_4af,error);}}else{_4bf(_4bc,type,_4ba);}if(1){if(type===_4af&&_4b7.instrumentRejected){_4b7.instrumentRejected(_4ba,!!func,_4bb,_4bc.promise);}}};var _4be=function(_4c0,type){return function(_4c1){_4bf(_4c0,type,_4c1);};};var _4bf=function(_4c2,type,_4c3){if(!_4c2.isCanceled()){switch(type){case _4ad:_4c2.progress(_4c3);break;case _4ae:_4c2.resolve(_4c3);break;case _4af:_4c2.reject(_4c3);break;}}};var _4b7=function(_4c4){var _4c5=this.promise=new _4ab();var _4c6=this;var _4c7,_4c8,_4c9;var _4ca=false;var _4cb=[];if(1&&Error.captureStackTrace){Error.captureStackTrace(_4c6,_4b7);Error.captureStackTrace(_4c5,_4b7);}this.isResolved=_4c5.isResolved=function(){return _4c7===_4ae;};this.isRejected=_4c5.isRejected=function(){return _4c7===_4af;};this.isFulfilled=_4c5.isFulfilled=function(){return !!_4c7;};this.isCanceled=_4c5.isCanceled=function(){return _4ca;};this.progress=function(_4cc,_4cd){if(!_4c7){_4b2(_4cb,_4ad,_4cc,null,_4c6);return _4c5;}else{if(_4cd===true){throw new Error(_4b0);}else{return _4c5;}}};this.resolve=function(_4ce,_4cf){if(!_4c7){_4b2(_4cb,_4c7=_4ae,_4c8=_4ce,null,_4c6);_4cb=null;return _4c5;}else{if(_4cf===true){throw new Error(_4b0);}else{return _4c5;}}};var _4d0=this.reject=function(_4d1,_4d2){if(!_4c7){if(1&&Error.captureStackTrace){Error.captureStackTrace(_4c9={},_4d0);}_4b2(_4cb,_4c7=_4af,_4c8=_4d1,_4c9,_4c6);_4cb=null;return _4c5;}else{if(_4d2===true){throw new Error(_4b0);}else{return _4c5;}}};this.then=_4c5.then=function(_4d3,_4d4,_4d5){var _4d6=[_4d5,_4d3,_4d4];_4d6.cancel=_4c5.cancel;_4d6.deferred=new _4b7(function(_4d7){return _4d6.cancel&&_4d6.cancel(_4d7);});if(_4c7&&!_4cb){_4b8(_4d6,_4c7,_4c8,_4c9);}else{_4cb.push(_4d6);}return _4d6.deferred.promise;};this.cancel=_4c5.cancel=function(_4d8,_4d9){if(!_4c7){if(_4c4){var _4da=_4c4(_4d8);_4d8=typeof _4da==="undefined"?_4d8:_4da;}_4ca=true;if(!_4c7){if(typeof _4d8==="undefined"){_4d8=new _4aa();}_4d0(_4d8);return _4d8;}else{if(_4c7===_4af&&_4c8===_4d8){return _4d8;}}}else{if(_4d9===true){throw new Error(_4b0);}}};_4b1(_4c5);};_4b7.prototype.toString=function(){return "[object Deferred]";};if(_4ac){_4ac(_4b7);}return _4b7;});},"dojo/_base/NodeList":function(){define("dojo/_base/NodeList",["./kernel","../query","./array","./html","../NodeList-dom"],function(dojo,_4db,_4dc){var _4dd=_4db.NodeList,nlp=_4dd.prototype;nlp.connect=_4dd._adaptAsForEach(function(){return dojo.connect.apply(this,arguments);});nlp.coords=_4dd._adaptAsMap(dojo.coords);_4dd.events=["blur","focus","change","click","error","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","submit"];_4dc.forEach(_4dd.events,function(evt){var _4de="on"+evt;nlp[_4de]=function(a,b){return this.connect(_4de,a,b);};});dojo.NodeList=_4dd;return _4dd;});},"dojo/_base/Color":function(){define(["./kernel","./lang","./array","./config"],function(dojo,lang,_4df,_4e0){var _4e1=dojo.Color=function(_4e2){if(_4e2){this.setColor(_4e2);}};_4e1.named={"black":[0,0,0],"silver":[192,192,192],"gray":[128,128,128],"white":[255,255,255],"maroon":[128,0,0],"red":[255,0,0],"purple":[128,0,128],"fuchsia":[255,0,255],"green":[0,128,0],"lime":[0,255,0],"olive":[128,128,0],"yellow":[255,255,0],"navy":[0,0,128],"blue":[0,0,255],"teal":[0,128,128],"aqua":[0,255,255],"transparent":_4e0.transparentColor||[0,0,0,0]};lang.extend(_4e1,{r:255,g:255,b:255,a:1,_set:function(r,g,b,a){var t=this;t.r=r;t.g=g;t.b=b;t.a=a;},setColor:function(_4e3){if(lang.isString(_4e3)){_4e1.fromString(_4e3,this);}else{if(lang.isArray(_4e3)){_4e1.fromArray(_4e3,this);}else{this._set(_4e3.r,_4e3.g,_4e3.b,_4e3.a);if(!(_4e3 instanceof _4e1)){this.sanitize();}}}return this;},sanitize:function(){return this;},toRgb:function(){var t=this;return [t.r,t.g,t.b];},toRgba:function(){var t=this;return [t.r,t.g,t.b,t.a];},toHex:function(){var arr=_4df.map(["r","g","b"],function(x){var s=this[x].toString(16);return s.length<2?"0"+s:s;},this);return "#"+arr.join("");},toCss:function(_4e4){var t=this,rgb=t.r+", "+t.g+", "+t.b;return (_4e4?"rgba("+rgb+", "+t.a:"rgb("+rgb)+")";},toString:function(){return this.toCss(true);}});_4e1.blendColors=dojo.blendColors=function(_4e5,end,_4e6,obj){var t=obj||new _4e1();_4df.forEach(["r","g","b","a"],function(x){t[x]=_4e5[x]+(end[x]-_4e5[x])*_4e6;if(x!="a"){t[x]=Math.round(t[x]);}});return t.sanitize();};_4e1.fromRgb=dojo.colorFromRgb=function(_4e7,obj){var m=_4e7.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);return m&&_4e1.fromArray(m[1].split(/\s*,\s*/),obj);};_4e1.fromHex=dojo.colorFromHex=function(_4e8,obj){var t=obj||new _4e1(),bits=(_4e8.length==4)?4:8,mask=(1<<bits)-1;_4e8=Number("0x"+_4e8.substr(1));if(isNaN(_4e8)){return null;}_4df.forEach(["b","g","r"],function(x){var c=_4e8&mask;_4e8>>=bits;t[x]=bits==4?17*c:c;});t.a=1;return t;};_4e1.fromArray=dojo.colorFromArray=function(a,obj){var t=obj||new _4e1();t._set(Number(a[0]),Number(a[1]),Number(a[2]),Number(a[3]));if(isNaN(t.a)){t.a=1;}return t.sanitize();};_4e1.fromString=dojo.colorFromString=function(str,obj){var a=_4e1.named[str];return a&&_4e1.fromArray(a,obj)||_4e1.fromRgb(str,obj)||_4e1.fromHex(str,obj);};return _4e1;});},"dojo/promise/instrumentation":function(){define(["./tracer","../has","../_base/lang","../_base/array"],function(_4e9,has,lang,_4ea){function _4eb(_4ec,_4ed,_4ee){var _4ef="";if(_4ec&&_4ec.stack){_4ef+=_4ec.stack;}if(_4ed&&_4ed.stack){_4ef+="\n ----------------------------------------\n rejected"+_4ed.stack.split("\n").slice(1).join("\n").replace(/^\s+/," ");}if(_4ee&&_4ee.stack){_4ef+="\n ----------------------------------------\n"+_4ee.stack;}console.error(_4ec,_4ef);};function _4f0(_4f1,_4f2,_4f3,_4f4){if(!_4f2){_4eb(_4f1,_4f3,_4f4);}};var _4f5=[];var _4f6=false;var _4f7=1000;function _4f8(_4f9,_4fa,_4fb,_4fc){if(_4fa){_4ea.some(_4f5,function(obj,ix){if(obj.error===_4f9){_4f5.splice(ix,1);return true;}});}else{if(!_4ea.some(_4f5,function(obj){return obj.error===_4f9;})){_4f5.push({error:_4f9,rejection:_4fb,deferred:_4fc,timestamp:new Date().getTime()});}}if(!_4f6){_4f6=setTimeout(_4fd,_4f7);}};function _4fd(){var now=new Date().getTime();var _4fe=now-_4f7;_4f5=_4ea.filter(_4f5,function(obj){if(obj.timestamp<_4fe){_4eb(obj.error,obj.rejection,obj.deferred);return false;}return true;});if(_4f5.length){_4f6=setTimeout(_4fd,_4f5[0].timestamp+_4f7-now);}};return function(_4ff){var _500=has("config-useDeferredInstrumentation");if(_500){_4e9.on("resolved",lang.hitch(console,"log","resolved"));_4e9.on("rejected",lang.hitch(console,"log","rejected"));_4e9.on("progress",lang.hitch(console,"log","progress"));var args=[];if(typeof _500==="string"){args=_500.split(",");_500=args.shift();}if(_500==="report-rejections"){_4ff.instrumentRejected=_4f0;}else{if(_500==="report-unhandled-rejections"||_500===true||_500===1){_4ff.instrumentRejected=_4f8;_4f7=parseInt(args[0],10)||_4f7;}else{throw new Error("Unsupported instrumentation usage <"+_500+">");}}}};});},"dojo/selector/_loader":function(){define(["../has","require"],function(has,_501){"use strict";var _502=document.createElement("div");has.add("dom-qsa2.1",!!_502.querySelectorAll);has.add("dom-qsa3",function(){try{_502.innerHTML="<p class='TEST'></p>";return _502.querySelectorAll(".TEST:empty").length==1;}catch(e){}});var _503;var acme="./acme",lite="./lite";return {load:function(id,_504,_505,_506){var req=_501;id=id=="default"?has("config-selectorEngine")||"css3":id;id=id=="css2"||id=="lite"?lite:id=="css2.1"?has("dom-qsa2.1")?lite:acme:id=="css3"?has("dom-qsa3")?lite:acme:id=="acme"?acme:(req=_504)&&id;if(id.charAt(id.length-1)=="?"){id=id.substring(0,id.length-1);var _507=true;}if(_507&&(has("dom-compliant-qsa")||_503)){return _505(_503);}req([id],function(_508){if(id!="./lite"){_503=_508;}_505(_508);});}};});},"dojo/promise/Promise":function(){define(["../_base/lang"],function(lang){"use strict";function _509(){throw new TypeError("abstract");};return lang.extend(function Promise(){},{then:function(_50a,_50b,_50c){_509();},cancel:function(_50d,_50e){_509();},isResolved:function(){_509();},isRejected:function(){_509();},isFulfilled:function(){_509();},isCanceled:function(){_509();},always:function(_50f){return this.then(_50f,_50f);},otherwise:function(_510){return this.then(null,_510);},trace:function(){return this;},traceRejected:function(){return this;},toString:function(){return "[object Promise]";}});});},"dojo/request/watch":function(){define(["./util","../errors/RequestTimeoutError","../errors/CancelError","../_base/array","../_base/window","../has!host-browser?dom-addeventlistener?:../on:"],function(util,_511,_512,_513,win,on){var _514=null,_515=[];function _516(){var now=+(new Date);for(var i=0,dfd;i<_515.length&&(dfd=_515[i]);i++){var _517=dfd.response,_518=_517.options;if((dfd.isCanceled&&dfd.isCanceled())||(dfd.isValid&&!dfd.isValid(_517))){_515.splice(i--,1);_519._onAction&&_519._onAction();}else{if(dfd.isReady&&dfd.isReady(_517)){_515.splice(i--,1);dfd.handleResponse(_517);_519._onAction&&_519._onAction();}else{if(dfd.startTime){if(dfd.startTime+(_518.timeout||0)<now){_515.splice(i--,1);dfd.cancel(new _511(_517));_519._onAction&&_519._onAction();}}}}}_519._onInFlight&&_519._onInFlight(dfd);if(!_515.length){clearInterval(_514);_514=null;}};function _519(dfd){if(dfd.response.options.timeout){dfd.startTime=+(new Date);}if(dfd.isFulfilled()){return;}_515.push(dfd);if(!_514){_514=setInterval(_516,50);}if(dfd.response.options.sync){_516();}};_519.cancelAll=function cancelAll(){try{_513.forEach(_515,function(dfd){try{dfd.cancel(new _512("All requests canceled."));}catch(e){}});}catch(e){}};if(win&&on&&win.doc.attachEvent){on(win.global,"unload",function(){_519.cancelAll();});}return _519;});},"dojo/on":function(){define(["./has!dom-addeventlistener?:./aspect","./_base/kernel","./has"],function(_51a,dojo,has){"use strict";if(1){var _51b=window.ScriptEngineMajorVersion;has.add("jscript",_51b&&(_51b()+ScriptEngineMinorVersion()/10));has.add("event-orientationchange",has("touch")&&!has("android"));has.add("event-stopimmediatepropagation",window.Event&&!!window.Event.prototype&&!!window.Event.prototype.stopImmediatePropagation);}var on=function(_51c,type,_51d,_51e){if(_51c.on&&typeof type!="function"){return _51c.on(type,_51d);}return on.parse(_51c,type,_51d,_51f,_51e,this);};on.pausable=function(_520,type,_521,_522){var _523;var _524=on(_520,type,function(){if(!_523){return _521.apply(this,arguments);}},_522);_524.pause=function(){_523=true;};_524.resume=function(){_523=false;};return _524;};on.once=function(_525,type,_526,_527){var _528=on(_525,type,function(){_528.remove();return _526.apply(this,arguments);});return _528;};on.parse=function(_529,type,_52a,_52b,_52c,_52d){if(type.call){return type.call(_52d,_529,_52a);}if(type.indexOf(",")>-1){var _52e=type.split(/\s*,\s*/);var _52f=[];var i=0;var _530;while(_530=_52e[i++]){_52f.push(_52b(_529,_530,_52a,_52c,_52d));}_52f.remove=function(){for(var i=0;i<_52f.length;i++){_52f[i].remove();}};return _52f;}return _52b(_529,type,_52a,_52c,_52d);};var _531=/^touch/;function _51f(_532,type,_533,_534,_535){var _536=type.match(/(.*):(.*)/);if(_536){type=_536[2];_536=_536[1];return on.selector(_536,type).call(_535,_532,_533);}if(has("touch")){if(_531.test(type)){_533=_537(_533);}if(!has("event-orientationchange")&&(type=="orientationchange")){type="resize";_532=window;_533=_537(_533);}}if(_538){_533=_538(_533);}if(_532.addEventListener){var _539=type in _53a,_53b=_539?_53a[type]:type;_532.addEventListener(_53b,_533,_539);return {remove:function(){_532.removeEventListener(_53b,_533,_539);}};}type="on"+type;if(_53c&&_532.attachEvent){return _53c(_532,type,_533);}throw new Error("Target must be an event emitter");};on.selector=function(_53d,_53e,_53f){return function(_540,_541){var _542=typeof _53d=="function"?{matches:_53d}:this,_543=_53e.bubble;function _544(_545){_542=_542&&_542.matches?_542:dojo.query;while(!_542.matches(_545,_53d,_540)){if(_545==_540||_53f===false||!(_545=_545.parentNode)||_545.nodeType!=1){return;}}return _545;};if(_543){return on(_540,_543(_544),_541);}return on(_540,_53e,function(_546){var _547=_544(_546.target);return _547&&_541.call(_547,_546);});};};function _548(){this.cancelable=false;};function _549(){this.bubbles=false;};var _54a=[].slice,_54b=on.emit=function(_54c,type,_54d){var args=_54a.call(arguments,2);var _54e="on"+type;if("parentNode" in _54c){var _54f=args[0]={};for(var i in _54d){_54f[i]=_54d[i];}_54f.preventDefault=_548;_54f.stopPropagation=_549;_54f.target=_54c;_54f.type=type;_54d=_54f;}do{_54c[_54e]&&_54c[_54e].apply(_54c,args);}while(_54d&&_54d.bubbles&&(_54c=_54c.parentNode));return _54d&&_54d.cancelable&&_54d;};var _53a={};if(!has("event-stopimmediatepropagation")){var _550=function(){this.immediatelyStopped=true;this.modified=true;};var _538=function(_551){return function(_552){if(!_552.immediatelyStopped){_552.stopImmediatePropagation=_550;return _551.apply(this,arguments);}};};}if(has("dom-addeventlistener")){_53a={focusin:"focus",focusout:"blur"};if(has("opera")){_53a.keydown="keypress";}on.emit=function(_553,type,_554){if(_553.dispatchEvent&&document.createEvent){var _555=_553.ownerDocument.createEvent("HTMLEvents");_555.initEvent(type,!!_554.bubbles,!!_554.cancelable);for(var i in _554){var _556=_554[i];if(!(i in _555)){_555[i]=_554[i];}}return _553.dispatchEvent(_555)&&_555;}return _54b.apply(on,arguments);};}else{on._fixEvent=function(evt,_557){if(!evt){var w=_557&&(_557.ownerDocument||_557.document||_557).parentWindow||window;evt=w.event;}if(!evt){return evt;}if(_558&&evt.type==_558.type){evt=_558;}if(!evt.target){evt.target=evt.srcElement;evt.currentTarget=(_557||evt.srcElement);if(evt.type=="mouseover"){evt.relatedTarget=evt.fromElement;}if(evt.type=="mouseout"){evt.relatedTarget=evt.toElement;}if(!evt.stopPropagation){evt.stopPropagation=_559;evt.preventDefault=_55a;}switch(evt.type){case "keypress":var c=("charCode" in evt?evt.charCode:evt.keyCode);if(c==10){c=0;evt.keyCode=13;}else{if(c==13||c==27){c=0;}else{if(c==3){c=99;}}}evt.charCode=c;_55b(evt);break;}}return evt;};var _558,_55c=function(_55d){this.handle=_55d;};_55c.prototype.remove=function(){delete _dojoIEListeners_[this.handle];};var _55e=function(_55f){return function(evt){evt=on._fixEvent(evt,this);var _560=_55f.call(this,evt);if(evt.modified){if(!_558){setTimeout(function(){_558=null;});}_558=evt;}return _560;};};var _53c=function(_561,type,_562){_562=_55e(_562);if(((_561.ownerDocument?_561.ownerDocument.parentWindow:_561.parentWindow||_561.window||window)!=top||has("jscript")<5.8)&&!has("config-_allow_leaks")){if(typeof _dojoIEListeners_=="undefined"){_dojoIEListeners_=[];}var _563=_561[type];if(!_563||!_563.listeners){var _564=_563;_563=Function("event","var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}");_563.listeners=[];_561[type]=_563;_563.global=this;if(_564){_563.listeners.push(_dojoIEListeners_.push(_564)-1);}}var _565;_563.listeners.push(_565=(_563.global._dojoIEListeners_.push(_562)-1));return new _55c(_565);}return _51a.after(_561,type,_562,true);};var _55b=function(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _559=function(){this.cancelBubble=true;};var _55a=on._preventDefault=function(){this.bubbledKeyCode=this.keyCode;if(this.ctrlKey){try{this.keyCode=0;}catch(e){}}this.defaultPrevented=true;this.returnValue=false;};}if(has("touch")){var _566=function(){};var _567=window.orientation;var _537=function(_568){return function(_569){var _56a=_569.corrected;if(!_56a){var type=_569.type;try{delete _569.type;}catch(e){}if(_569.type){_566.prototype=_569;var _56a=new _566;_56a.preventDefault=function(){_569.preventDefault();};_56a.stopPropagation=function(){_569.stopPropagation();};}else{_56a=_569;_56a.type=type;}_569.corrected=_56a;if(type=="resize"){if(_567==window.orientation){return null;}_567=window.orientation;_56a.type="orientationchange";return _568.call(this,_56a);}if(!("rotation" in _56a)){_56a.rotation=0;_56a.scale=1;}var _56b=_56a.changedTouches[0];for(var i in _56b){delete _56a[i];_56a[i]=_56b[i];}}return _568.call(this,_56a);};};}return on;});},"dojo/_base/sniff":function(){define(["./kernel","./lang","../sniff"],function(dojo,lang,has){if(!1){return has;}dojo._name="browser";lang.mixin(dojo,{isBrowser:true,isFF:has("ff"),isIE:has("ie"),isKhtml:has("khtml"),isWebKit:has("webkit"),isMozilla:has("mozilla"),isMoz:has("mozilla"),isOpera:has("opera"),isSafari:has("safari"),isChrome:has("chrome"),isMac:has("mac"),isIos:has("ios"),isAndroid:has("android"),isWii:has("wii"),isQuirks:has("quirks"),isAir:has("air")});dojo.locale=dojo.locale||(has("ie")?navigator.userLanguage:navigator.language).toLowerCase();return has;});},"dojo/errors/create":function(){define(["../_base/lang"],function(lang){return function(name,ctor,base,_56c){base=base||Error;var _56d=function(_56e){if(base===Error){if(Error.captureStackTrace){Error.captureStackTrace(this,_56d);}var err=Error.call(this,_56e),prop;for(prop in err){if(err.hasOwnProperty(prop)){this[prop]=err[prop];}}this.message=_56e;this.stack=err.stack;}else{base.apply(this,arguments);}if(ctor){ctor.apply(this,arguments);}};_56d.prototype=lang.delegate(base.prototype,_56c);_56d.prototype.name=name;_56d.prototype.constructor=_56d;return _56d;};});},"dojo/_base/array":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var _56f={},u;function _570(fn){return _56f[fn]=new Function("item","index","array",fn);};function _571(some){var _572=!some;return function(a,fn,o){var i=0,l=a&&a.length||0,_573;if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_56f[fn]||_570(fn);}if(o){for(;i<l;++i){_573=!fn.call(o,a[i],i,a);if(some^_573){return !_573;}}}else{for(;i<l;++i){_573=!fn(a[i],i,a);if(some^_573){return !_573;}}}return _572;};};function _574(up){var _575=1,_576=0,_577=0;if(!up){_575=_576=_577=-1;}return function(a,x,from,last){if(last&&_575>0){return _578.lastIndexOf(a,x,from);}var l=a&&a.length||0,end=up?l+_577:_576,i;if(from===u){i=up?_576:l+_577;}else{if(from<0){i=l+from;if(i<0){i=_576;}}else{i=from>=l?l+_577:from;}}if(l&&typeof a=="string"){a=a.split("");}for(;i!=end;i+=_575){if(a[i]==x){return i;}}return -1;};};var _578={every:_571(false),some:_571(true),indexOf:_574(true),lastIndexOf:_574(false),forEach:function(arr,_579,_57a){var i=0,l=arr&&arr.length||0;if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _579=="string"){_579=_56f[_579]||_570(_579);}if(_57a){for(;i<l;++i){_579.call(_57a,arr[i],i,arr);}}else{for(;i<l;++i){_579(arr[i],i,arr);}}},map:function(arr,_57b,_57c,Ctr){var i=0,l=arr&&arr.length||0,out=new (Ctr||Array)(l);if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _57b=="string"){_57b=_56f[_57b]||_570(_57b);}if(_57c){for(;i<l;++i){out[i]=_57b.call(_57c,arr[i],i,arr);}}else{for(;i<l;++i){out[i]=_57b(arr[i],i,arr);}}return out;},filter:function(arr,_57d,_57e){var i=0,l=arr&&arr.length||0,out=[],_57f;if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _57d=="string"){_57d=_56f[_57d]||_570(_57d);}if(_57e){for(;i<l;++i){_57f=arr[i];if(_57d.call(_57e,_57f,i,arr)){out.push(_57f);}}}else{for(;i<l;++i){_57f=arr[i];if(_57d(_57f,i,arr)){out.push(_57f);}}}return out;},clearCache:function(){_56f={};}};1&&lang.mixin(dojo,_578);return _578;});},"dojo/_base/json":function(){define(["./kernel","../json"],function(dojo,json){dojo.fromJson=function(js){return eval("("+js+")");};dojo._escapeString=json.stringify;dojo.toJsonIndentStr="\t";dojo.toJson=function(it,_580){return json.stringify(it,function(key,_581){if(_581){var tf=_581.__json__||_581.json;if(typeof tf=="function"){return tf.call(_581);}}return _581;},_580&&dojo.toJsonIndentStr);};return dojo;});},"dojo/_base/window":function(){define("dojo/_base/window",["./kernel","./lang","../sniff"],function(dojo,lang,has){var ret={global:dojo.global,doc:this["document"]||null,body:function(doc){doc=doc||dojo.doc;return doc.body||doc.getElementsByTagName("body")[0];},setContext:function(_582,_583){dojo.global=ret.global=_582;dojo.doc=ret.doc=_583;},withGlobal:function(_584,_585,_586,_587){var _588=dojo.global;try{dojo.global=ret.global=_584;return ret.withDoc.call(null,_584.document,_585,_586,_587);}finally{dojo.global=ret.global=_588;}},withDoc:function(_589,_58a,_58b,_58c){var _58d=ret.doc,oldQ=has("quirks"),_58e=has("ie"),isIE,mode,pwin;try{dojo.doc=ret.doc=_589;dojo.isQuirks=has.add("quirks",dojo.doc.compatMode=="BackCompat",true,true);if(has("ie")){if((pwin=_589.parentWindow)&&pwin.navigator){isIE=parseFloat(pwin.navigator.appVersion.split("MSIE ")[1])||undefined;mode=_589.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}dojo.isIE=has.add("ie",isIE,true,true);}}if(_58b&&typeof _58a=="string"){_58a=_58b[_58a];}return _58a.apply(_58b,_58c||[]);}finally{dojo.doc=ret.doc=_58d;dojo.isQuirks=has.add("quirks",oldQ,true,true);dojo.isIE=has.add("ie",_58e,true,true);}}};1&&lang.mixin(dojo,ret);return ret;});},"dojo/dom-class":function(){define(["./_base/lang","./_base/array","./dom"],function(lang,_58f,dom){var _590="className";var cls,_591=/\s+/,a1=[""];function _592(s){if(typeof s=="string"||s instanceof String){if(s&&!_591.test(s)){a1[0]=s;return a1;}var a=s.split(_591);if(a.length&&!a[0]){a.shift();}if(a.length&&!a[a.length-1]){a.pop();}return a;}if(!s){return [];}return _58f.filter(s,function(x){return x;});};var _593={};cls={contains:function containsClass(node,_594){return ((" "+dom.byId(node)[_590]+" ").indexOf(" "+_594+" ")>=0);},add:function addClass(node,_595){node=dom.byId(node);_595=_592(_595);var cls=node[_590],_596;cls=cls?" "+cls+" ":" ";_596=cls.length;for(var i=0,len=_595.length,c;i<len;++i){c=_595[i];if(c&&cls.indexOf(" "+c+" ")<0){cls+=c+" ";}}if(_596<cls.length){node[_590]=cls.substr(1,cls.length-2);}},remove:function removeClass(node,_597){node=dom.byId(node);var cls;if(_597!==undefined){_597=_592(_597);cls=" "+node[_590]+" ";for(var i=0,len=_597.length;i<len;++i){cls=cls.replace(" "+_597[i]+" "," ");}cls=lang.trim(cls);}else{cls="";}if(node[_590]!=cls){node[_590]=cls;}},replace:function replaceClass(node,_598,_599){node=dom.byId(node);_593[_590]=node[_590];cls.remove(_593,_599);cls.add(_593,_598);if(node[_590]!==_593[_590]){node[_590]=_593[_590];}},toggle:function toggleClass(node,_59a,_59b){node=dom.byId(node);if(_59b===undefined){_59a=_592(_59a);for(var i=0,len=_59a.length,c;i<len;++i){c=_59a[i];cls[cls.contains(node,c)?"remove":"add"](node,c);}}else{cls[_59b?"add":"remove"](node,_59a);}return _59b;}};return cls;});},"dojo/_base/config":function(){define(["../has","require"],function(has,_59c){var _59d={};if(1){var src=_59c.rawConfig,p;for(p in src){_59d[p]=src[p];}}else{var _59e=function(_59f,_5a0,_5a1){for(p in _59f){p!="has"&&has.add(_5a0+p,_59f[p],0,_5a1);}};_59d=1?_59c.rawConfig:this.dojoConfig||this.djConfig||{};_59e(_59d,"config",1);_59e(_59d.has,"",1);}return _59d;});},"dojo/main":function(){define(["./_base/kernel","./has","require","./sniff","./_base/lang","./_base/array","./_base/config","./ready","./_base/declare","./_base/connect","./_base/Deferred","./_base/json","./_base/Color","./has!dojo-firebug?./_firebug/firebug","./_base/browser","./_base/loader"],function(_5a2,has,_5a3,_5a4,lang,_5a5,_5a6,_5a7){if(_5a6.isDebug){_5a3(["./_firebug/firebug"]);}1||has.add("dojo-config-require",1);if(1){var deps=_5a6.require;if(deps){deps=_5a5.map(lang.isArray(deps)?deps:[deps],function(item){return item.replace(/\./g,"/");});if(_5a2.isAsync){_5a3(deps);}else{_5a7(1,function(){_5a3(deps);});}}}return _5a2;});},"dojo/_base/event":function(){define("dojo/_base/event",["./kernel","../on","../has","../dom-geometry"],function(dojo,on,has,dom){if(on._fixEvent){var _5a8=on._fixEvent;on._fixEvent=function(evt,se){evt=_5a8(evt,se);if(evt){dom.normalizeEvent(evt);}return evt;};}var ret={fix:function(evt,_5a9){if(on._fixEvent){return on._fixEvent(evt,_5a9);}return evt;},stop:function(evt){if(has("dom-addeventlistener")||(evt&&evt.preventDefault)){evt.preventDefault();evt.stopPropagation();}else{evt=evt||window.event;evt.cancelBubble=true;on._preventDefault.call(evt);}}};if(1){dojo.fixEvent=ret.fix;dojo.stopEvent=ret.stop;}return ret;});},"dojo/sniff":function(){define(["./has"],function(has){if(1){var n=navigator,dua=n.userAgent,dav=n.appVersion,tv=parseFloat(dav);has.add("air",dua.indexOf("AdobeAIR")>=0),has.add("khtml",dav.indexOf("Konqueror")>=0?tv:undefined);has.add("webkit",parseFloat(dua.split("WebKit/")[1])||undefined);has.add("chrome",parseFloat(dua.split("Chrome/")[1])||undefined);has.add("safari",dav.indexOf("Safari")>=0&&!has("chrome")?parseFloat(dav.split("Version/")[1]):undefined);has.add("mac",dav.indexOf("Macintosh")>=0);has.add("quirks",document.compatMode=="BackCompat");has.add("ios",/iPhone|iPod|iPad/.test(dua));has.add("android",parseFloat(dua.split("Android ")[1])||undefined);if(!has("webkit")){if(dua.indexOf("Opera")>=0){has.add("opera",tv>=9.8?parseFloat(dua.split("Version/")[1])||tv:tv);}if(dua.indexOf("Gecko")>=0&&!has("khtml")&&!has("webkit")){has.add("mozilla",tv);}if(has("mozilla")){has.add("ff",parseFloat(dua.split("Firefox/")[1]||dua.split("Minefield/")[1])||undefined);}if(document.all&&!has("opera")){var isIE=parseFloat(dav.split("MSIE ")[1])||undefined;var mode=document.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}has.add("ie",isIE);}has.add("wii",typeof opera!="undefined"&&opera.wiiremote);}}return has;});},"dojo/request/handlers":function(){define(["../json","../_base/kernel","../_base/array","../has"],function(JSON,_5aa,_5ab,has){has.add("activex",typeof ActiveXObject!=="undefined");var _5ac;if(has("activex")){var dp=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML.DOMDocument"];_5ac=function(_5ad){var _5ae=_5ad.data;if(!_5ae||!_5ae.documentElement){var text=_5ad.text;_5ab.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(text);_5ae=dom;}catch(e){return false;}return true;});}return _5ae;};}var _5af={"javascript":function(_5b0){return _5aa.eval(_5b0.text||"");},"json":function(_5b1){return JSON.parse(_5b1.text||null);},"xml":_5ac};function _5b2(_5b3){var _5b4=_5af[_5b3.options.handleAs];_5b3.data=_5b4?_5b4(_5b3):(_5b3.data||_5b3.text);return _5b3;};_5b2.register=function(name,_5b5){_5af[name]=_5b5;};return _5b2;});},"dojo/aspect":function(){define("dojo/aspect",[],function(){"use strict";var _5b6,_5b7=0;function _5b8(_5b9,type,_5ba,_5bb){var _5bc=_5b9[type];var _5bd=type=="around";var _5be;if(_5bd){var _5bf=_5ba(function(){return _5bc.advice(this,arguments);});_5be={remove:function(){_5be.cancelled=true;},advice:function(_5c0,args){return _5be.cancelled?_5bc.advice(_5c0,args):_5bf.apply(_5c0,args);}};}else{_5be={remove:function(){var _5c1=_5be.previous;var next=_5be.next;if(!next&&!_5c1){delete _5b9[type];}else{if(_5c1){_5c1.next=next;}else{_5b9[type]=next;}if(next){next.previous=_5c1;}}},id:_5b7++,advice:_5ba,receiveArguments:_5bb};}if(_5bc&&!_5bd){if(type=="after"){var next=_5bc;while(next){_5bc=next;next=next.next;}_5bc.next=_5be;_5be.previous=_5bc;}else{if(type=="before"){_5b9[type]=_5be;_5be.next=_5bc;_5bc.previous=_5be;}}}else{_5b9[type]=_5be;}return _5be;};function _5c2(type){return function(_5c3,_5c4,_5c5,_5c6){var _5c7=_5c3[_5c4],_5c8;if(!_5c7||_5c7.target!=_5c3){_5c3[_5c4]=_5c8=function(){var _5c9=_5b7;var args=arguments;var _5ca=_5c8.before;while(_5ca){args=_5ca.advice.apply(this,args)||args;_5ca=_5ca.next;}if(_5c8.around){var _5cb=_5c8.around.advice(this,args);}var _5cc=_5c8.after;while(_5cc&&_5cc.id<_5c9){if(_5cc.receiveArguments){var _5cd=_5cc.advice.apply(this,args);_5cb=_5cd===_5b6?_5cb:_5cd;}else{_5cb=_5cc.advice.call(this,_5cb,args);}_5cc=_5cc.next;}return _5cb;};if(_5c7){_5c8.around={advice:function(_5ce,args){return _5c7.apply(_5ce,args);}};}_5c8.target=_5c3;}var _5cf=_5b8((_5c8||_5c7),type,_5c5,_5c6);_5c5=null;return _5cf;};};var _5d0=_5c2("after");var _5d1=_5c2("before");var _5d2=_5c2("around");return {before:_5d1,around:_5d2,after:_5d0};});},"dojo/ready":function(){define("dojo/ready",["./_base/kernel","./has","require","./domReady","./_base/lang"],function(dojo,has,_5d3,_5d4,lang){var _5d5=0,_5d6,_5d7=[],_5d8=0,_5d9=function(){_5d5=1;dojo._postLoad=dojo.config.afterOnLoad=true;if(_5d7.length){_5d6(_5da);}},_5da=function(){if(_5d5&&!_5d8&&_5d7.length){_5d8=1;var f=_5d7.shift();try{f();}finally{_5d8=0;}_5d8=0;if(_5d7.length){_5d6(_5da);}}};_5d3.on("idle",_5da);_5d6=function(){if(_5d3.idle()){_5da();}};var _5db=dojo.ready=dojo.addOnLoad=function(_5dc,_5dd,_5de){var _5df=lang._toArray(arguments);if(typeof _5dc!="number"){_5de=_5dd;_5dd=_5dc;_5dc=1000;}else{_5df.shift();}_5de=_5de?lang.hitch.apply(dojo,_5df):function(){_5dd();};_5de.priority=_5dc;for(var i=0;i<_5d7.length&&_5dc>=_5d7[i].priority;i++){}_5d7.splice(i,0,_5de);_5d6();};1||has.add("dojo-config-addOnLoad",1);if(1){var dca=dojo.config.addOnLoad;if(dca){_5db[(lang.isArray(dca)?"apply":"call")](dojo,dca);}}if(1&&dojo.config.parseOnLoad&&!dojo.isAsync){_5db(99,function(){if(!dojo.parser){dojo.deprecated("Add explicit require(['dojo/parser']);","","2.0");_5d3(["dojo/parser"]);}});}if(1){_5d4(_5d9);}else{_5d9();}return _5db;});},"dojo/_base/connect":function(){define(["./kernel","../on","../topic","../aspect","./event","../mouse","./sniff","./lang","../keys"],function(dojo,on,hub,_5e0,_5e1,_5e2,has,lang){has.add("events-keypress-typed",function(){var _5e3={charCode:0};try{_5e3=document.createEvent("KeyboardEvent");(_5e3.initKeyboardEvent||_5e3.initKeyEvent).call(_5e3,"keypress",true,true,null,false,false,false,false,9,3);}catch(e){}return _5e3.charCode==0&&!has("opera");});function _5e4(obj,_5e5,_5e6,_5e7,_5e8){_5e7=lang.hitch(_5e6,_5e7);if(!obj||!(obj.addEventListener||obj.attachEvent)){return _5e0.after(obj||dojo.global,_5e5,_5e7,true);}if(typeof _5e5=="string"&&_5e5.substring(0,2)=="on"){_5e5=_5e5.substring(2);}if(!obj){obj=dojo.global;}if(!_5e8){switch(_5e5){case "keypress":_5e5=_5e9;break;case "mouseenter":_5e5=_5e2.enter;break;case "mouseleave":_5e5=_5e2.leave;break;}}return on(obj,_5e5,_5e7,_5e8);};var _5ea={106:42,111:47,186:59,187:43,188:44,189:45,190:46,191:47,192:96,219:91,220:92,221:93,222:39,229:113};var _5eb=has("mac")?"metaKey":"ctrlKey";var _5ec=function(evt,_5ed){var faux=lang.mixin({},evt,_5ed);_5ee(faux);faux.preventDefault=function(){evt.preventDefault();};faux.stopPropagation=function(){evt.stopPropagation();};return faux;};function _5ee(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _5e9;if(has("events-keypress-typed")){var _5ef=function(e,code){try{return (e.keyCode=code);}catch(e){return 0;}};_5e9=function(_5f0,_5f1){var _5f2=on(_5f0,"keydown",function(evt){var k=evt.keyCode;var _5f3=(k!=13)&&k!=32&&(k!=27||!has("ie"))&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222)&&k!=229;if(_5f3||evt.ctrlKey){var c=_5f3?0:k;if(evt.ctrlKey){if(k==3||k==13){return _5f1.call(evt.currentTarget,evt);}else{if(c>95&&c<106){c-=48;}else{if((!evt.shiftKey)&&(c>=65&&c<=90)){c+=32;}else{c=_5ea[c]||c;}}}}var faux=_5ec(evt,{type:"keypress",faux:true,charCode:c});_5f1.call(evt.currentTarget,faux);if(has("ie")){_5ef(evt,faux.keyCode);}}});var _5f4=on(_5f0,"keypress",function(evt){var c=evt.charCode;c=c>=32?c:0;evt=_5ec(evt,{charCode:c,faux:true});return _5f1.call(this,evt);});return {remove:function(){_5f2.remove();_5f4.remove();}};};}else{if(has("opera")){_5e9=function(_5f5,_5f6){return on(_5f5,"keypress",function(evt){var c=evt.which;if(c==3){c=99;}c=c<32&&!evt.shiftKey?0:c;if(evt.ctrlKey&&!evt.shiftKey&&c>=65&&c<=90){c+=32;}return _5f6.call(this,_5ec(evt,{charCode:c}));});};}else{_5e9=function(_5f7,_5f8){return on(_5f7,"keypress",function(evt){_5ee(evt);return _5f8.call(this,evt);});};}}var _5f9={_keypress:_5e9,connect:function(obj,_5fa,_5fb,_5fc,_5fd){var a=arguments,args=[],i=0;args.push(typeof a[0]=="string"?null:a[i++],a[i++]);var a1=a[i+1];args.push(typeof a1=="string"||typeof a1=="function"?a[i++]:null,a[i++]);for(var l=a.length;i<l;i++){args.push(a[i]);}return _5e4.apply(this,args);},disconnect:function(_5fe){if(_5fe){_5fe.remove();}},subscribe:function(_5ff,_600,_601){return hub.subscribe(_5ff,lang.hitch(_600,_601));},publish:function(_602,args){return hub.publish.apply(hub,[_602].concat(args));},connectPublisher:function(_603,obj,_604){var pf=function(){_5f9.publish(_603,arguments);};return _604?_5f9.connect(obj,_604,pf):_5f9.connect(obj,pf);},isCopyKey:function(e){return e[_5eb];}};_5f9.unsubscribe=_5f9.disconnect;1&&lang.mixin(dojo,_5f9);return _5f9;});},"dojo/errors/CancelError":function(){define(["./create"],function(_605){return _605("CancelError",null,null,{dojoType:"cancel"});});}}});(function(){var _606=this.require;_606({cache:{}});!_606.async&&_606(["dojo"]);_606.boot&&_606.apply(null,_606.boot);})();
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/full-json.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,38 @@
+/* Saves the Full JSON at each modification */
+
+
+Rkns.jsonIO = function(_renkan, _opts) {
+ var _proj = _renkan.project;
+ if (typeof _opts.http_method == "undefined") {
+ _opts.http_method = 'PUT';
+ }
+ var _load = function() {
+ Rkns.$.getJSON(_opts.url, function(_data) {
+ _proj.set(_data);
+ _renkan.renderer.autoScale();
+ });
+ }
+ var _save = function() {
+ var _data = _proj.toJSON();
+ Rkns.$.ajax({
+ type: _opts.http_method,
+ url: _opts.url,
+ contentType: "application/json",
+ data: JSON.stringify(_data),
+ success: function(data, textStatus, jqXHR) {
+ }
+ });
+
+ }
+ var _thrSave = Rkns._.throttle(
+ function() {
+ setTimeout(_save, 100)
+ }, 1000);
+ _load();
+ _proj.on("add:nodes add:edges add:users", function(_model) {
+ _model.on("change remove", function(_model) {
+ _thrSave();
+ });
+ _thrSave();
+ });
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/i18n.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,58 @@
+Rkns.i18n = {
+ en: {
+ edit_node: "Edit Node",
+ edit_edge: "Edit Edge",
+ edit_title: "Title:",
+ edit_uri: "URI:",
+ edit_description: "Description:",
+ edit_from: "From:",
+ edit_to: "To:",
+ edit_image: "Image:",
+ full_screen: "Full Screen",
+ add_node: "Add Node",
+ add_edge: "Add Edge",
+ created_by: "Created by:",
+ zoom_in: "Zoom In",
+ zoom_out: "Zoom Out",
+ caption_edit: "Edit",
+ caption_remove: "Remove",
+ caption_link: "Link to another node",
+ notif_add_node: "Click on the background canvas to add a node",
+ notif_start_edge: "Click on a first node to start the edge",
+ notif_end_edge: "Click on a second node to complete the edge",
+ search_on_twitter: "Twitter",
+ wiki_fr: "French Wikipedia",
+ wiki_en: "English Wikipedia",
+ wiki_ja: "Japanese Wikipedia",
+ wiki_: "Wikipedia (Other Language)",
+ untitled_project: "Untitled project"
+ },
+ fr: {
+ edit_node: "Édition d’un nœud",
+ edit_edge: "Édition d’un lien",
+ edit_title: "Titre :",
+ edit_uri: "URI :",
+ edit_description: "Description :",
+ edit_from: "De :",
+ edit_to: "Vers :",
+ edit_image: "Image :",
+ full_screen: "Mode plein écran",
+ add_node: "Ajouter un nœud",
+ add_edge: "Ajouter un lien",
+ created_by: "Créé par :",
+ zoom_in: "Agrandir l’échelle",
+ zoom_out: "Rapetisser l’échelle",
+ caption_edit: "Éditer",
+ caption_remove: "Supprimer",
+ caption_link: "Créer un lien",
+ notif_add_node: "Cliquer sur le fond du graphe pour rajouter un nœud",
+ notif_start_edge: "Cliquer sur un premier nœud pour commencer le lien",
+ notif_end_edge: "Cliquer sur un second nœud pour terminer le lien",
+ search_on_twitter: "Twitter",
+ wiki_fr: "Wikipedia en Français",
+ wiki_en: "Wikipedia en Anglais",
+ wiki_ja: "Wikipedia en Japonais",
+ wiki_: "Wikipedia (Autre langue)",
+ untitled_project: "Projet sans titre"
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/ldtjson-bin.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,87 @@
+Rkns.Ldt = {}
+
+Rkns.Ldt.ProjectBin = Rkns.Utils.inherit(Rkns._BaseBin);
+
+Rkns.Ldt.ProjectBin.prototype.tagTemplate = Rkns._.template(
+ '<li class="Rk-Bin-Item" data-image="<%=static_url%>img/ldt-tag.png" data-uri="<%=ldt_platform%>ldtplatform/ldt/front/search/?search=<%=encodedtitle%>&field=all" data-title="<%-title%>" data-description="Tag \'<%-title%>\'">'
+ + '<img class="Rk-Ldt-Tag-Icon" src="<%=static_url%>img/ldt-tag.png" /><h4><%-title%></h4><div class="Rk-Clear"></div></li>'
+);
+
+Rkns.Ldt.ProjectBin.prototype.annotationTemplate = Rkns._.template(
+ '<li class="Rk-Bin-Item" data-image="<%=image%>" data-uri="<%=ldt_platform%>ldtplatform/ldt/front/player/<%=mediaid%>/#id=<%=annotationid%>" data-title="<%-title%>" data-description="<%-description%>">'
+ + '<img class="Rk-Ldt-Annotation-Icon" src="<%=image%>"/><h4><%-title%></h4><p><%-description%></p><p>Start: <%=start%>, End: <%=end%>, Duration: <%=duration%></p><div class="Rk-Clear"></div></li>'
+);
+
+Rkns.Ldt.ProjectBin.prototype._init = function(_renkan, _opts) {
+ this.proj_id = _opts.project_id;
+ this.ldt_platform = _opts.ldt_platform || "http://ldt.iri.centrepompidou.fr/";
+ this.title_$.html(_opts.title);
+ this.refresh();
+}
+
+Rkns.Ldt.ProjectBin.prototype.refresh = function() {
+ var _this = this;
+ function convertTC(_ms) {
+ function pad(_n) {
+ var _res = _n.toString();
+ while (_res.length < 2) {
+ _res = '0' + _res;
+ }
+ return _res;
+ }
+ var _totalSeconds = Math.abs(Math.floor(_ms/1000)),
+ _hours = Math.floor(_totalSeconds / 3600),
+ _minutes = (Math.floor(_totalSeconds / 60) % 60),
+ _seconds = _totalSeconds % 60,
+ _res = '';
+ if (_hours) {
+ _res += pad(_hours) + ':'
+ }
+ _res += pad(_minutes) + ':' + pad(_seconds);
+ return _res;
+ }
+ Rkns.$.ajax({
+ url: this.ldt_platform + 'ldtplatform/ldt/cljson/id/' + this.proj_id,
+ dataType: "jsonp",
+ success: function(_data) {
+ var _html = '<li><h3>Tags</h3></li>',
+ _projtitle = _data.meta["dc:title"];
+ _this.title_$.html('LDT Project: "' + _projtitle + '"');
+ _html += Rkns._(_data.tags).map(function(_tag) {
+ var _title = _tag.meta["dc:title"]
+ return _this.tagTemplate({
+ ldt_platform: _this.ldt_platform,
+ title: _title,
+ encodedtitle : encodeURIComponent(_title),
+ static_url: _this.renkan.static_url
+ })
+ }).join("");
+ _html += '<li><h3>Annotations</h3></li>';
+ _html += Rkns._(_data.annotations).map(function(_annotation) {
+ var _description = _annotation.content.description,
+ _title = _annotation.content.title.replace(_description,""),
+ _duration = _annotation.end - _annotation.begin,
+ _img = (
+ (_annotation.content && _annotation.content.img && _annotation.content.img.src)
+ ? _annotation.content.img.src
+ : _this.renkan.static_url + ( _duration ? "img/ldt-segment.png" : "img/ldt-point.png" )
+ );
+ return _this.annotationTemplate({
+ ldt_platform: _this.ldt_platform,
+ title: _title,
+ description: _description,
+ start: convertTC(_annotation.begin),
+ end: convertTC(_annotation.end),
+ duration: convertTC(_duration),
+ mediaid: _annotation.media,
+ annotationid: _annotation.id,
+ image: _img,
+ static_url: _this.renkan.static_url
+ });
+ }).join("");
+
+ _this.main_$.html(_html);
+ _renkan.resizeBins();
+ }
+ });
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/main.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2012 Institut de recherche et d'innovation
+ * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron
+ *
+ * contact@iri.centrepompidou.fr
+ * http://www.iri.centrepompidou.fr
+ *
+ * This software is a computer program whose purpose is to show and add annotations on a video .
+ * This software is governed by the CeCILL-C license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-C
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+*/
+
+/* Declaring the Renkan Namespace Rkns and Default values */
+
+if (typeof Rkns !== "object") {
+ Rkns = {}
+}
+
+Rkns.$ = jQuery;
+
+Rkns._ = _;
+
+Rkns._BaseBin = function(_renkan, _opts) {
+ if (typeof _renkan !== "undefined") {
+ this.renkan = _renkan;
+ this.renkan.$.find(".Rk-Bin-Main").hide();
+ this.$ = Rkns.$('<li>')
+ .addClass("Rk-Bin")
+ .appendTo(_renkan.$.find(".Rk-Bin-List"));
+ this.title_icon_$ = Rkns.$('<span>')
+ .addClass("Rk-Bin-Title-Icon")
+ .appendTo(this.$);
+
+ var _this = this;
+
+ Rkns.$('<a>')
+ .attr("href","#")
+ .addClass("Rk-Bin-Close")
+ .html('×')
+ .appendTo(this.$)
+ .click(function() {
+ _this.destroy();
+ return false;
+ });
+ Rkns.$('<a>')
+ .attr("href","#")
+ .addClass("Rk-Bin-Refresh")
+ .appendTo(this.$)
+ .click(function() {
+ _this.refresh();
+ return false;
+ });
+ this.title_$ = Rkns.$('<h2>')
+ .addClass("Rk-Bin-Title")
+ .appendTo(this.$);
+ this.main_$ = Rkns.$('<div>')
+ .addClass("Rk-Bin-Main")
+ .appendTo(this.$);
+ this.title_$.html(_opts.title || '(new bin)');
+ this.renkan.resizeBins();
+
+ if (_opts.auto_refresh) {
+ window.setInterval(function() {
+ _this.refresh();
+ },_opts.auto_refresh)
+ }
+ }
+}
+
+Rkns._BaseBin.prototype.destroy = function() {
+ this.$.detach();
+ this.renkan.resizeBins();
+}
+
+/* Point of entry */
+
+Rkns.Renkan = function(_opts) {
+ if (typeof _opts.language !== "string" || typeof Rkns.i18n[_opts.language] == "undefined") {
+ _opts.language = "en";
+ }
+ if (typeof _opts.container !== "string") {
+ _opts.container = "renkan";
+ }
+ if (typeof _opts.search !== "object" || !_opts.search) {
+ _opts.search = [];
+ }
+ if (typeof _opts.static_url !== "string") {
+ _opts.static_url = "";
+ }
+ this.project = new Rkns.Models.Project();
+ this.language = _opts.language;
+ this.static_url = _opts.static_url;
+ this.l10n = Rkns.i18n[_opts.language];
+ if (typeof _opts.user_id !== "undefined") {
+ this.current_user = _opts.user_id;
+ }
+ this.$ = Rkns.$("#" + _opts.container);
+ this.$
+ .addClass("Rk-Main")
+ .html(this.template());
+ this.renderer = new Rkns.Renderer.Scene(this);
+ this.tabs = [];
+ this.search_engines = [];
+ this.selected_bin_item = undefined;
+ var _this = this;
+ this.$.mouseup(function() {
+ _this.selected_bin_item = undefined;
+ _this.$.find(".Rk-Bin-Item.dragging").removeClass("dragging");
+ });
+ if (!_opts.search.length) {
+ this.$.find(".Rk-Search-Form").detach();
+ } else {
+ var _tmpl = Rkns._.template('<li class="<%= className %>" data-key="<%= key %>"><%= title %></li>'),
+ _select = this.$.find(".Rk-Search-List"),
+ _input = this.$.find(".Rk-Search-Input"),
+ _form = this.$.find(".Rk-Search-Form");
+ Rkns._(_opts.search).each(function(_search, _key) {
+ var _searchObj = new _search.type(_this, _search);
+ _this.search_engines.push(_searchObj);
+ });
+ _select.html(
+ Rkns._(this.search_engines).map(function(_search, _key) {
+ return _tmpl({
+ key: _key,
+ title: _search.getSearchTitle(),
+ className: _search.getBgClass()
+ });
+ }).join("")
+ );
+ _select.find("li").click(function() {
+ var _el = Rkns.$(this);
+ _this.setSearchEngine(_el.attr("data-key"));
+ _form.submit();
+ });
+ _form.submit(function() {
+ if (_input.val()) {
+ var _search = _this.search_engine;
+ _search.search(_input.val());
+ }
+ return false;
+ });
+ this.$.find(".Rk-Search-Current").mouseenter(
+ function() { _select.slideDown(); }
+ );
+ this.$.find(".Rk-Search-Select").mouseleave(
+ function() { _select.slideUp(); }
+ );
+ this.setSearchEngine(0);
+ }
+ Rkns._(_opts.bins).each(function(_bin) {
+ _this.tabs.push(new _bin.bin(_this, _bin));
+ });
+
+ this.$.find(".Rk-Bins")
+ .on("click",".Rk-Bin-Title,.Rk-Bin-Title-Icon", function() {
+ var _mainDiv = Rkns.$(this).siblings(".Rk-Bin-Main");
+ if (_mainDiv.is(":hidden")) {
+ _this.$.find(".Rk-Bin-Main").slideUp();
+ _mainDiv.slideDown();
+ }
+ }).on("mousedown", ".Rk-Bin-Item", function() {
+ var _t = Rkns.$(this);
+ _t.addClass("dragging");
+ _this.selected_bin_item = {
+ uri : $(_t).attr("data-uri"),
+ title : $(_t).attr("data-title"),
+ description : $(_t).attr("data-description"),
+ image: $(_t).attr("data-image")
+ }
+ return false;
+ }).on("mouseover", ".Rk-Bin-Item", function(_e) {
+ var _t = Rkns.$(this);
+ if (_t && $(_t).attr("data-uri")) {
+ var _models = _this.project.get("nodes").where({
+ uri: $(_t).attr("data-uri")
+ });
+ Rkns._(_models).each(function(_model) {
+ _this.renderer.highlightModel(_model);
+ });
+ }
+ }).mouseout(function() {
+ _this.renderer.unhighlightAll();
+ });
+ Rkns.$(window).resize(function() {
+ _this.resizeBins();
+ });
+}
+
+Rkns.Renkan.prototype.template = Rkns._.template(
+ '<div class="Rk-Title"><h1>Hyper Plateau</h1></div><div class="Rk-Bins">'
+ + '<form class="Rk-Search-Form"><input class="Rk-Search-Input" type="text" placeholder="Search" />'
+ + '<div class="Rk-Search-Select"><div class="Rk-Search-Current"></div><ul class="Rk-Search-List"></ul></div>'
+ + '<input type="submit" value="" class="Rk-Search-Submit" /></form>'
+ + '<ul class="Rk-Bin-List"></ul></div><div class="Rk-Render Rk-Render-Panel"></div>'
+);
+
+
+Rkns.Renkan.prototype.setSearchEngine = function(_key) {
+ this.search_engine = this.search_engines[_key];
+ this.$.find(".Rk-Search-Current").attr("class","Rk-Search-Current " + this.search_engine.getBgClass());
+}
+
+Rkns.Renkan.prototype.resizeBins = function() {
+ var _d = + this.$.find(".Rk-Search-Form").outerHeight();
+ this.$.find(".Rk-Bin-Title").each(function() {
+ _d += Rkns.$(this).outerHeight();
+ });
+ this.$.find(".Rk-Bin-Main").css({
+ height: this.$.find(".Rk-Bins").height() - _d
+ });
+}
+
+/* Utility functions */
+
+Rkns.Utils = {
+ _ID_AUTO_INCREMENT : 0,
+ _ID_BASE : (function(_d) {
+ function pad(n){return n<10 ? '0'+n : n}
+ function fillrand(n) {
+ var _res = ''
+ for (var i=0; i<n; i++) {
+ _res += Math.floor(16*Math.random()).toString(16);
+ }
+ return _res;
+ }
+ return _d.getUTCFullYear() + '-'
+ + pad(_d.getUTCMonth()+1) + '-'
+ + pad(_d.getUTCDate()) + '-'
+ + fillrand(16);
+ })(new Date()),
+ getUID : function(_base) {
+ var _n = (++this._ID_AUTO_INCREMENT).toString(16),
+ _base = (typeof _base === "undefined" ? "" : _base + "-" );
+ while (_n.length < 4) {
+ _n = '0' + _n
+ }
+ return _base + this._ID_BASE + '-' + _n;
+ },
+ inherit : function(_baseClass, _callbefore) {
+ var _class = function() {
+ if (typeof _callbefore === "function") {
+ _callbefore.apply(this, Array.prototype.slice.call(arguments, 0));
+ }
+ _baseClass.apply(this, Array.prototype.slice.call(arguments, 0));
+ if (typeof this._init == "function") {
+ this._init.apply(this, Array.prototype.slice.call(arguments, 0));
+ }
+ }
+ _class.prototype = new _baseClass();
+ return _class;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/main_coweb.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,24 @@
+//
+// Cooperative web application template.
+//
+// Copyright (c) The Dojo Foundation 2011. All Rights Reserved.
+//
+
+// assumes admin servlet deployed with the application
+var cowebConfig = {
+ adminUrl : './admin'
+};
+
+//require(['corenkan']);
+
+require({moduleUrl : 'lib'},
+ ['coweb/main','dojo', 'corenkan'],
+function(coweb, dojo, corenkan) {
+ // do application setup here
+
+ dojo.ready(function() {
+ //this.collab = corenkan.app.collab;
+ });
+
+});
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/main_test_models.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,306 @@
+(function() {
+
+ var root = this;
+
+ var Backbone = root.Backbone;
+
+ var Rkns = root.Rkns = {};
+
+ root.ModelView = Backbone.View.extend({
+
+ events : {
+ "click .show_form" : "show_form",
+ "click .remove_button" : "remove_click",
+ },
+
+ initialize: function(options) {
+ _.bindAll(this);
+ this.template = _.template(options.template);
+ this.model.bind("change", this.render);
+ this.form_view = options.form_view;
+ this.form_el = options.form_el;
+ if(typeof options.getJSON === "function") {
+ this.getJSON = options.getJSON;
+ }
+ },
+ render: function() {
+ $(this.el).html(this.template(this.getJSON()));
+ return this;
+ },
+ show_form: function(evt) {
+ if(typeof this.form_view !== "undefined") {
+ this.form_view.render();
+ $(this.form_el).empty();
+ $(this.form_el).append(this.form_view.el);
+ }
+ },
+ getJSON : function() {
+ return this.model.toJSON();
+ },
+ remove_click : function(evt) {
+ var obj_id = $(evt.currentTarget).attr("value");
+ if(typeof this.model.collection !== "undefined") {
+ this.model.collection.remove(this.model);
+ }
+ },
+
+ });
+
+ root.ColView = Backbone.View.extend({
+ initialize: function(options) {
+
+ _.bindAll(this);
+ this.element = options.element;
+ this.element_form = options.element_form;
+ this.element_form_el = options.element_form_el;
+ this.rendered = false;
+
+ var that = this;
+ this.element_views = [];
+
+ var that = this;
+ this.collection.each(function(elt) {
+ that.add(elt);
+ });
+
+ this.collection.bind('add', this.add);
+ this.collection.bind('remove', this.remove);
+ },
+
+ render : function() {
+ this.rendered = true;
+ var that = this;
+ this.$el.empty();
+ _(this.element_views).each(function(dvs){
+ that.$el.append(dvs.disp.render().el);
+ });
+
+ return this;
+ },
+
+ add : function(elt) {
+
+ var fv_args = _.extend({}, this.element_form, {model: elt});
+ var fv = new FormView(fv_args);
+
+ var dv_args = _.extend({}, this.element, {model: elt, tagName: 'li', form_view: fv, form_el: this.element_form_el});
+ var dv = new ModelView(dv_args);
+
+ this.element_views.push({disp:dv, form:fv});
+
+ if(this.rendered) {
+ this.$el.append(dv.render().el);
+ }
+ },
+
+
+ remove : function(elt) {
+ var viewsToRemove = _(this.element_views).select(function(cvs) { return cvs.disp.model === elt; })[0];
+ this.element_views = _(this.element_views).without(viewsToRemove);
+
+ if(this.rendered) {
+ viewsToRemove.disp.$el.remove();
+ viewsToRemove.form.$el.remove();
+ }
+ },
+
+ remove_click : function(evt) {
+ var obj_id = $(evt.currentTarget).attr("value");
+ this.collection.remove(this.collection.get(obj_id));
+ }
+
+ });
+
+ root.FormView = Backbone.View.extend({
+ events : {
+ "change .form_field": "changed"
+ },
+ initialize: function(options) {
+ _.bindAll(this);
+ this.template = _.template(options.template);
+ this.model.bind("change", this.render);
+ if(typeof options.getJSON === "function") {
+ this.getJSON = options.getJSON;
+ }
+ },
+ render: function() {
+ this.$el.html(this.template(this.getJSON()));
+ return this;
+ },
+ changed: function(evt) {
+ var value = $(evt.currentTarget).val();
+ var field_name = $(evt.currentTarget).attr("name");
+ if(this.model.get(field_name) != value) {
+ this.model.set(field_name, value);
+ }
+ },
+ getJSON : function() {
+ return this.model.toJSON();
+ }
+ });
+
+
+ root.SelectCurrentUserView = Backbone.View.extend({
+ initialize: function(options) {
+ _.bindAll(this);
+ this.rendered = false;
+
+ this.child_view_constructor = options.child_view_constructor;
+ this.child_tag_name = options.child_tag_name;
+
+ this.children_views = [];
+ this.collection.each(this.add);
+
+ this.collection.bind('add', this.add);
+ this.collection.bind('remove', this.remove);
+ },
+ add: function(elt) {
+ var child_view = new this.child_view_constructor({
+ model: elt,
+ tagName : this.child_tag_name
+ });
+ this.children_views.push(child_view);
+
+ if (this.rendered) {
+ this.$el.append(child_view.render().el);
+ }
+ },
+ remove: function(elt) {
+ var view_to_remove = _(this.children_views).select(function(cv) { return cv.model === elt; })[0];
+ this.children_views = _(this.children_views).without(view_to_remove);
+ if (this.rendered) {
+ view_to_remove.$el.remove();
+ }
+ },
+ render: function() {
+ this.rendered = true;
+ var that = this;
+
+ this.$el.empty().html("<option value=\"\">Unknown</option>");
+
+ _(this.children_views).each(function(cv){
+ that.$el.append(cv.render().el);
+ });
+
+ return this;
+ }
+
+ });
+
+ root.SelectUserView = Backbone.View.extend({
+ initialize: function(options) {
+ _.bindAll(this);
+ this.model.bind("change", this.render);
+ },
+ render: function() {
+ this.$el.val(this.model.id).text(this.model.get("title"));
+ return this;
+ }
+ });
+
+ root.CurrentUserView = Backbone.View.extend({
+ initialize : function() {
+ this._select_view = new SelectCurrentUserView({
+ el : this.el,
+ collection : this.model.get("users"),
+ child_view_constructor: SelectUserView,
+ child_tag_name: "option",
+ });
+ },
+ render: function() {
+ this.$el.empty();
+ this._select_view.render();
+ return this;
+ }
+
+ });
+
+
+ root.BasicListView = Backbone.View.extend({
+
+ initialize: function(options) {
+ _.bindAll(this);
+
+ this.element_view_constructor = options.element_view_constructor;
+ if(typeof options.template !== "undefined") {
+ this.template = _.template(options.template);
+ }
+
+ this.rendered = false;
+ this.element_views = [];
+ this.collection.each(this.add);
+
+ this.collection.bind('add', this.add);
+ this.collection.bind('remove', this.remove);
+ this.collection.bind('reset', this.reset);
+ this.collection.bind('destroy', this.destroy);
+ },
+
+ render: function() {
+ this.rendered = true;
+ var that = this;
+ this.$el.empty();
+ if(typeof this.template !== "undefined") {
+ var data = {};
+ if(typeof this.model !== "undefined") {
+ data = this.$el.model.toJSON();
+ }
+ this.$el.html(this.template(data));
+ }
+ _(this.element_views).each(function(dvs){
+ that.$el.append(dvs.render().el);
+ });
+
+ return this;
+ },
+
+ add: function(elt) {
+ var element_view = new this.element_view_constructor({model: elt});
+ this.element_views.push(element_view);
+ if(this.rendered) {
+ this.$el.append(element_view.render().el);
+ }
+ },
+
+ remove: function(elt) {
+ var element_view = _(this.element_views).select(function(cv) {return cv.model === elt;})[0];
+ this.element_views = _(this.element_views).without(element_view);
+ if(this.rendered) {
+ element_view.$el.remove();
+ }
+
+ },
+
+ reset: function() {
+ _(this.element_views).each(function(cv) {
+ cv.$el.remove();
+ });
+ this.element_views = [];
+ this.collection.each(this.add);
+ }
+
+ });
+
+
+ root.BasicModelView = Backbone.View.extend({
+
+ initialize: function(options) {
+ _.bindAll(this);
+ if(typeof options.template !== "undefined") {
+ this.template = _.template(options.template);
+ }
+ if(typeof options.getJSON === "function") {
+ this.getJSON = options.getJSON;
+ }
+ this.model.bind("change", this.render);
+ },
+ render: function() {
+ $(this.el).html(this.template(this.getJSON()));
+ return this;
+ },
+ getJSON : function() {
+ return this.model.toJSON();
+ }
+ });
+
+}).call(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/models.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,219 @@
+(function() {
+
+ var root = this;
+
+ var Backbone = root.Backbone;
+
+ var Models = root.Rkns.Models = {};
+
+
+ Models.getUID = function(obj) {
+ var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ });
+ return obj.type + "-" + guid;
+ };
+
+
+ var RenkanModel = Backbone.RelationalModel.extend({
+ idAttribute : "_id",
+ constructor: function(options) {
+
+ if (typeof options !== "undefined") {
+ options._id = options._id || options.id || Models.getUID(this);
+ options.title = options.title || "(untitled " + this.type + ")";
+ options.description = options.description || "";
+ options.uri = options.uri || "";
+
+ if(typeof this.prepare === "function") {
+ options = this.prepare(options);
+ }
+ }
+ Backbone.RelationalModel.prototype.constructor.call(this, options);
+ },
+ validate: function() {
+ if(!this.type) {
+ return "object has no type";
+ }
+ },
+ addReference : function(_options, _propName, _list, _id, _default) {
+ var _element = _list.get(_id);
+ if (typeof _element === "undefined" && typeof _default !== "undefined") {
+ _options[_propName ] = _default;
+ }
+ else {
+ _options[_propName ] = _element;
+ }
+ }
+ });
+
+ // USER
+ var User = Models.User = RenkanModel.extend({
+ type: "user",
+ prepare: function(options) {
+ options.color = options.color || "#666666";
+ return options;
+ },
+ toJSON: function() {
+ return {
+ _id: this.get("_id"),
+ title: this.get("title"),
+ uri: this.get("uri"),
+ description: this.get("description"),
+ color: this.get("color"),
+ };
+ },
+ });
+
+ // NODE
+ var Node = Models.Node = RenkanModel.extend({
+ type: "node",
+ relations: [{
+ type: Backbone.HasOne,
+ key: "created_by",
+ relatedModel: User
+ }],
+ prepare: function(options) {
+ project = options.project;
+ this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
+ options.description = options.description || "";
+ return options;
+ },
+ toJSON: function() {
+ return {
+ _id: this.get("_id"),
+ title: this.get("title"),
+ uri: this.get("uri"),
+ description: this.get("description"),
+ position: this.get("position"),
+ image: this.get("image"),
+ created_by: this.get("created_by") ? this.get("created_by").get("_id") : null
+ };
+ },
+ });
+
+ // EDGE
+ var Edge = Models.Edge = RenkanModel.extend({
+ type: "edge",
+ relations: [
+ {
+ type: Backbone.HasOne,
+ key: "created_by",
+ relatedModel: User
+ },
+ {
+ type: Backbone.HasOne,
+ key: "from",
+ relatedModel: Node
+ },
+ {
+ type: Backbone.HasOne,
+ key: "to",
+ relatedModel: Node
+ },
+ ],
+ prepare: function(options) {
+ project = options.project;
+ this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
+ this.addReference(options, "from", project.get("nodes"), options.from);
+ this.addReference(options, "to", project.get("nodes"), options.to);
+ return options;
+ },
+ toJSON: function() {
+ return {
+ _id: this.get("_id"),
+ title: this.get("title"),
+ uri: this.get("uri"),
+ description: this.get("description"),
+ from: this.get("from") ? this.get("from").get("_id") : null,
+ to: this.get("to") ? this.get("to").get("_id") : null,
+ created_by: this.get("created_by") ? this.get("created_by").get("_id") : null
+ };
+ },
+ });
+
+ // PROJECT
+ var Project = Models.Project = RenkanModel.extend({
+ type: "project",
+ relations: [
+ {
+ type: Backbone.HasMany,
+ key: "users",
+ relatedModel: User,
+ reverseRelation: {
+ key: 'project',
+ includeInJSON: '_id'
+ },
+ },
+ {
+ type: Backbone.HasMany,
+ key: "nodes",
+ relatedModel: Node,
+ reverseRelation: {
+ key: 'project',
+ includeInJSON: '_id'
+ },
+ },
+ {
+ type: Backbone.HasMany,
+ key: "edges",
+ relatedModel: Edge,
+ reverseRelation: {
+ key: 'project',
+ includeInJSON: '_id'
+ },
+ }
+ ],
+ addUser: function(_props, _options) {
+ _props.project = this;
+ var _user = new User(_props);
+ this.get("users").push(_user, _options);
+ return _user;
+ },
+ addNode: function(_props, _options) {
+ _props.project = this;
+ var _node = new Node(_props);
+ this.get("nodes").push(_node, _options);
+ return _node;
+ },
+ addEdge: function(_props, _options) {
+ _props.project = this;
+ var _edge = new Edge(_props);
+ this.get("edges").push(_edge, _options);
+ return _edge;
+ },
+ removeNode: function(_model) {
+ this.get("nodes").remove(_model);
+ },
+ removeEdge: function(_model) {
+ this.get("edges").remove(_model);
+ },
+ validate: function(options) {
+ var _project = this;
+ _(options.users).each(function(_item) {
+ _item.project = _project;
+ });
+ _(options.nodes).each(function(_item) {
+ _item.project = _project;
+ });
+ _(options.edges).each(function(_item) {
+ _item.project = _project;
+ });
+ },
+ // Add event handler to remove edges when a node is removed
+ initialize: function() {
+ var _this = this;
+ this.on("remove:nodes", function(_node) {
+ _this.get("edges").remove(
+ _this.get("edges").filter(function(_edge) {
+ return _edge.get("from") == _node || _edge.get("to") == _node;
+ })
+ );
+ });
+ }
+ });
+
+
+}).call(window);
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/paper-renderer.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,1407 @@
+Rkns.Renderer = {
+ _MARGIN_X: 80,
+ _MARGIN_Y: 50,
+ _MIN_DRAG_DISTANCE: 2,
+ _NODE_RADIUS: 25,
+ _NODE_BUTTON_INNER: 26,
+ _NODE_BUTTON_OUTER: 60,
+ _EDGE_BUTTON_INNER: 1,
+ _EDGE_BUTTON_OUTER: 40,
+ _NODE_FONT_SIZE: 10,
+ _EDGE_FONT_SIZE: 9,
+ _NODE_MAX_CHAR: 50,
+ _EDGE_MAX_CHAR: 40,
+ _ARROW_LENGTH: 16,
+ _ARROW_WIDTH: 8,
+ _EDITOR_ARROW_LENGTH : 20,
+ _EDITOR_ARROW_WIDTH : 40,
+ _EDITOR_MARGIN : 15,
+ _EDITOR_PADDING : 10,
+ _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']),
+ _CLICKMODE_ADDNODE : 1,
+ _CLICKMODE_STARTEDGE : 2,
+ _CLICKMODE_ENDEDGE : 3
+}
+
+Rkns.Renderer.Utils = {
+ drawEditBox : function(_coords, _path, _width, _xmargin, _selector) {
+ _selector.css({
+ width: (_width - 2* Rkns.Renderer._EDITOR_PADDING),
+ })
+ var _height = _selector.outerHeight() + 2* Rkns.Renderer._EDITOR_PADDING,
+ _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),
+ _left = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._EDITOR_ARROW_LENGTH ),
+ _right = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._EDITOR_ARROW_LENGTH + _width ),
+ _top = _coords.y - _height / 2;
+ if (_top < Rkns.Renderer._EDITOR_MARGIN) {
+ _top = Math.min( Rkns.Renderer._EDITOR_MARGIN, _coords.y - Rkns.Renderer._EDITOR_ARROW_WIDTH / 2 );
+ }
+ var _bottom = _top + _height;
+ if (_bottom > (paper.view.size.height - Rkns.Renderer._EDITOR_MARGIN)) {
+ _bottom = Math.max( paper.view.size.height - Rkns.Renderer._EDITOR_MARGIN, _coords.y + Rkns.Renderer._EDITOR_ARROW_WIDTH / 2 );
+ _top = _bottom - _height;
+ }
+ _path.segments[0].point
+ = _path.segments[7].point
+ = _coords.add([_isLeft * _xmargin, 0]);
+ _path.segments[1].point.x
+ = _path.segments[2].point.x
+ = _path.segments[5].point.x
+ = _path.segments[6].point.x
+ = _left;
+ _path.segments[3].point.x
+ = _path.segments[4].point.x
+ = _right;
+ _path.segments[2].point.y
+ = _path.segments[3].point.y
+ = _top;
+ _path.segments[4].point.y
+ = _path.segments[5].point.y
+ = _bottom;
+ _path.segments[1].point.y = _coords.y - Rkns.Renderer._EDITOR_ARROW_WIDTH / 2;
+ _path.segments[6].point.y = _coords.y + Rkns.Renderer._EDITOR_ARROW_WIDTH / 2;
+ _path.closed = true;
+ _path.fillColor = new paper.GradientColor(Rkns.Renderer._EDITOR_GRADIENT, [0,_top], [0, _bottom]);
+ _selector.css({
+ left: (Rkns.Renderer._EDITOR_PADDING + Math.min(_left, _right)),
+ top: (Rkns.Renderer._EDITOR_PADDING + _top)
+ });
+ },
+ sector : function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgsrc, _caption) {
+ var _startRads = _startAngle * Math.PI / 180,
+ _endRads = _endAngle * Math.PI / 180,
+ _img = new Image(),
+ _span = _endRads - _startRads,
+ _k = .0879 * _span,
+ _kin = _k * _inR,
+ _kout = _k * _outR,
+ _startdx = - Math.sin(_startRads),
+ _startdy = Math.cos(_startRads),
+ _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx,
+ _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy,
+ _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx,
+ _startYOut = Math.sin(_startRads) * _outR + _padding * _startdy,
+ _enddx = - Math.sin(_endRads),
+ _enddy = Math.cos(_endRads),
+ _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx,
+ _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy,
+ _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx,
+ _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy,
+ _centerR = (_inR + _outR)/2,
+ _centerRads = (_startRads + _endRads) / 2,
+ _centerX = Math.cos(_centerRads) * _centerR,
+ _centerY = Math.sin(_centerRads) * _centerR,
+ _textX = Math.cos(_centerRads) * (_outR + 3),
+ _textY = Math.sin(_centerRads) * (_outR + 3),
+ _segments = [];
+ _segments.push([[_startXIn, _startYIn], [0, 0], [ _kin * _startdx, _kin * _startdy ]]);
+ for (var i = 1; i < 4; i++) {
+ var _rads = i * _span / 4 + _startRads,
+ _dx = - Math.sin(_rads),
+ _dy = Math.cos(_rads),
+ _x = Math.cos(_rads) * _inR,
+ _y = Math.sin(_rads) * _inR;
+ _segments.push([[_x, _y], [ - _kin * _dx, - _kin * _dy], [ _kin * _dx, _kin * _dy ]]);
+ }
+ _segments.push([[_endXIn, _endYIn], [ - _kin * _enddx, - _kin * _enddy ], [0,0]]);
+ _segments.push([[_endXOut, _endYOut], [ 0,0 ], [ - _kout * _enddx, - _kout * _enddy ]]);
+ for (var i = 3; i > 0; i--) {
+ var _rads = i * _span / 4 + _startRads,
+ _dx = - Math.sin(_rads),
+ _dy = Math.cos(_rads),
+ _x = Math.cos(_rads) * _outR,
+ _y = Math.sin(_rads) * _outR;
+ _segments.push([[_x, _y], [ _kout * _dx, _kout * _dy], [ - _kout * _dx, - _kout * _dy ]]);
+ }
+ _segments.push([[_startXOut, _startYOut], [ _kout * _startdx, _kout * _startdy ], [0, 0]]);
+ var _path = new paper.Path();
+ _path.add.apply(_path, _segments);
+ _path.fillColor = "#333333";
+ _path.opacity = .5;
+ _path.closed = true;
+ _path.__representation = _repr;
+ if (_textX >= -2 && _textX <= 2) {
+ if (_textY > 0) {
+ _textY += 6;
+ }
+ }
+ var _text = new paper.PointText(_textX,_textY);
+ _text.characterStyle = {
+ fontSize: 9,
+ fillColor: '#c000c0'
+ };
+ if (_textX > 2) {
+ _text.paragraphStyle.justification = 'left';
+ } else if (_textX < -2) {
+ _text.paragraphStyle.justification = 'right';
+ } else {
+ _text.paragraphStyle.justification = 'center';
+ }
+ _text.visible = false;
+ var _visible = false,
+ _restPos = new paper.Point(-200, -200),
+ _grp = new paper.Group([_path, _text]),
+ _delta = _grp.position,
+ _imgdelta = new paper.Point([_centerX, _centerY]),
+ _currentPos = new paper.Point(0,0);
+ _text.content = _caption;
+ _grp.visible = false;
+ _grp.position = _restPos;
+ var _res = {
+ show: function() {
+ _visible = true;
+ _grp.position = _currentPos.add(_delta);
+ _grp.visible = true;
+ },
+ moveTo: function(_point) {
+ _currentPos = _point;
+ if (_visible) {
+ _grp.position = _point.add(_delta);
+ }
+ },
+ hide: function() {
+ _visible = false;
+ _grp.visible = false;
+ _grp.position = _restPos;
+ },
+ select: function() {
+ _path.opacity = .8;
+ _text.visible = true;
+ },
+ unselect: function() {
+ _path.opacity = .5;
+ _text.visible = false;
+ },
+ destroy: function() {
+ _grp.remove();
+ }
+ }
+ _img.onload = function() {
+ var _h = _img.height;
+ var _raster = new paper.Raster(_img);
+ _raster.position = _imgdelta.add(_grp.position).subtract(_delta);
+ _grp.addChild(_raster);
+ }
+ _img.src = _imgsrc;
+ return _res
+ }
+}
+
+Rkns.Renderer._BaseRepresentation = function(_renderer, _model) {
+ if (typeof _renderer !== "undefined") {
+ this.renderer = _renderer;
+ this.project = _renderer.renkan.project;
+ this.model = _model;
+ if (this.model) {
+ var _this = this;
+ this._changeBinding = function() {
+ _this.redraw();
+ }
+ this._removeBinding = function() {
+ _renderer.removeRepresentation(_this);
+ _renderer.redraw();
+ }
+ this.model.on("change", this._changeBinding );
+ this.model.on("remove", this._removeBinding );
+ }
+ }
+}
+
+Rkns.Renderer._BaseRepresentation.prototype.super = function(_func) {
+ Rkns.Renderer._BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1));
+}
+
+Rkns.Renderer._BaseRepresentation.prototype.select = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.unselect = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.highlight = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.unhighlight = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.mouseup = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.destroy = function() {
+ if (this.model) {
+ this.model.off("change", this._changeBinding );
+ this.model.off("remove", this._removeBinding );
+ }
+}
+
+Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.Node.prototype._init = function() {
+ this.renderer.node_layer.activate();
+ this.type = "Node";
+ this.circle = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS);
+ this.circle.fillColor = '#ffffff';
+ this.circle.__representation = this;
+ this.title = new paper.PointText([0,0]);
+ this.title.characterStyle = {
+ fontSize: Rkns.Renderer._NODE_FONT_SIZE,
+ fillColor: 'black'
+ };
+ this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, null);
+ this.edit_button.node_representation = this;
+ this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, null);
+ this.remove_button.node_representation = this;
+ this.link_button = new Rkns.Renderer.NodeLinkButton(this.renderer, null);
+ this.link_button.node_representation = this;
+ this.title.paragraphStyle.justification = 'center';
+}
+
+Rkns.Renderer.Node.prototype.redraw = function() {
+ var _model_coords = new paper.Point(this.model.get("position"));
+ this.paper_coords = this.renderer.toPaperCoords(_model_coords);
+ this.circle.position = this.paper_coords;
+ this.title.content = this.model.get("title");
+ this.title.position = this.paper_coords.add([0, Rkns.Renderer._NODE_RADIUS + 1.5 *Rkns.Renderer._NODE_FONT_SIZE]);
+ this.circle.strokeColor = this.model.get("created_by").get("color");
+ this.edit_button.moveTo(this.paper_coords);
+ this.remove_button.moveTo(this.paper_coords);
+ this.link_button.moveTo(this.paper_coords);
+ var _img = this.model.get("image");
+ if (_img && _img !== this.img) {
+ var _image = new Image(),
+ _this = this;
+ _image.onload = function() {
+ if (_this.node_image) {
+ _this.node_image.remove();
+ }
+ _this.renderer.node_layer.activate();
+ var _ratio = Math.min(1, 2 * Rkns.Renderer._NODE_RADIUS / _image.width, 2 * Rkns.Renderer._NODE_RADIUS / _image.height );
+ var _raster = new paper.Raster(_image);
+ var _clip = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS);
+ _raster.scale(_ratio);
+ _this.node_image = new paper.Group(_clip, _raster);
+ _this.node_image.opacity = .9;
+ /* This is a workaround to allow clipping at group level
+ * If opacity was set to 1, paper.js would merge all clipping groups in one (known bug).
+ */
+ _this.node_image.clipped = true;
+ _this.node_image.position = _this.paper_coords;
+ _this.node_image.__representation = _this;
+ _clip.__representation = _this;
+ paper.view.draw();
+ }
+ _image.src = _img;
+ }
+ this.img = _img;
+ if (this.node_image) {
+ if (!this.img) {
+ this.node_image.remove();
+ delete this.node_image;
+ } else {
+ this.node_image.position = this.paper_coords;
+ }
+ }
+
+ Rkns._.each(this.project.get("edges").filter(function (ed) { return ((ed.to === this.model) || (ed.from === this.model));}), function(edge, index, list){
+ var repr = this.renderer.getRepresentationByModel(edge);
+ if(repr != null && typeof repr.from_representation.paper_coords !== "undefined" && typeof repr.to_representation.paper_coords !== "undefined") {
+ repr.redraw();
+ }
+ }, this);
+}
+
+Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
+ var _coords = this.renderer.toModelCoords(this.paper_coords.add(_delta)),
+ _data = {
+ position: {
+ x: _coords.x,
+ y: _coords.y
+ }
+ };
+ this.model.set(_data);
+ //this.renderer.redraw();
+}
+
+Rkns.Renderer.Node.prototype.openEditor = function() {
+ this.renderer.removeRepresentationsOfType("editor");
+ var _editor = this.renderer.addRepresentation("NodeEditor",null);
+ _editor.node_representation = this;
+ _editor.draw();
+}
+
+Rkns.Renderer.Node.prototype.select = function() {
+ this.circle.strokeWidth = 3;
+ this.edit_button.show();
+ this.remove_button.show();
+ this.link_button.show();
+ var _uri = this.model.get("uri");
+ Rkns.$('.Rk-Bin-Item').each(function() {
+ var _el = Rkns.$(this);
+ if (_el.attr("data-uri") == _uri) {
+ _el.addClass("selected");
+ }
+ });
+}
+
+Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
+ if (!_newTarget || _newTarget.node_representation !== this) {
+ this.edit_button.hide();
+ this.remove_button.hide();
+ this.link_button.hide();
+ this.circle.strokeWidth = 1;
+ Rkns.$('.Rk-Bin-Item').removeClass("selected");
+ }
+}
+
+Rkns.Renderer.Node.prototype.highlight = function() {
+ this.circle.fillColor = "#ffff80";
+ if (this.node_image) {
+ this.node_image.opacity = .5;
+ }
+}
+
+Rkns.Renderer.Node.prototype.unhighlight = function(_newTarget) {
+ this.circle.fillColor = "#ffffff";
+ if (this.node_image) {
+ this.node_image.opacity = .9;
+ }
+}
+
+Rkns.Renderer.Node.prototype.mouseup = function(_event) {
+ if (!this.renderer.is_dragging) {
+ this.openEditor();
+ }
+ this.renderer.click_target = null;
+ this.renderer.is_dragging = false;
+}
+
+Rkns.Renderer.Node.prototype.destroy = function(_event) {
+ this.super("destroy");
+ this.edit_button.destroy();
+ this.remove_button.destroy();
+ this.link_button.destroy();
+ this.circle.remove();
+ this.title.remove();
+ if (this.node_image) {
+ this.node_image.remove();
+ }
+}
+
+/* */
+
+Rkns.Renderer.Edge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.Edge.prototype._init = function() {
+ this.renderer.edge_layer.activate();
+ this.type = "Edge";
+ this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
+ this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
+ this.bundle = this.renderer.addToBundles(this);
+ this.line = new paper.Path();
+ this.line.add([0,0],[0,0],[0,0]);
+ this.line.__representation = this;
+ this.arrow = new paper.Path();
+ this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
+ this.arrow.__representation = this;
+ this.text = new paper.PointText();
+ this.text.characterStyle = {
+ fontSize: Rkns.Renderer._EDGE_FONT_SIZE,
+ fillColor: 'black'
+ };
+ this.text.paragraphStyle.justification = 'center';
+ this.text_angle = 0;
+ this.arrow_angle = 0;
+ this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
+ this.edit_button.edge_representation = this;
+ this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
+ this.remove_button.edge_representation = this;
+}
+
+Rkns.Renderer.Edge.prototype.redraw = function() {
+ var _p0a = this.from_representation.paper_coords,
+ _p1a = this.to_representation.paper_coords,
+ _v = _p1a.subtract(_p0a),
+ _r = _v.length,
+ _u = _v.divide(_r),
+ _group_pos = this.bundle.getPosition(this),
+ _delta = new paper.Point([- _u.y, _u.x]).multiply( 12 * _group_pos ),
+ _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
+ _p1b = _p1a.add(_delta), /* to differentiate inbound and outbound links */
+ _a = _v.angle,
+ _handle = _v.divide(3),
+ _color = this.model.get("created_by").get("color");
+ this.paper_coords = _p0b.add(_p1b).divide(2);
+ this.line.strokeColor = _color;
+ this.line.segments[0].point = _p0a;
+ this.line.segments[1].point = this.paper_coords;
+ this.line.segments[1].handleIn = _handle.multiply(-1);
+ this.line.segments[1].handleOut = _handle;
+ this.line.segments[2].point = _p1a;
+ this.arrow.rotate(_a - this.arrow_angle);
+ this.arrow.fillColor = _color;
+ this.arrow.position = this.paper_coords.subtract(_u.multiply(4));
+ this.arrow_angle = _a;
+ if (_a > 90) {
+ _a -= 180;
+ }
+ if (_a < -90) {
+ _a += 180;
+ }
+ this.text.rotate(_a - this.text_angle);
+ this.text.content = this.model.get("title");
+ this.text.position = this.paper_coords;
+ this.text_angle = _a;
+ this.edit_button.moveTo(this.paper_coords);
+ this.remove_button.moveTo(this.paper_coords);
+}
+
+Rkns.Renderer.Edge.prototype.openEditor = function() {
+ this.renderer.removeRepresentationsOfType("editor");
+ var _editor = this.renderer.addRepresentation("EdgeEditor",null);
+ _editor.edge_representation = this;
+ _editor.draw();
+}
+
+Rkns.Renderer.Edge.prototype.select = function() {
+ this.line.strokeWidth = 3;
+ this.edit_button.show();
+ this.remove_button.show();
+}
+
+Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
+ if (!_newTarget || _newTarget.edge_representation !== this) {
+ this.edit_button.hide();
+ this.remove_button.hide();
+ this.line.strokeWidth = 1;
+ }
+}
+
+Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
+ if (!this.renderer.is_dragging) {
+ this.openEditor();
+ }
+ this.renderer.click_target = null;
+ this.renderer.is_dragging = false;
+}
+
+Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
+ this.from_representation.paperShift(_delta);
+ this.to_representation.paperShift(_delta);
+ this.renderer.redraw();
+}
+
+Rkns.Renderer.Edge.prototype.destroy = function() {
+ this.super("destroy");
+ this.line.remove();
+ this.arrow.remove();
+ this.text.remove();
+ this.edit_button.destroy();
+ this.remove_button.destroy();
+ var _this = this;
+ this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
+ return _edge === _this;
+ });
+}
+
+/* */
+
+Rkns.Renderer.TempEdge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.TempEdge.prototype._init = function() {
+ this.renderer.edge_layer.activate();
+ this.type = "temp-edge";
+
+ var _color = this.project.get("users").get(this.renderer.renkan.current_user).get("color");
+ this.line = new paper.Path();
+ this.line.strokeColor = _color;
+ this.line.add([0,0],[0,0]);
+ this.line.__representation = this;
+ this.arrow = new paper.Path();
+ this.arrow.fillColor = _color;
+ this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
+ this.arrow.__representation = this;
+ this.arrow_angle = 0;
+}
+
+Rkns.Renderer.TempEdge.prototype.redraw = function() {
+ var _p0 = this.from_representation.paper_coords,
+ _p1 = this.end_pos,
+ _a = _p1.subtract(_p0).angle,
+ _c = _p0.add(_p1).divide(2);
+ this.line.segments[0].point = _p0;
+ this.line.segments[1].point = _p1;
+ this.arrow.rotate(_a - this.arrow_angle);
+ this.arrow.position = _c;
+ this.arrow_angle = _a;
+}
+
+Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) {
+ this.end_pos = this.end_pos.add(_delta);
+ var _hitResult = paper.project.hitTest(this.end_pos);
+ this.renderer.findTarget(_hitResult);
+ this.redraw();
+}
+
+Rkns.Renderer.TempEdge.prototype.mouseup = function(_event) {
+ var _hitResult = paper.project.hitTest(_event.point),
+ _model = this.from_representation.model,
+ _endDrag = true;
+ if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
+ var _target = _hitResult.item.__representation;
+ if (_target.type === "Node" && _model !== _target.model) {
+ var _data = {
+ id: Rkns.Utils.getUID('edge'),
+ created_by: this.renderer.renkan.current_user,
+ from: _model.get("_id"),
+ to: _target.model.get("_id")
+ };
+ this.project.addEdge(_data);
+ }
+ if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) {
+ _endDrag = false;
+ this.renderer.is_dragging = true;
+ }
+ }
+ if (_endDrag) {
+ this.renderer.click_target = null;
+ this.renderer.is_dragging = false;
+ this.renderer.removeRepresentation(this);
+ paper.view.draw();
+ }
+}
+
+Rkns.Renderer.TempEdge.prototype.destroy = function() {
+ this.arrow.remove();
+ this.line.remove();
+}
+
+/* */
+
+Rkns.Renderer.NodeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.NodeEditor.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "editor";
+ this.editor_block = new paper.Path();
+ var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
+ this.editor_block.add.apply(this.editor_block, _pts);
+ this.editor_block.strokeWidth = 2;
+ this.editor_block.strokeColor = "#999999";
+ this.editor_block.fillColor = "#e0e0e0";
+ this.editor_block.opacity = .8;
+ this.editor_$ = Rkns.$('<div>')
+ .appendTo(this.renderer.editor_$)
+ .css({
+ position: "absolute",
+ opacity: .8
+ })
+ .hide();
+}
+
+Rkns.Renderer.NodeEditor.prototype.template = Rkns._.template(
+ '<h2><span class="Rk-CloseX">×</span><%=l10n.edit_node%></span></h2>'
+ + '<p><label><%=l10n.edit_title%></label><input class="Rk-Edit-Title" type="text" value="<%=node.title%>"/></p>'
+ + '<p><label><%=l10n.edit_uri%></label><input class="Rk-Edit-URI" type="text" value="<%=node.uri%>"/><a class="Rk-Edit-Goto" href="<%=node.uri%>" target="_blank"></a></p>'
+ + '<p><label><%=l10n.edit_description%></label><textarea class="Rk-Edit-Description"><%=node.description%></textarea></p>'
+ + '<p><label><%=l10n.edit_image%></label><input class="Rk-Edit-Image" type="text" value="<%=node.image%>"/><img class="Rk-Edit-ImgPreview" src="<%=node.image%>" /></p>'
+ + '<p><label><%=l10n.created_by%></label> <span class="Rk-UserColor" style="background:<%=node.created_by_color%>;"></span><%=node.created_by_title%></p>'
+);
+
+Rkns.Renderer.NodeEditor.prototype.draw = function() {
+ var _model = this.node_representation.model;
+ this.editor_$
+ .html(this.template({
+ node: {
+ title: _model.get("title"),
+ uri: _model.get("uri"),
+ description: _model.get("description"),
+ image: _model.get("image") || "",
+ created_by_color: _model.get("created_by").get("color"),
+ created_by_title: _model.get("created_by").get("title")
+ },
+ l10n: this.renderer.renkan.l10n
+ }));
+ this.redraw();
+ var _this = this;
+ this.editor_$.find(".Rk-CloseX").click(function() {
+ _this.renderer.removeRepresentation(_this);
+ paper.view.draw();
+ });
+ this.editor_$.find("input, textarea").bind("keyup change", function() {
+ var _uri = _this.editor_$.find(".Rk-Edit-URI").val(),
+ _image = _this.editor_$.find(".Rk-Edit-Image").val();
+ _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image);
+ _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri);
+ var _data = {
+ title: _this.editor_$.find(".Rk-Edit-Title").val(),
+ description: _this.editor_$.find(".Rk-Edit-Description").val(),
+ uri: _uri,
+ image: _image
+ }
+ _model.set(_data);
+ _this.redraw();
+ });
+ this.editor_$.find("img").load(function() {
+ _this.redraw();
+ })
+ this.editor_$.find(".Rk-Edit-Title")[0].focus();
+}
+
+Rkns.Renderer.NodeEditor.prototype.redraw = function() {
+ var _coords = this.node_representation.paper_coords;
+ Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 20, this.editor_$);
+ this.editor_$.show();
+ paper.view.draw();
+}
+
+Rkns.Renderer.NodeEditor.prototype.destroy = function() {
+ this.editor_block.remove();
+ this.editor_$.detach();
+}
+
+/* */
+
+Rkns.Renderer.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.EdgeEditor.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "editor";
+ this.editor_block = new paper.Path();
+ var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
+ this.editor_block.add.apply(this.editor_block, _pts);
+ this.editor_block.strokeWidth = 2;
+ this.editor_block.strokeColor = "#999999";
+ this.editor_block.fillColor = "#e0e0e0";
+ this.editor_block.opacity = .8;
+ this.editor_$ = Rkns.$('<div>')
+ .appendTo(this.renderer.editor_$)
+ .css({
+ position: "absolute",
+ opacity: .8
+ })
+ .hide();
+}
+
+Rkns.Renderer.EdgeEditor.prototype.template = Rkns._.template(
+ '<h2><span class="Rk-CloseX">×</span><%=l10n.edit_edge%></span></h2>'
+ + '<p><label><%=l10n.edit_title%></label><input class="Rk-Edit-Title" type="text" value="<%=edge.title%>"/></p>'
+ + '<p><label><%=l10n.edit_uri%></label><input class="Rk-Edit-URI" type="text" value="<%=edge.uri%>"/><a class="Rk-Edit-Goto" href="<%=edge.uri%>" target="_blank"></a></p>'
+ + '<p><label><%=l10n.edit_from%></label><span class="Rk-UserColor" style="background:<%=edge.from_created_by_color%>;"></span><%=edge.from_title%></p>'
+ + '<p><label><%=l10n.edit_to%></label><span class="Rk-UserColor" style="background:<%=edge.to_created_by_color%>;"></span><%=edge.to_title%></p>'
+ + '<p><label><%=l10n.created_by%> </label><span class="Rk-UserColor" style="background:<%=edge.created_by_color%>;"></span><%=edge.created_by_title%></p>'
+);
+
+Rkns.Renderer.EdgeEditor.prototype.draw = function() {
+ var _model = this.edge_representation.model;
+ this.editor_$
+ .html(this.template({
+ edge: {
+ title: _model.get("title"),
+ uri: _model.get("uri"),
+ description: _model.get("description"),
+ from_title: _model.get("from").get("title"),
+ to_title: _model.get("to").get("title"),
+ from_created_by_color: _model.get("from").get("created_by").get("color"),
+ to_created_by_color: _model.get("to").get("created_by").get("color"),
+ created_by_color: _model.get("created_by").get("color"),
+ created_by_title: _model.get("created_by").get("title")
+ },
+ l10n: this.renderer.renkan.l10n
+ }));
+ this.redraw();
+ var _this = this;
+ this.editor_$.find(".Rk-CloseX").click(function() {
+ _this.renderer.removeRepresentation(_this);
+ paper.view.draw();
+ });
+ this.editor_$.find("input, textarea").bind("keyup change", function() {
+ _this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val());
+ var _data = {
+ title: _this.editor_$.find(".Rk-Edit-Title").val(),
+ uri: _this.editor_$.find(".Rk-Edit-URI").val()
+ }
+ _model.set(_data);
+ _this.redraw();
+ });
+}
+Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
+ var _coords = this.edge_representation.paper_coords;
+ Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 5, this.editor_$);
+ this.editor_$.show();
+ paper.view.draw();
+}
+
+Rkns.Renderer.EdgeEditor.prototype.destroy = function() {
+ this.editor_block.remove();
+ this.editor_$.detach();
+}
+
+/* */
+
+Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.NodeEditButton.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "Node-edit-button";
+ this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, - 90, 30, 1, this.renderer.renkan.static_url+'img/edit.png', this.renderer.renkan.l10n.caption_edit);
+}
+
+Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
+ this.sector.moveTo(_pos);
+}
+
+Rkns.Renderer.NodeEditButton.prototype.show = function() {
+ this.sector.show();
+}
+
+Rkns.Renderer.NodeEditButton.prototype.hide = function() {
+ this.sector.hide();
+}
+
+Rkns.Renderer.NodeEditButton.prototype.select = function() {
+ this.sector.select();
+}
+
+Rkns.Renderer.NodeEditButton.prototype.unselect = function(_newTarget) {
+ this.sector.unselect();
+ if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) {
+ this.node_representation.unselect();
+ }
+}
+
+Rkns.Renderer.NodeEditButton.prototype.mouseup = function() {
+ if (!this.renderer.is_dragging) {
+ this.node_representation.openEditor();
+ }
+}
+
+Rkns.Renderer.NodeEditButton.prototype.destroy = function() {
+ this.sector.destroy();
+}
+
+/* */
+
+Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "Node-remove-button";
+ this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, -210, -90, 1, this.renderer.renkan.static_url+'img/remove.png', this.renderer.renkan.l10n.caption_remove);
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
+ this.sector.moveTo(_pos);
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.show = function() {
+ this.sector.show();
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.hide = function() {
+ this.sector.hide();
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.select = function() {
+ this.sector.select();
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.unselect = function(_newTarget) {
+ this.sector.unselect();
+ if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) {
+ this.node_representation.unselect();
+ }
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
+ this.renderer.removeRepresentationsOfType("editor");
+ if (confirm('Do you really wish to remove node "' + this.node_representation.model.get("title") + '"?')) {
+ this.project.removeNode(this.node_representation.model);
+ }
+}
+
+Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() {
+ this.sector.destroy();
+}
+
+/* */
+
+Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.NodeLinkButton.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "Node-link-button";
+ this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, 30, 150, 1, this.renderer.renkan.static_url+'img/link.png', this.renderer.renkan.l10n.caption_link);
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
+ this.sector.moveTo(_pos);
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.show = function() {
+ this.sector.show();
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.hide = function() {
+ this.sector.hide();
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.select = function() {
+ this.sector.select();
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.unselect = function(_newTarget) {
+ this.sector.unselect();
+ if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) {
+ this.node_representation.unselect();
+ }
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.destroy = function() {
+ this.sector.destroy();
+}
+
+/* */
+
+Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.EdgeEditButton.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "Edge-edit-button";
+ this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 90, 90, 1, this.renderer.renkan.static_url+'img/edit.png', this.renderer.renkan.l10n.caption_edit);
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
+ this.sector.moveTo(_pos);
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.show = function() {
+ this.sector.show();
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.hide = function() {
+ this.sector.hide();
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.select = function() {
+ this.sector.select();
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.unselect = function(_newTarget) {
+ this.sector.unselect();
+ if (!_newTarget || (_newTarget !== this.edge_representation && _newTarget.edge_representation !== this.edge_representation)) {
+ this.edge_representation.unselect();
+ }
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.mouseup = function() {
+ if (!this.renderer.is_dragging) {
+ this.edge_representation.openEditor();
+ }
+}
+
+Rkns.Renderer.EdgeEditButton.prototype.destroy = function() {
+ this.sector.destroy();
+}
+
+/* */
+
+Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "Edge-remove-button";
+ this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 270, -90, 1, this.renderer.renkan.static_url+'img/remove.png', this.renderer.renkan.l10n.caption_remove);
+}
+Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
+ this.sector.moveTo(_pos);
+}
+
+Rkns.Renderer.EdgeRemoveButton.prototype.show = function() {
+ this.sector.show();
+}
+
+Rkns.Renderer.EdgeRemoveButton.prototype.hide = function() {
+ this.sector.hide();
+}
+
+Rkns.Renderer.EdgeRemoveButton.prototype.select = function() {
+ this.sector.select();
+}
+
+Rkns.Renderer.EdgeRemoveButton.prototype.unselect = function(_newTarget) {
+ this.sector.unselect();
+ if (!_newTarget || (_newTarget !== this.edge_representation && _newTarget.edge_representation !== this.edge_representation)) {
+ this.edge_representation.unselect();
+ }
+}
+
+Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
+ this.renderer.removeRepresentationsOfType("editor");
+ if (confirm('Do you really wish to remove edge "' + this.edge_representation.model.get("title") + '"?')) {
+ this.project.removeEdge(this.edge_representation.model);
+ }
+}
+
+Rkns.Renderer.EdgeRemoveButton.prototype.destroy = function() {
+ this.sector.destroy();
+}
+
+/* */
+
+Rkns.Renderer.Scene = function(_renkan) {
+ this.renkan = _renkan;
+ this.$ = Rkns.$(".Rk-Render");
+ this.representations = [];
+ this.$.html(this.template({
+ l10n: _renkan.l10n
+ }))
+ this.canvas_$ = this.$.find(".Rk-Canvas");
+ this.editor_$ = this.$.find(".Rk-Editor");
+ this.notif_$ = this.$.find(".Rk-Notifications");
+ paper.setup(this.canvas_$[0]);
+ this.scale = 1;
+ this.offset = paper.view.center;
+ this.totalScroll = 0;
+ this.click_target = null;
+ this.selected_target = null;
+ this.edge_layer = new paper.Layer();
+ this.node_layer = new paper.Layer();
+ this.overlay_layer = new paper.Layer();
+ this.bundles = [];
+ this.click_mode = false;
+ var _tool = new paper.Tool(),
+ _this = this;
+ _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
+ _tool.onMouseMove = function(_event) {
+ _this.onMouseMove(_event);
+ }
+ _tool.onMouseDown = function(_event) {
+ _this.onMouseDown(_event);
+ }
+ _tool.onMouseDrag = function(_event) {
+ _this.onMouseDrag(_event);
+ }
+ this.canvas_$.mouseup(function(_event) {
+ _this.onMouseUp(_event);
+ });
+ this.canvas_$.mousewheel(function(_event, _delta) {
+ _this.onScroll(_event, _delta);
+ });
+ this.canvas_$.dblclick(function(_event) {
+ _this.onDoubleClick(_event);
+ });
+ this.canvas_$.mouseenter(function(_event) {
+ _this.onMouseEnter(_event);
+ });
+ this.editor_$.find(".Rk-ZoomOut").click(function() {
+ _this.offset = new paper.Point([
+ _this.canvas_$.width(),
+ _this.canvas_$.height()
+ ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
+ _this.setScale( _this.scale * Math.SQRT1_2 );
+ _this.redraw();
+ });
+ this.editor_$.find(".Rk-ZoomIn").click(function() {
+ _this.offset = new paper.Point([
+ _this.canvas_$.width(),
+ _this.canvas_$.height()
+ ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
+ _this.setScale( _this.scale * Math.SQRT2 );
+ _this.redraw();
+ });
+ this.$.find(".Rk-CurrentUser").mouseenter(
+ function() { _this.$.find(".Rk-UserList").slideDown() }
+ );
+ this.$.find(".Rk-Users").mouseleave(
+ function() { _this.$.find(".Rk-UserList").slideUp(); }
+ );
+ this.$.find(".Rk-FullScreen-Button").click(function() {
+ var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,
+ _el = _this.renkan.$[0],
+ _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],
+ _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"];
+ if (_isFull) {
+ for (var i = 0; i < _cancelMethods.length; i++) {
+ if (typeof document[_cancelMethods[i]] === "function") {
+ document[_cancelMethods[i]]();
+ break;
+ }
+ }
+ } else {
+ for (var i = 0; i < _requestMethods.length; i++) {
+ if (typeof _el[_requestMethods[i]] === "function") {
+ _el[_requestMethods[i]]();
+ break;
+ }
+ }
+ }
+ });
+ this.$.find(".Rk-AddNode-Button").click(function() {
+ if (_this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
+ _this.click_mode = false;
+ _this.notif_$.hide();
+ } else {
+ _this.click_mode = Rkns.Renderer._CLICKMODE_ADDNODE;
+ _this.notif_$.html(_renkan.l10n.notif_add_node).fadeIn();
+ }
+ });
+ this.$.find(".Rk-AddEdge-Button").click(function() {
+ if (_this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE || _this.click_mode === Rkns.Renderer._CLICKMODE_ENDEDGE) {
+ _this.click_mode = false;
+ _this.notif_$.hide();
+ } else {
+ _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE;
+ _this.notif_$.html(_renkan.l10n.notif_start_edge).fadeIn();
+ }
+ });
+ this.$.find(".Rk-TopBar-Button").mouseover(function() {
+ Rkns.$(this).find(".Rk-TopBar-Tooltip").show();
+ }).mouseout(function() {
+ Rkns.$(this).find(".Rk-TopBar-Tooltip").hide();
+ });
+
+ paper.view.onResize = function(_event) {
+ _this.offset = _this.offset.add(_event.delta.divide(2));
+ _this.redraw();
+ }
+
+ var _thRedraw = Rkns._.throttle(function() {
+ _this.redraw();
+ },50);
+
+ this.addRepresentations("Node", this.renkan.project.get("nodes"));
+ this.addRepresentations("Edge", this.renkan.project.get("edges"));
+ this.renkan.project.get("users").each(function(_user) {
+ _this.addUser(_user);
+ })
+
+ this.renkan.project.on("add:users", function(_user) {
+ _this.addUser(_user);
+ });
+ this.renkan.project.on("add:nodes", function(_node) {
+ _this.addRepresentation("Node", _node);
+ _thRedraw();
+ });
+ this.renkan.project.on("add:edges", function(_edge) {
+ _this.addRepresentation("Edge", _edge);
+ _thRedraw();
+ });
+
+ this.redraw();
+}
+
+Rkns.Renderer.Scene.prototype.template = Rkns._.template(
+ '<div class="Rk-TopBar"><h3 class="Rk-PadTitle"><%=l10n.untitled_project%></h3>'
+ + '<div class="Rk-Users"><div class="Rk-CurrentUser"><span class="Rk-CurrentUser-Color"></span><span class="Rk-CurrentUser-Name"><unknown user></span></div><ul class="Rk-UserList"></ul></div>'
+ + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%=l10n.full_screen%></div></div></div>'
+ + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%=l10n.add_node%></div></div></div>'
+ + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%=l10n.add_edge%></div></div></div>'
+ + '<div class="Rk-TopBar-Separator"></div></div>'
+ + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
+ + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
+ + '</div>'
+);
+
+Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
+ var _bundle = Rkns._(this.bundles).find(function(_bundle) {
+ return (
+ ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation )
+ || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )
+ );
+ });
+ if (typeof _bundle !== "undefined") {
+ _bundle.edges.push(_edgeRepr)
+ } else {
+ _bundle = {
+ from: _edgeRepr.from_representation,
+ to: _edgeRepr.to_representation,
+ edges: [ _edgeRepr ],
+ getPosition: function(_er) {
+ var _dir = (_er.from_representation === this.from) ? 1 : -1;
+ return _dir * ( Rkns._(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 );
+ }
+ }
+ this.bundles.push(_bundle);
+ }
+ return _bundle;
+}
+
+Rkns.Renderer.Scene.prototype.setScale = function(_newScale) {
+ this.scale = _newScale;
+ this.redraw();
+}
+
+Rkns.Renderer.Scene.prototype.autoScale = function() {
+ var nodes = this.renkan.project.get("nodes")
+ if (nodes.length > 1) {
+ var _xx = nodes.map(function(_node) { return _node.get("position").x }),
+ _yy = nodes.map(function(_node) { return _node.get("position").y }),
+ _minx = Math.min.apply(Math, _xx),
+ _miny = Math.min.apply(Math, _yy),
+ _maxx = Math.max.apply(Math, _xx),
+ _maxy = Math.max.apply(Math, _yy);
+ var _scale = Math.min((paper.view.size.width - 2 * Rkns.Renderer._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._MARGIN_Y) / (_maxy - _miny));
+ this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));
+ this.setScale(_scale);
+ }
+ if (nodes.length === 1) {
+ this.offset = paper.view.center.subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]));
+ this.setScale(1);
+ }
+}
+
+Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) {
+ return _point.multiply(this.scale).add(this.offset);
+}
+
+
+Rkns.Renderer.Scene.prototype.toModelCoords = function(_point) {
+ return _point.subtract(this.offset).divide(this.scale);
+}
+
+Rkns.Renderer.Scene.prototype.addRepresentation = function(_type, _model) {
+ var _repr = new Rkns.Renderer[_type](this, _model);
+ this.representations.push(_repr);
+ return _repr;
+}
+
+Rkns.Renderer.Scene.prototype.addRepresentations = function(_type, _collection) {
+ var _this = this;
+ _collection.forEach(function(_model) {
+ _this.addRepresentation(_type, _model);
+ });
+}
+
+Rkns.Renderer.Scene.prototype.userTemplate = Rkns._.template(
+ '<li class="Rk-User"><span class="Rk-UserColor" style="background:<%=background%>;"></span><%=name%></li>'
+);
+
+Rkns.Renderer.Scene.prototype.addUser = function(_user) {
+ if (_user.get("_id") === this.renkan.current_user) {
+ this.$.find(".Rk-CurrentUser-Name").text(_user.get("title"));
+ this.$.find(".Rk-CurrentUser-Color").css("background", _user.get("color"));
+ } else {
+ this.$.find(".Rk-UserList").append(
+ Rkns.$(
+ this.userTemplate({
+ name: _user.get("title"),
+ background: _user.get("color")
+ })
+ )
+ );
+ }
+}
+
+Rkns.Renderer.Scene.prototype.removeRepresentation = function(_representation) {
+ _representation.destroy();
+ this.representations = Rkns._(this.representations).reject(
+ function(_repr) {
+ return _repr == _representation
+ }
+ );
+}
+
+Rkns.Renderer.Scene.prototype.getRepresentationByModel = function(_model) {
+ return Rkns._(this.representations).find(function(_repr) {
+ return _repr.model === _model;
+ });
+}
+
+Rkns.Renderer.Scene.prototype.removeRepresentationsOfType = function(_type) {
+ var _representations = Rkns._(this.representations).filter(function(_repr) {
+ return _repr.type == _type;
+ }),
+ _this = this;
+ Rkns._(_representations).each(function(_repr) {
+ _this.removeRepresentation(_repr);
+ });
+}
+
+Rkns.Renderer.Scene.prototype.highlightModel = function(_model) {
+ var _repr = this.getRepresentationByModel(_model);
+ if (_repr) {
+ _repr.highlight();
+ }
+}
+
+Rkns.Renderer.Scene.prototype.unhighlightAll = function(_model) {
+ Rkns._(this.representations).each(function(_repr) {
+ _repr.unhighlight();
+ });
+}
+
+Rkns.Renderer.Scene.prototype.redraw = function() {
+ Rkns._(this.representations).each(function(_representation) {
+ _representation.redraw();
+ });
+ paper.view.draw();
+}
+
+Rkns.Renderer.Scene.prototype.addTempEdge = function(_from, _point) {
+ var _tmpEdge = this.addRepresentation("TempEdge",null);
+ _tmpEdge.end_pos = _point;
+ _tmpEdge.from_representation = _from;
+ _tmpEdge.redraw();
+ this.click_target = _tmpEdge;
+}
+
+Rkns.Renderer.Scene.prototype.findTarget = function(_hitResult) {
+ if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
+ var _newTarget = _hitResult.item.__representation;
+ if (this.selected_target !== _hitResult.item.__representation) {
+ if (this.selected_target) {
+ this.selected_target.unselect(_newTarget);
+ }
+ _newTarget.select(this.selected_target);
+ this.selected_target = _newTarget;
+ }
+ } else {
+ if (this.selected_target) {
+ this.selected_target.unselect(null);
+ }
+ this.selected_target = null;
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) {
+ var _hitResult = paper.project.hitTest(_event.point);
+ if (this.is_dragging) {
+ if (this.click_target && typeof this.click_target.paperShift === "function") {
+ this.click_target.paperShift(_event.delta);
+ } else {
+ this.offset = this.offset.add(_event.delta);
+ this.redraw();
+ }
+ } else {
+ this.findTarget(_hitResult);
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
+ if (!this.click_target || this.click_target.type !== "temp-edge") {
+ this.is_dragging = false;
+ var _hitResult = paper.project.hitTest(_event.point);
+ if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
+ this.click_target = _hitResult.item.__representation;
+ if (this.click_target.type === "Node-link-button") {
+ this.removeRepresentationsOfType("editor");
+ this.addTempEdge(this.click_target.node_representation, _event.point);
+ }
+ } else {
+ this.click_target = null;
+ if (this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
+ var _coords = this.toModelCoords(_event.point),
+ _data = {
+ id: Rkns.Utils.getUID('node'),
+ created_by: this.renkan.current_user,
+ position: {
+ x: _coords.x,
+ y: _coords.y
+ }
+ };
+ _node = this.renkan.project.addNode(_data);
+ this.getRepresentationByModel(_node).openEditor();
+ }
+ }
+ }
+ if (this.click_mode) {
+ if (this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") {
+ this.removeRepresentationsOfType("editor");
+ this.addTempEdge(this.click_target, _event.point);
+ this.click_mode = Rkns.Renderer._CLICKMODE_ENDEDGE;
+ this.notif_$.fadeOut(function() {
+ Rkns.$(this).html(_renkan.l10n.notif_end_edge).fadeIn();
+ });
+ } else {
+ this.notif_$.hide();
+ this.click_mode = false;
+ }
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) {
+ this.is_dragging = true;
+ this.onMouseMove(_event);
+}
+
+Rkns.Renderer.Scene.prototype.onMouseUp = function(_event) {
+ if (this.click_target) {
+ var _off = this.canvas_$.offset();
+ this.click_target.mouseup(
+ {
+ point: new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ])
+ }
+ );
+ } else {
+ this.click_target = null;
+ this.is_dragging = false;
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
+ this.totalScroll += _scrolldelta;
+ if (Math.abs(this.totalScroll) >= 1) {
+ var _off = this.canvas_$.offset(),
+ _delta = new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
+ if (this.totalScroll > 0) {
+ this.offset = this.offset.subtract(_delta);
+ this.setScale( this.scale * Math.SQRT2 );
+ } else {
+ this.offset = this.offset.add(_delta.divide( Math.SQRT2 ));
+ this.setScale( this.scale * Math.SQRT1_2);
+ }
+ this.totalScroll = 0;
+ this.redraw();
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onDoubleClick = function(_event) {
+ var _off = this.canvas_$.offset(),
+ _point = new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ]);
+ var _hitResult = paper.project.hitTest(_point);
+ if (!_hitResult || typeof _hitResult.item.__representation === "undefined") {
+ var _coords = this.toModelCoords(_point),
+ _data = {
+ id: Rkns.Utils.getUID('node'),
+ created_by: this.renkan.current_user,
+ position: {
+ x: _coords.x,
+ y: _coords.y
+ }
+ };
+ _node = this.renkan.project.addNode(_data);
+ this.getRepresentationByModel(_node).openEditor();
+ }
+ paper.view.draw();
+}
+
+Rkns.Renderer.Scene.prototype.onMouseEnter = function(_event) {
+ var _newEl = this.renkan.selected_bin_item;
+ if (_newEl) {
+ var _off = this.canvas_$.offset(),
+ _point = new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ]),
+ _coords = this.toModelCoords(_point),
+ _data = {
+ id: Rkns.Utils.getUID('node'),
+ created_by: this.renkan.current_user,
+ uri: _newEl.uri,
+ title: _newEl.title,
+ description: _newEl.description,
+ image: _newEl.image,
+ position: {
+ x: _coords.x,
+ y: _coords.y
+ }
+ };
+ var _node = this.renkan.project.addNode(_data);
+ this.renkan.selected_bin_item = null;
+ this.is_dragging = true;
+ this.click_target = this.getRepresentationByModel(_node);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/random-data.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,42 @@
+Rkns.randomData = function(_renkan, _opts) {
+ _opts = _opts || {};
+ _opts.user_count = _opts.user_count || 5;
+ _opts.node_count = _opts.node_count || 20;
+ _opts.edge_count = _opts.edge_count || 2 * _opts.node_count;
+ _opts.user_colors = _opts.user_colors || ["#ff0000", "#008000", "#0000ff", "#808000", "#808080", "#c000c0", "#00c0c0"];
+ var _proj = _renkan.project
+ for (var i = 0; i < _opts.user_count; i++) {
+ _proj.addUser({
+ id: "user-"+i,
+ title: "User #"+(1+i),
+ color: _opts.user_colors[i]
+ });
+ }
+ for (var i = 0; i < _opts.node_count; i++) {
+ _proj.addNode({
+ id: "node-"+i,
+ title: "Node #"+(1+i),
+ created_by: "user-" + Math.floor(_opts.user_count*Math.random()),
+ position: {
+ x: 300 * Math.cos(2 * Math.PI * i / _opts.node_count),
+ y: 300 * Math.sin(2 * Math.PI * i / _opts.node_count)
+ }
+ });
+ }
+ for (var i = 0; i < _opts.node_count; i++) {
+ var _from, _to;
+ _from = _to = Math.floor(_opts.node_count*Math.random());
+ while(_from === _to) {
+ _to = Math.floor(_opts.node_count*Math.random());
+ }
+ _proj.addEdge({
+ id: "edge-"+i,
+ title: "Edge #"+(1+i),
+ created_by: "user-" + Math.floor(_opts.user_count*Math.random()),
+ from: "node-" + _from,
+ to: "node-" + _to
+ });
+ }
+ _renkan.current_user = "user-0";
+ _renkan.renderer.autoScale();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/renkan-publish.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,1079 @@
+/*
+ * Copyright 2012 Institut de recherche et d'innovation
+ * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron
+ *
+ * contact@iri.centrepompidou.fr
+ * http://www.iri.centrepompidou.fr
+ *
+ * This software is a computer program whose purpose is to show and add annotations on a video .
+ * This software is governed by the CeCILL-C license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL-C
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+*/
+
+if (typeof Rkns !== "object") {
+ Rkns = {}
+}
+
+Rkns.$ = jQuery;
+
+Rkns._ = _;
+
+Rkns.i18n = {
+ en: {
+ zoom_in: "Zoom In",
+ zoom_out: "Zoom Out",
+ see_in_project: 'See also <b>"{node}"</b> in <b>"{project}"</b>'
+ }
+}
+
+Rkns.Utils = {
+ inherit : function(_baseClass) {
+ var _class = function() {
+ _baseClass.apply(this, Array.prototype.slice.call(arguments, 0));
+ if (typeof this._init == "function") {
+ this._init.apply(this, Array.prototype.slice.call(arguments, 0));
+ }
+ }
+ _class.prototype = new _baseClass();
+ return _class;
+ }
+}
+
+Rkns.Models = {};
+
+Rkns.Models.getUID = function(obj) {
+ var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ });
+ return obj.type + "-" + guid;
+};
+
+Rkns.Models.RenkanModel = Backbone.RelationalModel.extend({
+ idAttribute : "_id",
+ constructor: function(options) {
+
+ if (typeof options !== "undefined") {
+ options._id = options._id || options.id || Rkns.Models.getUID(this);
+ options.title = options.title || "(untitled " + this.type + ")";
+ options.description = options.description || "";
+ options.uri = options.uri || "";
+
+ if(typeof this.prepare === "function") {
+ options = this.prepare(options);
+ }
+ }
+ Backbone.RelationalModel.prototype.constructor.call(this, options);
+ },
+ validate: function() {
+ if(!this.type) {
+ return "object has no type";
+ }
+ },
+ addReference : function(_options, _propName, _list, _id, _default) {
+ var _element = _list.get(_id);
+ if (typeof _element === "undefined" && typeof _default !== "undefined") {
+ _options[_propName ] = _default;
+ }
+ else {
+ _options[_propName ] = _element;
+ }
+ }
+});
+
+// USER
+Rkns.Models.User = Rkns.Models.RenkanModel.extend({
+ type: "user",
+ prepare: function(options) {
+ options.color = options.color || "#666666";
+ return options;
+ },
+ toJSON: function() {
+ return {
+ id: this.get("_id"),
+ title: this.get("title"),
+ uri: this.get("uri"),
+ description: this.get("description"),
+ color: this.get("color"),
+ }
+ },
+});
+
+// NODE
+Rkns.Models.Node = Rkns.Models.RenkanModel.extend({
+ type: "node",
+ relations: [{
+ type: Backbone.HasOne,
+ key: "created_by",
+ relatedModel: Rkns.Models.User
+ }],
+ prepare: function(options) {
+ project = options.project;
+ this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
+ options.description = options.description || "";
+ return options;
+ },
+ toJSON: function() {
+ return {
+ id: this.get("_id"),
+ title: this.get("title"),
+ uri: this.get("uri"),
+ description: this.get("description"),
+ position: this.get("position"),
+ image: this.get("image"),
+ created_by: this.get("created_by").get("_id")
+ }
+ },
+});
+
+// EDGE
+Rkns.Models.Edge = Rkns.Models.RenkanModel.extend({
+ type: "edge",
+ relations: [
+ {
+ type: Backbone.HasOne,
+ key: "created_by",
+ relatedModel: Rkns.Models.User
+ },
+ {
+ type: Backbone.HasOne,
+ key: "from",
+ relatedModel: Rkns.Models.Node
+ },
+ {
+ type: Backbone.HasOne,
+ key: "to",
+ relatedModel: Rkns.Models.Node
+ },
+ ],
+ prepare: function(options) {
+ project = options.project;
+ this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user);
+ this.addReference(options, "from", project.get("nodes"), options.from);
+ this.addReference(options, "to", project.get("nodes"), options.to);
+ return options;
+ },
+ toJSON: function() {
+ return {
+ id: this.get("_id"),
+ title: this.get("title"),
+ uri: this.get("uri"),
+ description: this.get("description"),
+ from: this.get("from").get("_id"),
+ to: this.get("to").get("_id"),
+ created_by: this.get("created_by").get("_id"),
+ }
+ },
+});
+
+// PROJECT
+Rkns.Models.Project = Rkns.Models.RenkanModel.extend({
+ type: "project",
+ relations: [
+ {
+ type: Backbone.HasMany,
+ key: "users",
+ relatedModel: Rkns.Models.User,
+ reverseRelation: {
+ key: 'project',
+ includeInJSON: '_id'
+ },
+ },
+ {
+ type: Backbone.HasMany,
+ key: "nodes",
+ relatedModel: Rkns.Models.Node,
+ reverseRelation: {
+ key: 'project',
+ includeInJSON: '_id'
+ },
+ },
+ {
+ type: Backbone.HasMany,
+ key: "edges",
+ relatedModel: Rkns.Models.Edge,
+ reverseRelation: {
+ key: 'project',
+ includeInJSON: '_id'
+ },
+ }
+ ],
+ addUser: function(_props) {
+ _props.project = this;
+ var _user = new Rkns.Models.User(_props);
+ this.get("users").push(_user);
+ return _user;
+ },
+ addNode: function(_props) {
+ _props.project = this;
+ var _node = new Rkns.Models.Node(_props);
+ this.get("nodes").push(_node);
+ return _node;
+ },
+ addEdge: function(_props) {
+ _props.project = this;
+ var _edge = new Rkns.Models.Edge(_props);
+ this.get("edges").push(_edge);
+ return _edge;
+ },
+ removeNode: function(_model) {
+ this.get("nodes").remove(_model);
+ },
+ removeEdge: function(_model) {
+ this.get("edges").remove(_model);
+ },
+ validate: function(options) {
+ var _project = this;
+ Rkns._(options.users).each(function(_item) {
+ _item.project = _project;
+ });
+ Rkns._(options.nodes).each(function(_item) {
+ _item.project = _project;
+ });
+ Rkns._(options.edges).each(function(_item) {
+ _item.project = _project;
+ });
+ },
+ // Add event handler to remove edges when a node is removed
+ initialize: function() {
+ var _this = this;
+ this.on("remove:nodes", function(_node) {
+ _this.get("edges").remove(
+ _this.get("edges").filter(function(_edge) {
+ return _edge.get("from") == _node || _edge.get("to") == _node;
+ })
+ );
+ });
+ }
+});
+
+/* Point of entry */
+
+Rkns.Renkan = function(_opts) {
+ if (typeof _opts.language !== "string" || typeof Rkns.i18n[_opts.language] == "undefined") {
+ _opts.language = "en";
+ }
+ if (typeof _opts.container !== "string") {
+ _opts.container = "renkan";
+ }
+ if (typeof _opts.search !== "object" || !_opts.search) {
+ _opts.search = [];
+ }
+ this.projects = [];
+ this.l10n = Rkns.i18n[_opts.language];
+ this.$ = Rkns.$("#" + _opts.container);
+ this.$.html(this.template());
+ this.uris = {};
+ this.active_project = null;
+ this.renderer = null;
+}
+
+Rkns.Renkan.prototype.template = Rkns._.template(
+ '<div class="Rk-Render"></div><ul class="Rk-Project-List"></ul>'
+);
+
+Rkns.Renkan.prototype.addProject = function(_opts) {
+ var _proj = new Rkns.Models.Project(),
+ _li = Rkns.$("<li>").addClass("Rk-Project").text("Untitled #" + (1+this.projects.length));
+ this.$.find(".Rk-Project-List").append(_li);
+ Rkns.loadJson(_proj, _opts);
+ var _this = this;
+ _li.click(function() {
+ _this.renderProject(_proj);
+ });
+ _proj.on("change:title", function() {
+ _li.html(_proj.get("title"));
+ });
+ _proj.on("select", function() {
+ _this.$.find(".Rk-Project").removeClass("active");
+ _li.addClass("active");
+ });
+ _proj.on("add:nodes", function(_node) {
+ var _uri = _node.get("uri");
+ if (_uri) {
+ if (typeof _this.uris[_uri] === "undefined") {
+ _this.uris[_uri] = [];
+ }
+ _this.uris[_uri].push(_node);
+ }
+ });
+ this.projects.push(_proj);
+ return _proj;
+}
+
+Rkns.Renkan.prototype.renderProject = function(_project) {
+ if (_project) {
+ if (this.renderer) {
+ this.renderer.destroy();
+ }
+ this.active_project = _project;
+ this.renderer = new Rkns.Renderer.Scene(this, _project);
+ this.renderer.autoScale();
+ _project.trigger("select");
+ }
+}
+
+Rkns.Renkan.prototype.renderProjectAt = function(_index) {
+ this.renderProject(this.projects[_index]);
+}
+
+Rkns.loadJson = function(_proj, _opts) {
+ if (typeof _opts.http_method == "undefined") {
+ _opts.http_method = 'PUT';
+ }
+ var _load = function() {
+ Rkns.$.getJSON(_opts.url, function(_data) {
+ _proj.set(_data);
+ if (typeof _opts.callback === "function") {
+ _opts.callback(_proj);
+ }
+ });
+ }
+ _load();
+}
+
+Rkns.Renderer = {
+ _MARGIN_X: 80,
+ _MARGIN_Y: 50,
+ _MIN_DRAG_DISTANCE: 2,
+ _NODE_RADIUS: 20,
+ _NODE_FONT_SIZE: 10,
+ _EDGE_FONT_SIZE: 9,
+ _NODE_MAX_CHAR: 30,
+ _EDGE_MAX_CHAR: 20,
+ _ARROW_LENGTH: 16,
+ _ARROW_WIDTH: 8,
+ _TOOLTIP_ARROW_LENGTH : 15,
+ _TOOLTIP_ARROW_WIDTH : 26,
+ _TOOLTIP_MARGIN : 10,
+ _TOOLTIP_PADDING : 8,
+ _TOOLTIP_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0'])
+}
+
+Rkns.Renderer.Utils = {
+ shortenText : function(_text,_length) {
+ var _rgxp = new RegExp('^(.{' + _length + '}).+$');
+ return _text.replace(/(\n|\r|\r\n)/mg,' ').replace(_rgxp,'$1…');
+ },
+ drawTooltip : function(_coords, _path, _width, _xmargin, _selector) {
+ _selector.css({
+ width: (_width - 2* Rkns.Renderer._TOOLTIP_PADDING),
+ });
+ var _height = _selector.outerHeight() + 2* Rkns.Renderer._TOOLTIP_PADDING,
+ _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),
+ _left = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._TOOLTIP_ARROW_LENGTH ),
+ _right = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._TOOLTIP_ARROW_LENGTH + _width ),
+ _top = _coords.y - _height / 2;
+ if (_top < Rkns.Renderer._TOOLTIP_MARGIN) {
+ _top = Math.min( Rkns.Renderer._TOOLTIP_MARGIN, _coords.y - Rkns.Renderer._TOOLTIP_ARROW_WIDTH / 2 );
+ }
+ var _bottom = _top + _height;
+ if (_bottom > (paper.view.size.height - Rkns.Renderer._TOOLTIP_MARGIN)) {
+ _bottom = Math.max( paper.view.size.height - Rkns.Renderer._TOOLTIP_MARGIN, _coords.y + Rkns.Renderer._TOOLTIP_ARROW_WIDTH / 2 );
+ _top = _bottom - _height;
+ }
+ _path.segments[0].point
+ = _path.segments[7].point
+ = _coords.add([_isLeft * _xmargin, 0]);
+ _path.segments[1].point.x
+ = _path.segments[2].point.x
+ = _path.segments[5].point.x
+ = _path.segments[6].point.x
+ = _left;
+ _path.segments[3].point.x
+ = _path.segments[4].point.x
+ = _right;
+ _path.segments[2].point.y
+ = _path.segments[3].point.y
+ = _top;
+ _path.segments[4].point.y
+ = _path.segments[5].point.y
+ = _bottom;
+ _path.segments[1].point.y = _coords.y - Rkns.Renderer._TOOLTIP_ARROW_WIDTH / 2;
+ _path.segments[6].point.y = _coords.y + Rkns.Renderer._TOOLTIP_ARROW_WIDTH / 2;
+ _path.closed = true;
+ _path.fillColor = new paper.GradientColor(Rkns.Renderer._TOOLTIP_GRADIENT, [0,_top], [0, _bottom]);
+ _selector.css({
+ left: (Rkns.Renderer._TOOLTIP_PADDING + Math.min(_left, _right)),
+ top: (Rkns.Renderer._TOOLTIP_PADDING + _top)
+ });
+ }
+}
+
+Rkns.Renderer._BaseRepresentation = function(_renderer, _model) {
+ if (typeof _renderer !== "undefined") {
+ this.renderer = _renderer;
+ this.project = _renderer.project;
+ this.model = _model;
+ if (this.model) {
+ var _this = this;
+ this._selectBinding = function() {
+ _this.select();
+ };
+ this._unselectBinding = function() {
+ _this.unselect();
+ }
+ this._changeBinding = function() {
+ _this.redraw();
+ }
+ this._removeBinding = function() {
+ _renderer.removeRepresentation(_this);
+ _renderer.redraw();
+ }
+ this.model.on("change", this._changeBinding );
+ this.model.on("remove", this._removeBinding );
+ this.model.on("select", this._selectBinding );
+ this.model.on("unselect", this._unselectBinding );
+ }
+ }
+}
+
+Rkns.Renderer._BaseRepresentation.prototype.super = function(_func) {
+ Rkns.Renderer._BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1));
+}
+
+Rkns.Renderer._BaseRepresentation.prototype.select = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.unselect = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.mouseup = function() {}
+
+Rkns.Renderer._BaseRepresentation.prototype.destroy = function() {
+ if (this.model) {
+ this.model.off("change", this._changeBinding );
+ this.model.off("remove", this._removeBinding );
+ this.model.off("select", this._selectBinding);
+ this.model.off("unselect", this._unselectBinding);
+ }
+}
+
+Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.Node.prototype._init = function() {
+ this.renderer.node_layer.activate();
+ this.type = "Node";
+ this.circle = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS);
+ this.circle.fillColor = '#ffffff';
+ this.circle.__representation = this;
+ this.title = new paper.PointText([0,0]);
+ this.title.characterStyle = {
+ fontSize: Rkns.Renderer._NODE_FONT_SIZE,
+ fillColor: 'black'
+ };
+ this.title.paragraphStyle.justification = 'center';
+ this.title.__representation = this;
+ this.model_coords = new paper.Point(this.model.get("position"));
+}
+
+Rkns.Renderer.Node.prototype.redraw = function() {
+ this.paper_coords = this.renderer.toPaperCoords(this.model_coords);
+ this.circle.position = this.paper_coords;
+ this.title.content = Rkns.Renderer.Utils.shortenText(this.model.get("title"), Rkns.Renderer._NODE_MAX_CHAR);
+ this.title.position = this.paper_coords.add([0, 2 * Rkns.Renderer._NODE_RADIUS]);
+ this.circle.strokeColor = this.model.get("created_by").get("color");
+ var _img = this.model.get("image");
+ if (_img && _img !== this.img) {
+ var _image = new Image(),
+ _this = this;
+ _image.onload = function() {
+ if (_this.node_image) {
+ _this.node_image.remove();
+ }
+ _this.renderer.node_layer.activate();
+ var _ratio = Math.min(1, 2 * Rkns.Renderer._NODE_RADIUS / _image.width, 2 * Rkns.Renderer._NODE_RADIUS / _image.height );
+ var _raster = new paper.Raster(_image);
+ var _clip = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS);
+ _raster.scale(_ratio);
+ _this.node_image = new paper.Group(_clip, _raster);
+ _this.node_image.opacity = _this.selected ? .5 : .9;
+ /* This is a workaround to allow clipping at group level */
+ _this.node_image.clipped = true;
+ _this.node_image.position = _this.paper_coords;
+ _this.node_image.__representation = _this;
+ paper.view.draw();
+ }
+ _image.src = _img;
+ }
+ this.img = _img;
+ if (this.node_image) {
+ if (!this.img) {
+ this.node_image.remove();
+ delete this.node_image;
+ } else {
+ this.node_image.position = this.paper_coords;
+ }
+ }
+}
+
+Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
+ this.paper_coords = this.paper_coords.add(_delta);
+ this.model_coords = this.renderer.toModelCoords(this.paper_coords);
+ this.renderer.redraw();
+}
+
+Rkns.Renderer.Node.prototype.openTooltip = function() {
+ this.renderer.removeRepresentationsOfType("tooltip");
+ var _tooltip = this.renderer.addRepresentation("NodeTooltip",null);
+ _tooltip.node_representation = this;
+ _tooltip.draw();
+}
+
+Rkns.Renderer.Node.prototype.select = function() {
+ this.selected = true;
+ this.circle.strokeWidth = 3;
+ this.openTooltip();
+ this.circle.fillColor = "#ffff80";
+ if (this.node_image) {
+ this.node_image.opacity = .5;
+ }
+ paper.view.draw();
+}
+
+Rkns.Renderer.Node.prototype.unselect = function() {
+ this.selected = false;
+ this.circle.strokeWidth = 1;
+ this.circle.fillColor = "#ffffff";
+ if (this.node_image) {
+ this.node_image.opacity = .9;
+ }
+ paper.view.draw();
+}
+
+Rkns.Renderer.Node.prototype.mouseup = function(_event) {
+}
+
+Rkns.Renderer.Node.prototype.destroy = function(_event) {
+ this.super("destroy");
+ this.circle.remove();
+ this.title.remove();
+ if (this.node_image) {
+ this.node_image.remove();
+ }
+}
+
+/* */
+
+Rkns.Renderer.Edge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.Edge.prototype._init = function() {
+ this.renderer.edge_layer.activate();
+ this.type = "Edge";
+ this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
+ this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
+ this.bundle = this.renderer.addToBundles(this);
+ this.line = new paper.Path();
+ this.line.add([0,0],[0,0],[0,0]);
+ this.line.__representation = this;
+ this.arrow = new paper.Path();
+ this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
+ this.arrow.__representation = this;
+ this.text = new paper.PointText();
+ this.text.characterStyle = {
+ fontSize: Rkns.Renderer._EDGE_FONT_SIZE,
+ fillColor: 'black'
+ };
+ this.text.paragraphStyle.justification = 'center';
+ this.text.__representation = this;
+ this.text_angle = 0;
+ this.arrow_angle = 0;
+}
+
+Rkns.Renderer.Edge.prototype.redraw = function() {
+ var _p0a = this.from_representation.paper_coords,
+ _p1a = this.to_representation.paper_coords,
+ _v = _p1a.subtract(_p0a),
+ _r = _v.length,
+ _u = _v.divide(_r),
+ _group_pos = this.bundle.getPosition(this),
+ _delta = new paper.Point([- _u.y, _u.x]).multiply( 12 * _group_pos ),
+ _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
+ _p1b = _p1a.add(_delta), /* to differentiate inbound and outbound links */
+ _a = _v.angle,
+ _handle = _v.divide(3),
+ _color = this.model.get("created_by").get("color");
+ this.paper_coords = _p0b.add(_p1b).divide(2);
+ this.line.strokeColor = _color;
+ this.line.segments[0].point = _p0a;
+ this.line.segments[1].point = this.paper_coords;
+ this.line.segments[1].handleIn = _handle.multiply(-1);
+ this.line.segments[1].handleOut = _handle;
+ this.line.segments[2].point = _p1a;
+ this.arrow.rotate(_a - this.arrow_angle);
+ this.arrow.fillColor = _color;
+ this.arrow.position = this.paper_coords.subtract(_u.multiply(4));
+ this.arrow_angle = _a;
+ if (_a > 90) {
+ _a -= 180;
+ }
+ if (_a < -90) {
+ _a += 180;
+ }
+ this.text.rotate(_a - this.text_angle);
+ this.text.content = Rkns.Renderer.Utils.shortenText(this.model.get("title"), Rkns.Renderer._EDGE_MAX_CHAR);
+ this.text.position = this.paper_coords;
+ this.text_angle = _a;
+}
+
+Rkns.Renderer.Edge.prototype.openTooltip = function() {
+ this.renderer.removeRepresentationsOfType("tooltip");
+ var _tooltip = this.renderer.addRepresentation("EdgeTooltip",null);
+ _tooltip.edge_representation = this;
+ _tooltip.draw();
+}
+
+Rkns.Renderer.Edge.prototype.select = function() {
+ this.line.strokeWidth = 3;
+ this.openTooltip();
+ paper.view.draw();
+}
+
+Rkns.Renderer.Edge.prototype.unselect = function() {
+ this.line.strokeWidth = 1;
+ paper.view.draw();
+}
+
+Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
+}
+
+Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
+ this.from_representation.paperShift(_delta);
+ this.to_representation.paperShift(_delta);
+ this.renderer.redraw();
+}
+
+Rkns.Renderer.Edge.prototype.destroy = function() {
+ this.super("destroy");
+ this.line.remove();
+ this.arrow.remove();
+ this.text.remove();
+ var _this = this;
+ this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
+ return _edge === _this;
+ });
+}
+
+/* */
+
+Rkns.Renderer.NodeTooltip = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.NodeTooltip.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "tooltip";
+ this.tooltip_block = new paper.Path();
+ var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
+ this.tooltip_block.add.apply(this.tooltip_block, _pts);
+ this.tooltip_block.strokeWidth = 2;
+ this.tooltip_block.strokeColor = "#999999";
+ this.tooltip_block.fillColor = "#e0e0e0";
+ this.tooltip_block.opacity = .8;
+ this.tooltip_$ = Rkns.$('<div>')
+ .appendTo(this.renderer.tooltip_$)
+ .css({
+ position: "absolute",
+ opacity: .8
+ })
+ .hide();
+}
+
+Rkns.Renderer.NodeTooltip.prototype.template = Rkns._.template(
+ '<h2><span class="Rk-CloseX">×</span><%=a%></h2>'
+ + '<p><%-description%></p>'
+ + '<ul class="Rk-Related-List"></ul>'
+);
+
+Rkns.Renderer.NodeTooltip.prototype.draw = function() {
+ var _model = this.node_representation.model,
+ _title = _model.get("title"),
+ _uri = _model.get("uri");
+ this.tooltip_$
+ .html(this.template({
+ a: (_uri ? '<a href="' + _uri + '" target="_blank">' : '' ) + _title + (_uri ? '</a>' : '' ),
+ description: _model.get("description").replace(/(\n|\r|\r\n)/mg,' ').substr(0,180).replace(/(^.{150,179})[\s].+$/m,'$1…')
+ }))
+ var _this = this,
+ _renkan = this.renderer.renkan,
+ _uris = _renkan.uris[_uri];
+ Rkns._(_uris).each(function(_othernode) {
+ if (_othernode !== _model && _othernode.get("project") !== _this.project) {
+ var _otherproj = _othernode.get("project"),
+ _nodetitle = _othernode.get("title") || "Untitled node"
+ _projtitle = _otherproj.get("title") || "Untitled node",
+ _html = _renkan.l10n.see_in_project.replace('{node}',Rkns._.escape(_nodetitle)).replace('{project}',Rkns._.escape(_projtitle)),
+ _li = Rkns.$("<li>").addClass("Rk-Related").html(_html);
+ _li.click(function() {
+ _renkan.renderProject(_otherproj);
+ Rkns._.defer(function() {
+ _othernode.trigger("select");
+ });
+ });
+ _this.tooltip_$.append(_li);
+ }
+ });
+ this.tooltip_$.find(".Rk-CloseX").click(function() {
+ _this.renderer.removeRepresentation(_this);
+ paper.view.draw();
+ });
+ this.redraw();
+}
+
+Rkns.Renderer.NodeTooltip.prototype.redraw = function() {
+ var _coords = this.node_representation.paper_coords;
+ Rkns.Renderer.Utils.drawTooltip(_coords, this.tooltip_block, 250, 15, this.tooltip_$);
+ this.tooltip_$.show();
+}
+
+Rkns.Renderer.NodeTooltip.prototype.destroy = function() {
+ this.tooltip_block.remove();
+ this.tooltip_$.detach();
+}
+
+/* */
+
+Rkns.Renderer.EdgeTooltip = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
+
+Rkns.Renderer.EdgeTooltip.prototype._init = function() {
+ this.renderer.overlay_layer.activate();
+ this.type = "tooltip";
+ this.tooltip_block = new paper.Path();
+ var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
+ this.tooltip_block.add.apply(this.tooltip_block, _pts);
+ this.tooltip_block.strokeWidth = 2;
+ this.tooltip_block.strokeColor = "#999999";
+ this.tooltip_block.fillColor = "#e0e0e0";
+ this.tooltip_block.opacity = .8;
+ this.tooltip_$ = Rkns.$('<div>')
+ .appendTo(this.renderer.tooltip_$)
+ .css({
+ position: "absolute",
+ opacity: .8
+ })
+ .hide();
+}
+
+Rkns.Renderer.EdgeTooltip.prototype.template = Rkns._.template(
+ '<h2><span class="Rk-CloseX">×</span><%=a%></h2>'
+ + '<p><%-description%></p>'
+);
+
+Rkns.Renderer.EdgeTooltip.prototype.draw = function() {
+ var _model = this.edge_representation.model,
+ _title = _model.get("title"),
+ _uri = _model.get("uri");
+ this.tooltip_$
+ .html(this.template({
+ a: (_uri ? '<a href="' + _uri + '" target="_blank">' : '' ) + _title + (_uri ? '</a>' : '' ),
+ description: _model.get("description").replace(/(\n|\r|\r\n)/mg,' ').substr(0,180).replace(/(^.{150,179})[\s].+$/m,'$1…')
+ }));
+ this.redraw();
+ var _this = this;
+ this.tooltip_$.find(".Rk-CloseX").click(function() {
+ _this.renderer.removeRepresentation(_this);
+ paper.view.draw();
+ });
+}
+
+Rkns.Renderer.EdgeTooltip.prototype.redraw = function() {
+ var _coords = this.edge_representation.paper_coords;
+ Rkns.Renderer.Utils.drawTooltip(_coords, this.tooltip_block, 250, 5, this.tooltip_$);
+ this.tooltip_$.show();
+ paper.view.draw();
+}
+
+Rkns.Renderer.EdgeTooltip.prototype.destroy = function() {
+ this.tooltip_block.remove();
+ this.tooltip_$.detach();
+}
+
+/* */
+
+Rkns.Renderer.Scene = function(_renkan, _project) {
+ this.renkan = _renkan;
+ this.project = _project;
+ this.$ = Rkns.$(".Rk-Render");
+ this.representations = [];
+ this.$.html(this.template({
+ width: this.$.width(),
+ height: this.$.height(),
+ l10n: _renkan.l10n
+ }))
+ this.canvas_$ = this.$.find(".Rk-Canvas");
+ this.tooltip_$ = this.$.find(".Rk-Editor");
+ paper.setup(this.canvas_$[0]);
+ this.scale = 1;
+ this.offset = paper.view.center;
+ this.totalScroll = 0;
+ this.click_target = null;
+ this.selected_target = null;
+ this.edge_layer = new paper.Layer();
+ this.node_layer = new paper.Layer();
+ this.overlay_layer = new paper.Layer();
+ this.bundles = [];
+ var _tool = new paper.Tool(),
+ _this = this;
+ _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
+ _tool.onMouseMove = function(_event) {
+ _this.onMouseMove(_event);
+ }
+ _tool.onMouseDown = function(_event) {
+ _this.onMouseDown(_event);
+ }
+ _tool.onMouseDrag = function(_event) {
+ _this.onMouseDrag(_event);
+ }
+ this.canvas_$.mouseup(function(_event) {
+ _this.onMouseUp(_event);
+ });
+ this.canvas_$.mousewheel(function(_event, _delta) {
+ _this.onScroll(_event, _delta);
+ });
+ this.tooltip_$.find(".Rk-ZoomOut").click(function() {
+ _this.offset = new paper.Point([
+ _this.canvas_$.width(),
+ _this.canvas_$.height()
+ ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
+ _this.scale *= Math.SQRT1_2;
+ _this.redraw();
+ });
+ this.tooltip_$.find(".Rk-ZoomIn").click(function() {
+ _this.offset = new paper.Point([
+ _this.canvas_$.width(),
+ _this.canvas_$.height()
+ ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
+ _this.scale *= Math.SQRT2;
+ _this.redraw();
+ });
+ paper.view.onResize = function(_event) {
+ _this.offset = _this.offset.add(_event.delta.divide(2));
+ _this.redraw();
+ }
+
+ var _thRedraw = Rkns._.throttle(function() {
+ _this.redraw();
+ },50);
+
+ this.addRepresentations("Node", this.project.get("nodes"));
+ this.addRepresentations("Edge", this.project.get("edges"));
+
+ this._addNodesBinding = function(_node) {
+ _this.addRepresentation("Node", _node);
+ _thRedraw();
+ }
+ this._addEdgesBinding = function(_edge) {
+ _this.addRepresentation("Edge", _edge);
+ _thRedraw();
+ }
+
+ this.project.on("add:nodes", this._addNodesBinding );
+ this.project.on("add:edges", this._addEdgesBinding );
+ this.redraw();
+}
+
+Rkns.Renderer.Scene.prototype.template = Rkns._.template(
+ '<canvas class="Rk-Canvas" width="<%-width%>" height="<%-height%>"></canvas><div class="Rk-Editor">'
+ + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%-l10n.zoom_out%>"></div></div>'
+ + '</div>'
+);
+
+Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
+ var _bundle = Rkns._(this.bundles).find(function(_bundle) {
+ return (
+ ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation )
+ || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )
+ );
+ });
+ if (typeof _bundle !== "undefined") {
+ _bundle.edges.push(_edgeRepr)
+ } else {
+ _bundle = {
+ from: _edgeRepr.from_representation,
+ to: _edgeRepr.to_representation,
+ edges: [ _edgeRepr ],
+ getPosition: function(_er) {
+ var _dir = (_er.from_representation === this.from) ? 1 : -1;
+ return _dir * ( Rkns._(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 );
+ }
+ }
+ this.bundles.push(_bundle);
+ }
+ return _bundle;
+}
+
+Rkns.Renderer.Scene.prototype.autoScale = function() {
+ if (this.project.get("nodes").length) {
+ var _xx = this.project.get("nodes").map(function(_node) { return _node.get("position").x }),
+ _yy = this.project.get("nodes").map(function(_node) { return _node.get("position").y }),
+ _minx = Math.min.apply(Math, _xx),
+ _miny = Math.min.apply(Math, _yy),
+ _maxx = Math.max.apply(Math, _xx),
+ _maxy = Math.max.apply(Math, _yy);
+ this.scale = Math.min((paper.view.size.width - 2 * Rkns.Renderer._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._MARGIN_Y) / (_maxy - _miny));
+ this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(this.scale));
+ this.redraw();
+ }
+}
+
+Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) {
+ return _point.multiply(this.scale).add(this.offset);
+}
+
+
+Rkns.Renderer.Scene.prototype.toModelCoords = function(_point) {
+ return _point.subtract(this.offset).divide(this.scale);
+}
+
+Rkns.Renderer.Scene.prototype.addRepresentation = function(_type, _model) {
+ var _repr = new Rkns.Renderer[_type](this, _model);
+ this.representations.push(_repr);
+ return _repr;
+}
+
+Rkns.Renderer.Scene.prototype.addRepresentations = function(_type, _collection) {
+ var _this = this;
+ _collection.forEach(function(_model) {
+ _this.addRepresentation(_type, _model);
+ });
+}
+
+Rkns.Renderer.Scene.prototype.removeRepresentation = function(_representation) {
+ _representation.destroy();
+ this.representations = Rkns._(this.representations).reject(
+ function(_repr) {
+ return _repr == _representation
+ }
+ );
+}
+
+Rkns.Renderer.Scene.prototype.getRepresentationByModel = function(_model) {
+ return Rkns._(this.representations).find(function(_repr) {
+ return _repr.model === _model;
+ });
+}
+
+Rkns.Renderer.Scene.prototype.removeRepresentationsOfType = function(_type) {
+ var _representations = Rkns._(this.representations).filter(function(_repr) {
+ return _repr.type == _type;
+ }),
+ _this = this;
+ Rkns._(_representations).each(function(_repr) {
+ _this.removeRepresentation(_repr);
+ });
+}
+
+Rkns.Renderer.Scene.prototype.unselectAll = function() {
+ Rkns._(this.representations).each(function(_repr) {
+ _repr.model.trigger("unselect");
+ });
+}
+
+Rkns.Renderer.Scene.prototype.redraw = function() {
+ Rkns._(this.representations).each(function(_representation) {
+ _representation.redraw();
+ });
+ paper.view.draw();
+}
+
+Rkns.Renderer.Scene.prototype.addTempEdge = function(_from, _point) {
+ var _tmpEdge = this.addRepresentation("TempEdge",null);
+ _tmpEdge.end_pos = _point;
+ _tmpEdge.from_representation = _from;
+ _tmpEdge.redraw();
+ this.click_target = _tmpEdge;
+}
+
+Rkns.Renderer.Scene.prototype.findTarget = function(_hitResult) {
+ if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
+ var _newTarget = _hitResult.item.__representation;
+ if (this.selected_target !== _newTarget && _newTarget.model) {
+ if (this.selected_target) {
+ this.selected_target.model.trigger("unselect");
+ }
+ _newTarget.model.trigger("select");
+ this.selected_target = _newTarget;
+ }
+ } else {
+ if (!_hitResult) {
+ this.removeRepresentationsOfType("tooltip");
+ }
+ if (this.selected_target) {
+ this.selected_target.model.trigger("unselect");
+ }
+ this.selected_target = null;
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) {
+ var _hitResult = paper.project.hitTest(_event.point);
+ if (this.is_dragging) {
+ if (this.click_target && typeof this.click_target.paperShift === "function") {
+ this.click_target.paperShift(_event.delta);
+ } else {
+ this.offset = this.offset.add(_event.delta);
+ this.redraw();
+ }
+ } else {
+ this.findTarget(_hitResult);
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
+ this.is_dragging = false;
+ var _hitResult = paper.project.hitTest(_event.point);
+ if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
+ this.click_target = _hitResult.item.__representation;
+ } else {
+ this.click_target = null;
+ }
+}
+
+Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) {
+ this.is_dragging = true;
+ this.onMouseMove(_event);
+}
+
+Rkns.Renderer.Scene.prototype.onMouseUp = function(_event) {
+ if (this.click_target) {
+ var _off = this.canvas_$.offset();
+ if (this.click_target.model) {
+ this.click_target.model.trigger("click");
+ }
+ }
+ this.is_dragging = false;
+ this.click_target = null;
+}
+
+Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
+ this.totalScroll += _scrolldelta;
+ if (Math.abs(this.totalScroll) >= 1) {
+ var _off = this.canvas_$.offset(),
+ _delta = new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
+ if (this.totalScroll > 0) {
+ this.offset = this.offset.subtract(_delta);
+ this.scale *= Math.SQRT2;
+ } else {
+ this.offset = this.offset.add(_delta.divide( Math.SQRT2 ));
+ this.scale *= Math.SQRT1_2;
+ }
+ this.totalScroll = 0;
+ this.redraw();
+ }
+}
+
+Rkns.Renderer.Scene.prototype.destroy = function() {
+ this.project.off("add:nodes", this._addNodesBinding );
+ this.project.off("add:edges", this._addEdgesBinding );
+ Rkns._(this.representations).each(function(_repr) {
+ _repr.destroy();
+ });
+ this.$.html("");
+ paper.remove();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/twitter-bin.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,124 @@
+Rkns.Twitter = {
+}
+
+Rkns.Twitter.Search = function(_renkan, _opts) {
+ this.renkan = _renkan;
+ this.opts = _opts;
+}
+
+Rkns.Twitter.Search.prototype.getBgClass = function() {
+ return "Rk-Twitter-Icon";
+}
+
+Rkns.Twitter.Search.prototype.getSearchTitle = function() {
+ return this.renkan.l10n.search_on_twitter;
+}
+
+Rkns.Twitter.Search.prototype.search = function(_q) {
+ this.renkan.tabs.push(
+ new Rkns.Twitter.Bin(this.renkan, {
+ search: _q
+ })
+ );
+}
+
+Rkns.Twitter.Bin = Rkns.Utils.inherit(Rkns._BaseBin);
+
+Rkns.Twitter.Bin.prototype.tweetTemplate = Rkns._.template(
+ '<li class="Rk-Twitter-Tweet Rk-Bin-Item" data-uri="http://twitter.com/<%=tweet.from_user%>/status/<%=tweet.id_str%>" '
+ + 'data-title="Tweet by @<%=tweet.from_user%>" data-description="<%-tweet.text%>" data-image="<%=tweet.profile_image_url%>">'
+ + '<img class="Rk-Twitter-TwImage" src="<%=tweet.profile_image_url%>" />'
+ + '<h4 class="Rk-Twitter-TwTitle"><a href="http://twitter.com/<%=tweet.from_user%>" target="_blank">@<%=tweet.from_user%></a> (<%=tweet.from_user_name%>)</h4>'
+ + '<p class="Rk-Twitter-TwDate"><%=date%></p>'
+ + '<p class="Rk-Twitter-TwText"><%=text%></p>'
+ + '<p class="Rk-Twitter-TwActions"><a class="Rk-Twitter-TwAction" href="http://twitter.com/<%=tweet.from_user%>/status/<%=tweet.id_str%>" target="_blank">show original</a> · '
+ + '<a href="http://twitter.com/intent/tweet?in_reply_to=<%=tweet.id_str%>" target="_blank">reply</a> · '
+ + '<a href="http://twitter.com/intent/retweet?tweet_id=<%=tweet.id_str%>" target="_blank">retweet</a> · '
+ + '<a href="http://twitter.com/intent/favorite?tweet_id=<%=tweet.id_str%>" target="_blank">favorite</a></p></li>'
+);
+
+Rkns.Twitter.Bin.prototype._init = function(_renkan, _opts) {
+ this.search = _opts.search;
+ this.title_icon_$.addClass('Rk-Twitter-Title-Icon');
+ this.title_$.html(this.search).addClass("Rk-Twitter-Title");
+ this.refresh();
+}
+
+Rkns.Twitter.Bin.prototype.refresh = function() {
+ var _this = this;
+ Rkns.$.ajax({
+ url: "http://search.twitter.com/search.json?q=" + encodeURIComponent(this.search),
+ dataType: "jsonp",
+ success: function(_data) {
+ var _rgxp = new RegExp('('+_this.search.replace(/(\W)/g,'\\$1')+')','gi');
+ function highlight(_text) {
+ return _text.replace(_rgxp, "<span class='searchmatch'>$1</span>");
+ }
+ var _html = Rkns._(_data.results).map(function(_result) {
+ var _entities = [],
+ _users = _result.text.match(/@[\w_]+/gm),
+ _lastpos = 0;
+ if (_users) {
+ for (var _i = 0; _i < _users.length; _i++) {
+ var _m = _users[_i],
+ _start = _lastpos + _result.text.substr(_lastpos).search(_m),
+ _lastpos = _start + _m.length;
+ _entities.push({
+ "text" : _m,
+ "start" : _start,
+ "end" : _lastpos,
+ "link" :'<a href="http://twitter.com/' + _m.substr(1) + '" onclick="filtrerTexte(\'' + _m + '\'); return false;" target="_blank">',
+ });
+ }
+ }
+ var _hashes = _result.text.match(/([^&]|^)#[^\s,.!?=#@&;()]+/gm),
+ _lastpos = 0;
+ if (_hashes) {
+ for (var _i = 0; _i < _hashes.length; _i++) {
+ var _m = _hashes[_i],
+ _h = ( _m[0] == '#' ? _m : _m.substr(1) ),
+ _start = _lastpos + _result.text.substr(_lastpos).search(_h),
+ _lastpos = _start + _h.length;
+ _entities.push({
+ "text" : _h,
+ "start" : _start,
+ "end" : _lastpos,
+ "link" :'<a href="http://twitter.com/search?q=' + encodeURIComponent(_h) + '" onclick="filtrerTexte(\'' + _.escape(_h) + '\'); return false;" target="_blank">',
+ });
+ }
+ }
+
+ var _urls = _result.text.match(/(www\.|https?:\/\/)[\w./_\-]+/gim),
+ _lastpos = 0;
+ if (_urls) {
+ for (var _i = 0; _i < _urls.length; _i++) {
+ var _m = _urls[_i],
+ _start = _lastpos + _result.text.substr(_lastpos).search(_m),
+ _lastpos = _start + _m.length;
+ _entities.push({
+ "text" : _m,
+ "start" : _start,
+ "end" : _lastpos,
+ "link" :'<a href="' + _m + '" target="_blank">',
+ });
+ }
+ }
+ _entities = Rkns._(_entities).sortBy(function(a) { return a.start });
+ var _lastend = 0,
+ _text = Rkns._(_entities).map(function(_e) {
+ var _txt = highlight(_result.text.substring(_lastend, _e.start)) + _e.link + highlight(_e.text) + '</a>';
+ _lastend = _e.end;
+ return _txt;
+ }).join("") + highlight(_result.text.substring(_lastend));
+
+ return _this.tweetTemplate({
+ tweet: _result,
+ date: new Date(_result.created_at.replace(/(\+|-)/,'UTC$1')).toLocaleString(),
+ text: _text
+ });
+ }).join("");
+ _this.main_$.html(_html);
+ _renkan.resizeBins();
+ }
+ });
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/underscore.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,32 @@
+// Underscore.js 1.3.3
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
+c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
+g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,
+c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&&
+a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
+c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
+a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
+function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&
+(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
+j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,
+0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,
+e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
+i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<=
+1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=
+i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=
+g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));
+return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
+c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
+function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
+b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
+b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
+function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
+u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
+b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
+this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/wikipedia-bin.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,63 @@
+Rkns.Wikipedia = {
+}
+
+Rkns.Wikipedia.Search = function(_renkan, _opts) {
+ this.renkan = _renkan;
+ this.lang = _opts.lang || "en";
+}
+
+Rkns.Wikipedia.Search.prototype.getBgClass = function() {
+ return "Rk-Wikipedia-Search-Icon Rk-Wikipedia-Lang-" + this.lang;
+}
+
+Rkns.Wikipedia.Search.prototype.getSearchTitle = function() {
+ return ( this.renkan.l10n["wiki_" + this.lang] || this.renkan.l10n.wiki_) ;
+}
+
+Rkns.Wikipedia.Search.prototype.search = function(_q) {
+ this.renkan.tabs.push(
+ new Rkns.Wikipedia.Bin(this.renkan, {
+ lang: this.lang,
+ search: _q
+ })
+ );
+}
+
+Rkns.Wikipedia.Bin = Rkns.Utils.inherit(Rkns._BaseBin);
+
+Rkns.Wikipedia.Bin.prototype.resultTemplate = Rkns._.template(
+ '<li class="Rk-Wikipedia-Result Rk-Bin-Item" data-uri="<%=wpurl%>" '
+ + 'data-title="Wikipedia: <%=result.title%>" data-description="<%=wpdesc%>" data-image="<%=static_url%>img/wikipedia.png">'
+ + '<img class="Rk-Wikipedia-Icon" src="<%=static_url%>img/wikipedia.png"></div><h4 class="Rk-Wikipedia-Title"><a href="<%=wpurl%>" target="_blank"><%=highlightedtitle%></a></h4>'
+ + '<p class="Rk-Wikipedia-Snippet"><%=result.snippet%></p></li>'
+);
+
+Rkns.Wikipedia.Bin.prototype._init = function(_renkan, _opts) {
+ this.search = _opts.search;
+ this.lang = _opts.lang || "en";
+ this.title_icon_$.addClass('Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-' + this.lang);
+ this.title_$.html(this.search).addClass("Rk-Wikipedia-Title");
+ this.refresh();
+}
+
+Rkns.Wikipedia.Bin.prototype.refresh = function() {
+ var _this = this;
+ Rkns.$.ajax({
+ url: "http://" + _this.lang + ".wikipedia.org/w/api.php?action=query&list=search&srsearch=" + encodeURIComponent(this.search) + "&format=json",
+ dataType: "jsonp",
+ success: function(_data) {
+ var _rgxp = new RegExp('('+_this.search.replace(/(\W)/g,'\\$1')+')','gi'),
+ _html = Rkns._(_data.query.search).map(function(_result) {
+ return _this.resultTemplate({
+ result: _result,
+ wpurl: "http://" + _this.lang + ".wikipedia.org/wiki/" + encodeURI(_result.title.replace(/ /g,"_")),
+ highlightedtitle: _result.title.replace(_rgxp, "<span class='searchmatch'>$1</span>"),
+ wpdesc: Rkns.$('<div>').html(_result.snippet).text(),
+ static_url: _this.renkan.static_url
+ });
+ }).join("");
+ _this.main_$.html(_html);
+ _renkan.resizeBins();
+ }
+ });
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/backbone-relational.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,1715 @@
+/* vim: set tabstop=4:softtabstop=4:shiftwidth=4:noexpandtab */
+/**
+ * Backbone-relational.js 0.7.0
+ * (c) 2011-2013 Paul Uithol
+ *
+ * Backbone-relational may be freely distributed under the MIT license; see the accompanying LICENSE.txt.
+ * For details and documentation: https://github.com/PaulUithol/Backbone-relational.
+ * Depends on Backbone (and thus on Underscore as well): https://github.com/documentcloud/backbone.
+ */
+( function( undefined ) {
+ "use strict";
+
+ /**
+ * CommonJS shim
+ **/
+ var _, Backbone, exports;
+ if ( typeof window === 'undefined' ) {
+ _ = require( 'underscore' );
+ Backbone = require( 'backbone' );
+ exports = module.exports = Backbone;
+ }
+ else {
+ _ = window._;
+ Backbone = window.Backbone;
+ exports = window;
+ }
+
+ Backbone.Relational = {
+ showWarnings: true
+ };
+
+ /**
+ * Semaphore mixin; can be used as both binary and counting.
+ **/
+ Backbone.Semaphore = {
+ _permitsAvailable: null,
+ _permitsUsed: 0,
+
+ acquire: function() {
+ if ( this._permitsAvailable && this._permitsUsed >= this._permitsAvailable ) {
+ throw new Error( 'Max permits acquired' );
+ }
+ else {
+ this._permitsUsed++;
+ }
+ },
+
+ release: function() {
+ if ( this._permitsUsed === 0 ) {
+ throw new Error( 'All permits released' );
+ }
+ else {
+ this._permitsUsed--;
+ }
+ },
+
+ isLocked: function() {
+ return this._permitsUsed > 0;
+ },
+
+ setAvailablePermits: function( amount ) {
+ if ( this._permitsUsed > amount ) {
+ throw new Error( 'Available permits cannot be less than used permits' );
+ }
+ this._permitsAvailable = amount;
+ }
+ };
+
+ /**
+ * A BlockingQueue that accumulates items while blocked (via 'block'),
+ * and processes them when unblocked (via 'unblock').
+ * Process can also be called manually (via 'process').
+ */
+ Backbone.BlockingQueue = function() {
+ this._queue = [];
+ };
+ _.extend( Backbone.BlockingQueue.prototype, Backbone.Semaphore, {
+ _queue: null,
+
+ add: function( func ) {
+ if ( this.isBlocked() ) {
+ this._queue.push( func );
+ }
+ else {
+ func();
+ }
+ },
+
+ process: function() {
+ while ( this._queue && this._queue.length ) {
+ this._queue.shift()();
+ }
+ },
+
+ block: function() {
+ this.acquire();
+ },
+
+ unblock: function() {
+ this.release();
+ if ( !this.isBlocked() ) {
+ this.process();
+ }
+ },
+
+ isBlocked: function() {
+ return this.isLocked();
+ }
+ });
+ /**
+ * Global event queue. Accumulates external events ('add:<key>', 'remove:<key>' and 'update:<key>')
+ * until the top-level object is fully initialized (see 'Backbone.RelationalModel').
+ */
+ Backbone.Relational.eventQueue = new Backbone.BlockingQueue();
+
+ /**
+ * Backbone.Store keeps track of all created (and destruction of) Backbone.RelationalModel.
+ * Handles lookup for relations.
+ */
+ Backbone.Store = function() {
+ this._collections = [];
+ this._reverseRelations = [];
+ this._subModels = [];
+ this._modelScopes = [ exports ];
+ };
+ _.extend( Backbone.Store.prototype, Backbone.Events, {
+ addModelScope: function( scope ) {
+ this._modelScopes.push( scope );
+ },
+
+ /**
+ * Add a set of subModelTypes to the store, that can be used to resolve the '_superModel'
+ * for a model later in 'setupSuperModel'.
+ *
+ * @param {Backbone.RelationalModel} subModelTypes
+ * @param {Backbone.RelationalModel} superModelType
+ */
+ addSubModels: function( subModelTypes, superModelType ) {
+ this._subModels.push({
+ 'superModelType': superModelType,
+ 'subModels': subModelTypes
+ });
+ },
+
+ /**
+ * Check if the given modelType is registered as another model's subModel. If so, add it to the super model's
+ * '_subModels', and set the modelType's '_superModel', '_subModelTypeName', and '_subModelTypeAttribute'.
+ *
+ * @param {Backbone.RelationalModel} modelType
+ */
+ setupSuperModel: function( modelType ) {
+ _.find( this._subModels || [], function( subModelDef ) {
+ return _.find( subModelDef.subModels || [], function( subModelTypeName, typeValue ) {
+ var subModelType = this.getObjectByName( subModelTypeName );
+
+ if ( modelType === subModelType ) {
+ // Set 'modelType' as a child of the found superModel
+ subModelDef.superModelType._subModels[ typeValue ] = modelType;
+
+ // Set '_superModel', '_subModelTypeValue', and '_subModelTypeAttribute' on 'modelType'.
+ modelType._superModel = subModelDef.superModelType;
+ modelType._subModelTypeValue = typeValue;
+ modelType._subModelTypeAttribute = subModelDef.superModelType.prototype.subModelTypeAttribute;
+ return true;
+ }
+ }, this );
+ }, this );
+ },
+
+ /**
+ * Add a reverse relation. Is added to the 'relations' property on model's prototype, and to
+ * existing instances of 'model' in the store as well.
+ * @param {Object} relation
+ * @param {Backbone.RelationalModel} relation.model
+ * @param {String} relation.type
+ * @param {String} relation.key
+ * @param {String|Object} relation.relatedModel
+ */
+ addReverseRelation: function( relation ) {
+ var exists = _.any( this._reverseRelations || [], function( rel ) {
+ return _.all( relation || [], function( val, key ) {
+ return val === rel[ key ];
+ });
+ });
+
+ if ( !exists && relation.model && relation.type ) {
+ this._reverseRelations.push( relation );
+
+ var addRelation = function( model, relation ) {
+ if ( !model.prototype.relations ) {
+ model.prototype.relations = [];
+ }
+ model.prototype.relations.push( relation );
+
+ _.each( model._subModels || [], function( subModel ) {
+ addRelation( subModel, relation );
+ }, this );
+ };
+
+ addRelation( relation.model, relation );
+
+ this.retroFitRelation( relation );
+ }
+ },
+
+ /**
+ * Add a 'relation' to all existing instances of 'relation.model' in the store
+ * @param {Object} relation
+ */
+ retroFitRelation: function( relation ) {
+ var coll = this.getCollection( relation.model );
+ coll.each( function( model ) {
+ if ( !( model instanceof relation.model ) ) {
+ return;
+ }
+
+ new relation.type( model, relation );
+ }, this);
+ },
+
+ /**
+ * Find the Store's collection for a certain type of model.
+ * @param {Backbone.RelationalModel} model
+ * @return {Backbone.Collection} A collection if found (or applicable for 'model'), or null
+ */
+ getCollection: function( model ) {
+ if ( model instanceof Backbone.RelationalModel ) {
+ model = model.constructor;
+ }
+
+ var rootModel = model;
+ while ( rootModel._superModel ) {
+ rootModel = rootModel._superModel;
+ }
+
+ var coll = _.detect( this._collections, function( c ) {
+ return c.model === rootModel;
+ });
+
+ if ( !coll ) {
+ coll = this._createCollection( rootModel );
+ }
+
+ return coll;
+ },
+
+ /**
+ * Find a type on the global object by name. Splits name on dots.
+ * @param {String} name
+ * @return {Object}
+ */
+ getObjectByName: function( name ) {
+ var parts = name.split( '.' ),
+ type = null;
+
+ _.find( this._modelScopes || [], function( scope ) {
+ type = _.reduce( parts || [], function( memo, val ) {
+ return memo ? memo[ val ] : undefined;
+ }, scope );
+
+ if ( type && type !== scope ) {
+ return true;
+ }
+ }, this );
+
+ return type;
+ },
+
+ _createCollection: function( type ) {
+ var coll;
+
+ // If 'type' is an instance, take its constructor
+ if ( type instanceof Backbone.RelationalModel ) {
+ type = type.constructor;
+ }
+
+ // Type should inherit from Backbone.RelationalModel.
+ if ( type.prototype instanceof Backbone.RelationalModel ) {
+ coll = new Backbone.Collection();
+ coll.model = type;
+
+ this._collections.push( coll );
+ }
+
+ return coll;
+ },
+
+ /**
+ * Find the attribute that is to be used as the `id` on a given object
+ * @param type
+ * @param {String|Number|Object|Backbone.RelationalModel} item
+ * @return {String|Number}
+ */
+ resolveIdForItem: function( type, item ) {
+ var id = _.isString( item ) || _.isNumber( item ) ? item : null;
+
+ if ( id === null ) {
+ if ( item instanceof Backbone.RelationalModel ) {
+ id = item.id;
+ }
+ else if ( _.isObject( item ) ) {
+ id = item[ type.prototype.idAttribute ];
+ }
+ }
+
+ // Make all falsy values `null` (except for 0, which could be an id.. see '/issues/179')
+ if ( !id && id !== 0 ) {
+ id = null;
+ }
+
+ return id;
+ },
+
+ /**
+ *
+ * @param type
+ * @param {String|Number|Object|Backbone.RelationalModel} item
+ */
+ find: function( type, item ) {
+ var id = this.resolveIdForItem( type, item );
+ var coll = this.getCollection( type );
+
+ // Because the found object could be of any of the type's superModel
+ // types, only return it if it's actually of the type asked for.
+ if ( coll ) {
+ var obj = coll.get( id );
+
+ if ( obj instanceof type ) {
+ return obj;
+ }
+ }
+
+ return null;
+ },
+
+ /**
+ * Add a 'model' to it's appropriate collection. Retain the original contents of 'model.collection'.
+ * @param {Backbone.RelationalModel} model
+ */
+ register: function( model ) {
+ var coll = this.getCollection( model );
+
+ if ( coll ) {
+ if ( coll.get( model ) ) {
+ throw new Error( "Cannot instantiate more than one Backbone.RelationalModel with the same id per type!" );
+ }
+
+ var modelColl = model.collection;
+ coll.add( model );
+ model.bind( 'destroy', this.unregister, this );
+ model.collection = modelColl;
+ }
+ },
+
+ /**
+ * Explicitly update a model's id in it's store collection
+ * @param {Backbone.RelationalModel} model
+ */
+ update: function( model ) {
+ var coll = this.getCollection( model );
+ coll._onModelEvent( 'change:' + model.idAttribute, model, coll );
+ },
+
+ /**
+ * Remove a 'model' from the store.
+ * @param {Backbone.RelationalModel} model
+ */
+ unregister: function( model ) {
+ model.unbind( 'destroy', this.unregister );
+ var coll = this.getCollection( model );
+ coll && coll.remove( model );
+ }
+ });
+ Backbone.Relational.store = new Backbone.Store();
+
+ /**
+ * The main Relation class, from which 'HasOne' and 'HasMany' inherit. Internally, 'relational:<key>' events
+ * are used to regulate addition and removal of models from relations.
+ *
+ * @param {Backbone.RelationalModel} instance
+ * @param {Object} options
+ * @param {string} options.key
+ * @param {Backbone.RelationalModel.constructor} options.relatedModel
+ * @param {Boolean|String} [options.includeInJSON=true] Serialize the given attribute for related model(s)' in toJSON, or just their ids.
+ * @param {Boolean} [options.createModels=true] Create objects from the contents of keys if the object is not found in Backbone.store.
+ * @param {Object} [options.reverseRelation] Specify a bi-directional relation. If provided, Relation will reciprocate
+ * the relation to the 'relatedModel'. Required and optional properties match 'options', except that it also needs
+ * {Backbone.Relation|String} type ('HasOne' or 'HasMany').
+ */
+ Backbone.Relation = function( instance, options ) {
+ this.instance = instance;
+ // Make sure 'options' is sane, and fill with defaults from subclasses and this object's prototype
+ options = _.isObject( options ) ? options : {};
+ this.reverseRelation = _.defaults( options.reverseRelation || {}, this.options.reverseRelation );
+ this.reverseRelation.type = !_.isString( this.reverseRelation.type ) ? this.reverseRelation.type :
+ Backbone[ this.reverseRelation.type ] || Backbone.Relational.store.getObjectByName( this.reverseRelation.type );
+ this.model = options.model || this.instance.constructor;
+ this.options = _.defaults( options, this.options, Backbone.Relation.prototype.options );
+
+ this.key = this.options.key;
+ this.keySource = this.options.keySource || this.key;
+ this.keyDestination = this.options.keyDestination || this.keySource || this.key;
+
+ // 'exports' should be the global object where 'relatedModel' can be found on if given as a string.
+ this.relatedModel = this.options.relatedModel;
+ if ( _.isString( this.relatedModel ) ) {
+ this.relatedModel = Backbone.Relational.store.getObjectByName( this.relatedModel );
+ }
+
+ if ( !this.checkPreconditions() ) {
+ return;
+ }
+
+ if ( instance ) {
+ var contentKey = this.keySource;
+ if ( contentKey !== this.key && typeof this.instance.get( this.key ) === 'object' ) {
+ contentKey = this.key;
+ }
+
+ this.keyContents = this.instance.get( contentKey );
+
+ // Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
+ if ( this.keySource !== this.key ) {
+ this.instance.unset( this.keySource, { silent: true } );
+ }
+
+ // Add this Relation to instance._relations
+ this.instance._relations.push( this );
+ }
+
+ // Add the reverse relation on 'relatedModel' to the store's reverseRelations
+ if ( !this.options.isAutoRelation && this.reverseRelation.type && this.reverseRelation.key ) {
+ Backbone.Relational.store.addReverseRelation( _.defaults( {
+ isAutoRelation: true,
+ model: this.relatedModel,
+ relatedModel: this.model,
+ reverseRelation: this.options // current relation is the 'reverseRelation' for it's own reverseRelation
+ },
+ this.reverseRelation // Take further properties from this.reverseRelation (type, key, etc.)
+ ) );
+ }
+
+ _.bindAll( this, '_modelRemovedFromCollection', '_relatedModelAdded', '_relatedModelRemoved' );
+
+ if ( instance ) {
+ this.initialize();
+
+ if ( options.autoFetch ) {
+ this.instance.fetchRelated( options.key, _.isObject( options.autoFetch ) ? options.autoFetch : {} );
+ }
+
+ // When a model in the store is destroyed, check if it is 'this.instance'.
+ Backbone.Relational.store.getCollection( this.instance )
+ .bind( 'relational:remove', this._modelRemovedFromCollection );
+
+ // When 'relatedModel' are created or destroyed, check if it affects this relation.
+ Backbone.Relational.store.getCollection( this.relatedModel )
+ .bind( 'relational:add', this._relatedModelAdded )
+ .bind( 'relational:remove', this._relatedModelRemoved );
+ }
+ };
+ // Fix inheritance :\
+ Backbone.Relation.extend = Backbone.Model.extend;
+ // Set up all inheritable **Backbone.Relation** properties and methods.
+ _.extend( Backbone.Relation.prototype, Backbone.Events, Backbone.Semaphore, {
+ options: {
+ createModels: true,
+ includeInJSON: true,
+ isAutoRelation: false,
+ autoFetch: false
+ },
+
+ instance: null,
+ key: null,
+ keyContents: null,
+ relatedModel: null,
+ reverseRelation: null,
+ related: null,
+
+ _relatedModelAdded: function( model, coll, options ) {
+ // Allow 'model' to set up it's relations, before calling 'tryAddRelated'
+ // (which can result in a call to 'addRelated' on a relation of 'model')
+ var dit = this;
+ model.queue( function() {
+ dit.tryAddRelated( model, options );
+ });
+ },
+
+ _relatedModelRemoved: function( model, coll, options ) {
+ this.removeRelated( model, options );
+ },
+
+ _modelRemovedFromCollection: function( model ) {
+ if ( model === this.instance ) {
+ this.destroy();
+ }
+ },
+
+ /**
+ * Check several pre-conditions.
+ * @return {Boolean} True if pre-conditions are satisfied, false if they're not.
+ */
+ checkPreconditions: function() {
+ var i = this.instance,
+ k = this.key,
+ m = this.model,
+ rm = this.relatedModel,
+ warn = Backbone.Relational.showWarnings && typeof console !== 'undefined';
+
+ if ( !m || !k || !rm ) {
+ warn && console.warn( 'Relation=%o; no model, key or relatedModel (%o, %o, %o)', this, m, k, rm );
+ return false;
+ }
+ // Check if the type in 'model' inherits from Backbone.RelationalModel
+ if ( !( m.prototype instanceof Backbone.RelationalModel ) ) {
+ warn && console.warn( 'Relation=%o; model does not inherit from Backbone.RelationalModel (%o)', this, i );
+ return false;
+ }
+ // Check if the type in 'relatedModel' inherits from Backbone.RelationalModel
+ if ( !( rm.prototype instanceof Backbone.RelationalModel ) ) {
+ warn && console.warn( 'Relation=%o; relatedModel does not inherit from Backbone.RelationalModel (%o)', this, rm );
+ return false;
+ }
+ // Check if this is not a HasMany, and the reverse relation is HasMany as well
+ if ( this instanceof Backbone.HasMany && this.reverseRelation.type === Backbone.HasMany ) {
+ warn && console.warn( 'Relation=%o; relation is a HasMany, and the reverseRelation is HasMany as well.', this );
+ return false;
+ }
+
+ // Check if we're not attempting to create a duplicate relationship
+ if ( i && i._relations.length ) {
+ var exists = _.any( i._relations || [], function( rel ) {
+ var hasReverseRelation = this.reverseRelation.key && rel.reverseRelation.key;
+ return rel.relatedModel === rm && rel.key === k &&
+ ( !hasReverseRelation || this.reverseRelation.key === rel.reverseRelation.key );
+ }, this );
+
+ if ( exists ) {
+ warn && console.warn( 'Relation=%o between instance=%o.%s and relatedModel=%o.%s already exists',
+ this, i, k, rm, this.reverseRelation.key );
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Set the related model(s) for this relation
+ * @param {Backbone.Model|Backbone.Collection} related
+ * @param {Object} [options]
+ */
+ setRelated: function( related, options ) {
+ this.related = related;
+
+ this.instance.acquire();
+ this.instance.set( this.key, related, _.defaults( options || {}, { silent: true } ) );
+ this.instance.release();
+ },
+
+ /**
+ * Determine if a relation (on a different RelationalModel) is the reverse
+ * relation of the current one.
+ * @param {Backbone.Relation} relation
+ * @return {Boolean}
+ */
+ _isReverseRelation: function( relation ) {
+ if ( relation.instance instanceof this.relatedModel && this.reverseRelation.key === relation.key &&
+ this.key === relation.reverseRelation.key ) {
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Get the reverse relations (pointing back to 'this.key' on 'this.instance') for the currently related model(s).
+ * @param {Backbone.RelationalModel} [model] Get the reverse relations for a specific model.
+ * If not specified, 'this.related' is used.
+ * @return {Backbone.Relation[]}
+ */
+ getReverseRelations: function( model ) {
+ var reverseRelations = [];
+ // Iterate over 'model', 'this.related.models' (if this.related is a Backbone.Collection), or wrap 'this.related' in an array.
+ var models = !_.isUndefined( model ) ? [ model ] : this.related && ( this.related.models || [ this.related ] );
+ _.each( models || [], function( related ) {
+ _.each( related.getRelations() || [], function( relation ) {
+ if ( this._isReverseRelation( relation ) ) {
+ reverseRelations.push( relation );
+ }
+ }, this );
+ }, this );
+
+ return reverseRelations;
+ },
+
+ /**
+ * Rename options.silent to options.silentChange, so events propagate properly.
+ * (for example in HasMany, from 'addRelated'->'handleAddition')
+ * @param {Object} [options]
+ * @return {Object}
+ */
+ sanitizeOptions: function( options ) {
+ options = options ? _.clone( options ) : {};
+ if ( options.silent ) {
+ options.silentChange = true;
+ delete options.silent;
+ }
+ return options;
+ },
+
+ /**
+ * Rename options.silentChange to options.silent, so events are silenced as intended in Backbone's
+ * original functions.
+ * @param {Object} [options]
+ * @return {Object}
+ */
+ unsanitizeOptions: function( options ) {
+ options = options ? _.clone( options ) : {};
+ if ( options.silentChange ) {
+ options.silent = true;
+ delete options.silentChange;
+ }
+ return options;
+ },
+
+ // Cleanup. Get reverse relation, call removeRelated on each.
+ destroy: function() {
+ Backbone.Relational.store.getCollection( this.instance )
+ .unbind( 'relational:remove', this._modelRemovedFromCollection );
+
+ Backbone.Relational.store.getCollection( this.relatedModel )
+ .unbind( 'relational:add', this._relatedModelAdded )
+ .unbind( 'relational:remove', this._relatedModelRemoved );
+
+ _.each( this.getReverseRelations() || [], function( relation ) {
+ relation.removeRelated( this.instance );
+ }, this );
+ }
+ });
+
+ Backbone.HasOne = Backbone.Relation.extend({
+ options: {
+ reverseRelation: { type: 'HasMany' }
+ },
+
+ initialize: function() {
+ _.bindAll( this, 'onChange' );
+
+ this.instance.bind( 'relational:change:' + this.key, this.onChange );
+
+ var model = this.findRelated( { silent: true } );
+ this.setRelated( model );
+
+ // Notify new 'related' object of the new relation.
+ _.each( this.getReverseRelations() || [], function( relation ) {
+ relation.addRelated( this.instance );
+ }, this );
+ },
+
+ findRelated: function( options ) {
+ var item = this.keyContents;
+ var model = null;
+
+ if ( item instanceof this.relatedModel ) {
+ model = item;
+ }
+ else if ( item || item === 0 ) { // since 0 can be a valid `id` as well
+ model = this.relatedModel.findOrCreate( item, { create: this.options.createModels } );
+ }
+
+ return model;
+ },
+
+ /**
+ * If the key is changed, notify old & new reverse relations and initialize the new relation
+ */
+ onChange: function( model, attr, options ) {
+ // Don't accept recursive calls to onChange (like onChange->findRelated->findOrCreate->initializeRelations->addRelated->onChange)
+ if ( this.isLocked() ) {
+ return;
+ }
+ this.acquire();
+ options = this.sanitizeOptions( options );
+
+ // 'options._related' is set by 'addRelated'/'removeRelated'. If it is set, the change
+ // is the result of a call from a relation. If it's not, the change is the result of
+ // a 'set' call on this.instance.
+ var changed = _.isUndefined( options._related );
+ var oldRelated = changed ? this.related : options._related;
+
+ if ( changed ) {
+ this.keyContents = attr;
+
+ // Set new 'related'
+ if ( attr instanceof this.relatedModel ) {
+ this.related = attr;
+ }
+ else if ( attr ) {
+ var related = this.findRelated( options );
+ this.setRelated( related );
+ }
+ else {
+ this.setRelated( null );
+ }
+ }
+
+ // Notify old 'related' object of the terminated relation
+ if ( oldRelated && this.related !== oldRelated ) {
+ _.each( this.getReverseRelations( oldRelated ) || [], function( relation ) {
+ relation.removeRelated( this.instance, options );
+ }, this );
+ }
+
+ // Notify new 'related' object of the new relation. Note we do re-apply even if this.related is oldRelated;
+ // that can be necessary for bi-directional relations if 'this.instance' was created after 'this.related'.
+ // In that case, 'this.instance' will already know 'this.related', but the reverse might not exist yet.
+ _.each( this.getReverseRelations() || [], function( relation ) {
+ relation.addRelated( this.instance, options );
+ }, this);
+
+ // Fire the 'update:<key>' event if 'related' was updated
+ if ( !options.silentChange && this.related !== oldRelated ) {
+ var dit = this;
+ Backbone.Relational.eventQueue.add( function() {
+ dit.instance.trigger( 'update:' + dit.key, dit.instance, dit.related, options );
+ });
+ }
+ this.release();
+ },
+
+ /**
+ * If a new 'this.relatedModel' appears in the 'store', try to match it to the last set 'keyContents'
+ */
+ tryAddRelated: function( model, options ) {
+ if ( this.related ) {
+ return;
+ }
+ options = this.sanitizeOptions( options );
+
+ var item = this.keyContents;
+ if ( item || item === 0 ) { // since 0 can be a valid `id` as well
+ var id = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item );
+ if ( !_.isNull( id ) && model.id === id ) {
+ this.addRelated( model, options );
+ }
+ }
+ },
+
+ addRelated: function( model, options ) {
+ if ( model !== this.related ) {
+ var oldRelated = this.related || null;
+ this.setRelated( model );
+ this.onChange( this.instance, model, { _related: oldRelated } );
+ }
+ },
+
+ removeRelated: function( model, options ) {
+ if ( !this.related ) {
+ return;
+ }
+
+ if ( model === this.related ) {
+ var oldRelated = this.related || null;
+ this.setRelated( null );
+ this.onChange( this.instance, model, { _related: oldRelated } );
+ }
+ }
+ });
+
+ Backbone.HasMany = Backbone.Relation.extend({
+ collectionType: null,
+
+ options: {
+ reverseRelation: { type: 'HasOne' },
+ collectionType: Backbone.Collection,
+ collectionKey: true,
+ collectionOptions: {}
+ },
+
+ initialize: function() {
+ _.bindAll( this, 'onChange', 'handleAddition', 'handleRemoval', 'handleReset' );
+ this.instance.bind( 'relational:change:' + this.key, this.onChange );
+
+ // Handle a custom 'collectionType'
+ this.collectionType = this.options.collectionType;
+ if ( _.isString( this.collectionType ) ) {
+ this.collectionType = Backbone.Relational.store.getObjectByName( this.collectionType );
+ }
+ if ( !this.collectionType.prototype instanceof Backbone.Collection ){
+ throw new Error( 'collectionType must inherit from Backbone.Collection' );
+ }
+
+ // Handle cases where a model/relation is created with a collection passed straight into 'attributes'
+ if ( this.keyContents instanceof Backbone.Collection ) {
+ this.setRelated( this._prepareCollection( this.keyContents ) );
+ }
+ else {
+ this.setRelated( this._prepareCollection() );
+ }
+
+ this.findRelated( { silent: true } );
+ },
+
+ _getCollectionOptions: function() {
+ return _.isFunction( this.options.collectionOptions ) ?
+ this.options.collectionOptions( this.instance ) :
+ this.options.collectionOptions;
+ },
+
+ /**
+ * Bind events and setup collectionKeys for a collection that is to be used as the backing store for a HasMany.
+ * If no 'collection' is supplied, a new collection will be created of the specified 'collectionType' option.
+ * @param {Backbone.Collection} [collection]
+ */
+ _prepareCollection: function( collection ) {
+ if ( this.related ) {
+ this.related
+ .unbind( 'relational:add', this.handleAddition )
+ .unbind( 'relational:remove', this.handleRemoval )
+ .unbind( 'relational:reset', this.handleReset )
+ }
+
+ if ( !collection || !( collection instanceof Backbone.Collection ) ) {
+ collection = new this.collectionType( [], this._getCollectionOptions() );
+ }
+
+ collection.model = this.relatedModel;
+
+ if ( this.options.collectionKey ) {
+ var key = this.options.collectionKey === true ? this.options.reverseRelation.key : this.options.collectionKey;
+
+ if ( collection[ key ] && collection[ key ] !== this.instance ) {
+ if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) {
+ console.warn( 'Relation=%o; collectionKey=%s already exists on collection=%o', this, key, this.options.collectionKey );
+ }
+ }
+ else if ( key ) {
+ collection[ key ] = this.instance;
+ }
+ }
+
+ collection
+ .bind( 'relational:add', this.handleAddition )
+ .bind( 'relational:remove', this.handleRemoval )
+ .bind( 'relational:reset', this.handleReset );
+
+ return collection;
+ },
+
+ findRelated: function( options ) {
+ if ( this.keyContents ) {
+ var models = [];
+
+ if ( this.keyContents instanceof Backbone.Collection ) {
+ models = this.keyContents.models;
+ }
+ else {
+ // Handle cases the an API/user supplies just an Object/id instead of an Array
+ this.keyContents = _.isArray( this.keyContents ) ? this.keyContents : [ this.keyContents ];
+
+ // Try to find instances of the appropriate 'relatedModel' in the store
+ _.each( this.keyContents || [], function( item ) {
+ var model = null;
+ if ( item instanceof this.relatedModel ) {
+ model = item;
+ }
+ else if ( item || item === 0 ) { // since 0 can be a valid `id` as well
+ model = this.relatedModel.findOrCreate( item, { create: this.options.createModels } );
+ }
+
+ if ( model && !this.related.get( model ) ) {
+ models.push( model );
+ }
+ }, this );
+ }
+
+ // Add all found 'models' in on go, so 'add' will only be called once (and thus 'sort', etc.)
+ if ( models.length ) {
+ options = this.unsanitizeOptions( options );
+ this.related.add( models, options );
+ }
+ }
+ },
+
+ /**
+ * If the key is changed, notify old & new reverse relations and initialize the new relation
+ */
+ onChange: function( model, attr, options ) {
+ options = this.sanitizeOptions( options );
+ this.keyContents = attr;
+
+ // Replace 'this.related' by 'attr' if it is a Backbone.Collection
+ if ( attr instanceof Backbone.Collection ) {
+ this._prepareCollection( attr );
+ this.related = attr;
+ }
+ // Otherwise, 'attr' should be an array of related object ids.
+ // Re-use the current 'this.related' if it is a Backbone.Collection, and remove any current entries.
+ // Otherwise, create a new collection.
+ else {
+ var oldIds = {}, newIds = {};
+
+ if (!_.isArray( attr ) && attr !== undefined) {
+ attr = [ attr ];
+ }
+
+ _.each( attr, function( attributes ) {
+ newIds[ attributes.id ] = true;
+ });
+
+ var coll = this.related;
+ if ( coll instanceof Backbone.Collection ) {
+ // Make sure to operate on a copy since we're removing while iterating
+ _.each( coll.models.slice(0) , function( model ) {
+ // When fetch is called with the 'keepNewModels' option, we don't want to remove
+ // client-created new models when the fetch is completed.
+ if ( !options.keepNewModels || !model.isNew() ) {
+ oldIds[ model.id ] = true;
+ coll.remove( model, { silent: (model.id in newIds) } );
+ }
+ });
+ } else {
+ coll = this._prepareCollection();
+ }
+
+ _.each( attr, function( attributes ) {
+ var model = this.relatedModel.findOrCreate( attributes, { create: this.options.createModels } );
+ if (model) {
+ coll.add( model, { silent: (attributes.id in oldIds)} );
+ }
+ }, this);
+
+ this.setRelated( coll );
+
+ }
+
+ var dit = this;
+ Backbone.Relational.eventQueue.add( function() {
+ !options.silentChange && dit.instance.trigger( 'update:' + dit.key, dit.instance, dit.related, options );
+ });
+ },
+
+ tryAddRelated: function( model, options ) {
+ options = this.sanitizeOptions( options );
+ if ( !this.related.get( model ) ) {
+ // Check if this new model was specified in 'this.keyContents'
+ var item = _.any( this.keyContents || [], function( item ) {
+ var id = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item );
+ return !_.isNull( id ) && id === model.id;
+ }, this );
+
+ if ( item ) {
+ this.related.add( model, options );
+ }
+ }
+ },
+
+ /**
+ * When a model is added to a 'HasMany', trigger 'add' on 'this.instance' and notify reverse relations.
+ * (should be 'HasOne', must set 'this.instance' as their related).
+ */
+ handleAddition: function( model, coll, options ) {
+ //console.debug('handleAddition called; args=%o', arguments);
+ // Make sure the model is in fact a valid model before continuing.
+ // (it can be invalid as a result of failing validation in Backbone.Collection._prepareModel)
+ if ( !( model instanceof Backbone.Model ) ) {
+ return;
+ }
+
+ options = this.sanitizeOptions( options );
+
+ _.each( this.getReverseRelations( model ) || [], function( relation ) {
+ relation.addRelated( this.instance, options );
+ }, this );
+
+ // Only trigger 'add' once the newly added model is initialized (so, has it's relations set up)
+ var dit = this;
+ Backbone.Relational.eventQueue.add( function() {
+ !options.silentChange && dit.instance.trigger( 'add:' + dit.key, model, dit.related, options );
+ });
+ },
+
+ /**
+ * When a model is removed from a 'HasMany', trigger 'remove' on 'this.instance' and notify reverse relations.
+ * (should be 'HasOne', which should be nullified)
+ */
+ handleRemoval: function( model, coll, options ) {
+ //console.debug('handleRemoval called; args=%o', arguments);
+ if ( !( model instanceof Backbone.Model ) ) {
+ return;
+ }
+
+ options = this.sanitizeOptions( options );
+
+ _.each( this.getReverseRelations( model ) || [], function( relation ) {
+ relation.removeRelated( this.instance, options );
+ }, this );
+
+ var dit = this;
+ Backbone.Relational.eventQueue.add( function() {
+ !options.silentChange && dit.instance.trigger( 'remove:' + dit.key, model, dit.related, options );
+ });
+ },
+
+ handleReset: function( coll, options ) {
+ options = this.sanitizeOptions( options );
+
+ var dit = this;
+ Backbone.Relational.eventQueue.add( function() {
+ !options.silentChange && dit.instance.trigger( 'reset:' + dit.key, dit.related, options );
+ });
+ },
+
+ addRelated: function( model, options ) {
+ var dit = this;
+ options = this.unsanitizeOptions( options );
+ model.queue( function() { // Queued to avoid errors for adding 'model' to the 'this.related' set twice
+ if ( dit.related && !dit.related.get( model ) ) {
+ dit.related.add( model, options );
+ }
+ });
+ },
+
+ removeRelated: function( model, options ) {
+ options = this.unsanitizeOptions( options );
+ if ( this.related.get( model ) ) {
+ this.related.remove( model, options );
+ }
+ }
+ });
+
+ /**
+ * A type of Backbone.Model that also maintains relations to other models and collections.
+ * New events when compared to the original:
+ * - 'add:<key>' (model, related collection, options)
+ * - 'remove:<key>' (model, related collection, options)
+ * - 'update:<key>' (model, related model or collection, options)
+ */
+ Backbone.RelationalModel = Backbone.Model.extend({
+ relations: null, // Relation descriptions on the prototype
+ _relations: null, // Relation instances
+ _isInitialized: false,
+ _deferProcessing: false,
+ _queue: null,
+
+ subModelTypeAttribute: 'type',
+ subModelTypes: null,
+
+ constructor: function( attributes, options ) {
+ // Nasty hack, for cases like 'model.get( <HasMany key> ).add( item )'.
+ // Defer 'processQueue', so that when 'Relation.createModels' is used we:
+ // a) Survive 'Backbone.Collection.add'; this takes care we won't error on "can't add model to a set twice"
+ // (by creating a model from properties, having the model add itself to the collection via one of
+ // it's relations, then trying to add it to the collection).
+ // b) Trigger 'HasMany' collection events only after the model is really fully set up.
+ // Example that triggers both a and b: "p.get('jobs').add( { company: c, person: p } )".
+ var dit = this;
+ if ( options && options.collection ) {
+ this._deferProcessing = true;
+
+ var processQueue = function( model ) {
+ if ( model === dit ) {
+ dit._deferProcessing = false;
+ dit.processQueue();
+ options.collection.unbind( 'relational:add', processQueue );
+ }
+ };
+ options.collection.bind( 'relational:add', processQueue );
+
+ // So we do process the queue eventually, regardless of whether this model really gets added to 'options.collection'.
+ _.defer( function() {
+ processQueue( dit );
+ });
+ }
+
+ this._queue = new Backbone.BlockingQueue();
+ this._queue.block();
+ Backbone.Relational.eventQueue.block();
+
+ Backbone.Model.apply( this, arguments );
+
+ // Try to run the global queue holding external events
+ Backbone.Relational.eventQueue.unblock();
+ },
+
+ /**
+ * Override 'trigger' to queue 'change' and 'change:*' events
+ */
+ trigger: function( eventName ) {
+ if ( eventName.length > 5 && 'change' === eventName.substr( 0, 6 ) ) {
+ var dit = this, args = arguments;
+ Backbone.Relational.eventQueue.add( function() {
+ Backbone.Model.prototype.trigger.apply( dit, args );
+ });
+ }
+ else {
+ Backbone.Model.prototype.trigger.apply( this, arguments );
+ }
+
+ return this;
+ },
+
+ /**
+ * Initialize Relations present in this.relations; determine the type (HasOne/HasMany), then creates a new instance.
+ * Invoked in the first call so 'set' (which is made from the Backbone.Model constructor).
+ */
+ initializeRelations: function() {
+ this.acquire(); // Setting up relations often also involve calls to 'set', and we only want to enter this function once
+ this._relations = [];
+
+ _.each( this.relations || [], function( rel ) {
+ var type = !_.isString( rel.type ) ? rel.type : Backbone[ rel.type ] || Backbone.Relational.store.getObjectByName( rel.type );
+ if ( type && type.prototype instanceof Backbone.Relation ) {
+ new type( this, rel ); // Also pushes the new Relation into _relations
+ }
+ else {
+ Backbone.Relational.showWarnings && typeof console !== 'undefined' && console.warn( 'Relation=%o; missing or invalid type!', rel );
+ }
+ }, this );
+
+ this._isInitialized = true;
+ this.release();
+ this.processQueue();
+ },
+
+ /**
+ * When new values are set, notify this model's relations (also if options.silent is set).
+ * (Relation.setRelated locks this model before calling 'set' on it to prevent loops)
+ */
+ updateRelations: function( options ) {
+ if ( this._isInitialized && !this.isLocked() ) {
+ _.each( this._relations || [], function( rel ) {
+ // Update from data in `rel.keySource` if set, or `rel.key` otherwise
+ var val = this.attributes[ rel.keySource ] || this.attributes[ rel.key ];
+ if ( rel.related !== val ) {
+ this.trigger( 'relational:change:' + rel.key, this, val, options || {} );
+ }
+ }, this );
+ }
+ },
+
+ /**
+ * Either add to the queue (if we're not initialized yet), or execute right away.
+ */
+ queue: function( func ) {
+ this._queue.add( func );
+ },
+
+ /**
+ * Process _queue
+ */
+ processQueue: function() {
+ if ( this._isInitialized && !this._deferProcessing && this._queue.isBlocked() ) {
+ this._queue.unblock();
+ }
+ },
+
+ /**
+ * Get a specific relation.
+ * @param key {string} The relation key to look for.
+ * @return {Backbone.Relation} An instance of 'Backbone.Relation', if a relation was found for 'key', or null.
+ */
+ getRelation: function( key ) {
+ return _.detect( this._relations, function( rel ) {
+ if ( rel.key === key ) {
+ return true;
+ }
+ }, this );
+ },
+
+ /**
+ * Get all of the created relations.
+ * @return {Backbone.Relation[]}
+ */
+ getRelations: function() {
+ return this._relations;
+ },
+
+ /**
+ * Retrieve related objects.
+ * @param key {string} The relation key to fetch models for.
+ * @param [options] {Object} Options for 'Backbone.Model.fetch' and 'Backbone.sync'.
+ * @param [update=false] {boolean} Whether to force a fetch from the server (updating existing models).
+ * @return {jQuery.when[]} An array of request objects
+ */
+ fetchRelated: function( key, options, update ) {
+ options || ( options = {} );
+ var setUrl,
+ requests = [],
+ rel = this.getRelation( key ),
+ keyContents = rel && rel.keyContents,
+ toFetch = keyContents && _.select( _.isArray( keyContents ) ? keyContents : [ keyContents ], function( item ) {
+ var id = Backbone.Relational.store.resolveIdForItem( rel.relatedModel, item );
+ return !_.isNull( id ) && ( update || !Backbone.Relational.store.find( rel.relatedModel, id ) );
+ }, this );
+
+ if ( toFetch && toFetch.length ) {
+ // Create a model for each entry in 'keyContents' that is to be fetched
+ var models = _.map( toFetch, function( item ) {
+ var model;
+
+ if ( _.isObject( item ) ) {
+ model = rel.relatedModel.findOrCreate( item );
+ }
+ else {
+ var attrs = {};
+ attrs[ rel.relatedModel.prototype.idAttribute ] = item;
+ model = rel.relatedModel.findOrCreate( attrs );
+ }
+
+ return model;
+ }, this );
+
+ // Try if the 'collection' can provide a url to fetch a set of models in one request.
+ if ( rel.related instanceof Backbone.Collection && _.isFunction( rel.related.url ) ) {
+ setUrl = rel.related.url( models );
+ }
+
+ // An assumption is that when 'Backbone.Collection.url' is a function, it can handle building of set urls.
+ // To make sure it can, test if the url we got by supplying a list of models to fetch is different from
+ // the one supplied for the default fetch action (without args to 'url').
+ if ( setUrl && setUrl !== rel.related.url() ) {
+ var opts = _.defaults(
+ {
+ error: function() {
+ var args = arguments;
+ _.each( models || [], function( model ) {
+ model.trigger( 'destroy', model, model.collection, options );
+ options.error && options.error.apply( model, args );
+ });
+ },
+ url: setUrl
+ },
+ options,
+ { add: true }
+ );
+
+ requests = [ rel.related.fetch( opts ) ];
+ }
+ else {
+ requests = _.map( models || [], function( model ) {
+ var opts = _.defaults(
+ {
+ error: function() {
+ model.trigger( 'destroy', model, model.collection, options );
+ options.error && options.error.apply( model, arguments );
+ }
+ },
+ options
+ );
+ return model.fetch( opts );
+ }, this );
+ }
+ }
+
+ return requests;
+ },
+
+ set: function( key, value, options ) {
+ Backbone.Relational.eventQueue.block();
+
+ // Duplicate backbone's behavior to allow separate key/value parameters, instead of a single 'attributes' object
+ var attributes;
+ if ( _.isObject( key ) || key == null ) {
+ attributes = key;
+ options = value;
+ }
+ else {
+ attributes = {};
+ attributes[ key ] = value;
+ }
+
+ var result = Backbone.Model.prototype.set.apply( this, arguments );
+
+ // Ideal place to set up relations :)
+ if ( !this._isInitialized && !this.isLocked() ) {
+ this.constructor.initializeModelHierarchy();
+
+ Backbone.Relational.store.register( this );
+
+ this.initializeRelations();
+ }
+ // Update the 'idAttribute' in Backbone.store if; we don't want it to miss an 'id' update due to {silent:true}
+ else if ( attributes && this.idAttribute in attributes ) {
+ Backbone.Relational.store.update( this );
+ }
+
+ if ( attributes ) {
+ this.updateRelations( options );
+ }
+
+ // Try to run the global queue holding external events
+ Backbone.Relational.eventQueue.unblock();
+
+ return result;
+ },
+
+ unset: function( attribute, options ) {
+ Backbone.Relational.eventQueue.block();
+
+ var result = Backbone.Model.prototype.unset.apply( this, arguments );
+ this.updateRelations( options );
+
+ // Try to run the global queue holding external events
+ Backbone.Relational.eventQueue.unblock();
+
+ return result;
+ },
+
+ clear: function( options ) {
+ Backbone.Relational.eventQueue.block();
+
+ var result = Backbone.Model.prototype.clear.apply( this, arguments );
+ this.updateRelations( options );
+
+ // Try to run the global queue holding external events
+ Backbone.Relational.eventQueue.unblock();
+
+ return result;
+ },
+
+ /**
+ * Override 'change', so the change will only execute after 'set' has finised (relations are updated),
+ * and 'previousAttributes' will be available when the event is fired.
+ */
+ change: function( options ) {
+ var dit = this, args = arguments;
+ Backbone.Relational.eventQueue.add( function() {
+ Backbone.Model.prototype.change.apply( dit, args );
+ });
+ },
+
+ clone: function() {
+ var attributes = _.clone( this.attributes );
+ if ( !_.isUndefined( attributes[ this.idAttribute ] ) ) {
+ attributes[ this.idAttribute ] = null;
+ }
+
+ _.each( this.getRelations() || [], function( rel ) {
+ delete attributes[ rel.key ];
+ });
+
+ return new this.constructor( attributes );
+ },
+
+ /**
+ * Convert relations to JSON, omits them when required
+ */
+ toJSON: function(options) {
+ // If this Model has already been fully serialized in this branch once, return to avoid loops
+ if ( this.isLocked() ) {
+ return this.id;
+ }
+
+ this.acquire();
+ var json = Backbone.Model.prototype.toJSON.call( this, options );
+
+ if ( this.constructor._superModel && !( this.constructor._subModelTypeAttribute in json ) ) {
+ json[ this.constructor._subModelTypeAttribute ] = this.constructor._subModelTypeValue;
+ }
+
+ _.each( this._relations || [], function( rel ) {
+ var value = json[ rel.key ];
+
+ if ( rel.options.includeInJSON === true) {
+ if ( value && _.isFunction( value.toJSON ) ) {
+ json[ rel.keyDestination ] = value.toJSON( options );
+ }
+ else {
+ json[ rel.keyDestination ] = null;
+ }
+ }
+ else if ( _.isString( rel.options.includeInJSON ) ) {
+ if ( value instanceof Backbone.Collection ) {
+ json[ rel.keyDestination ] = value.pluck( rel.options.includeInJSON );
+ }
+ else if ( value instanceof Backbone.Model ) {
+ json[ rel.keyDestination ] = value.get( rel.options.includeInJSON );
+ }
+ else {
+ json[ rel.keyDestination ] = null;
+ }
+ }
+ else if ( _.isArray( rel.options.includeInJSON ) ) {
+ if ( value instanceof Backbone.Collection ) {
+ var valueSub = [];
+ value.each( function( model ) {
+ var curJson = {};
+ _.each( rel.options.includeInJSON, function( key ) {
+ curJson[ key ] = model.get( key );
+ });
+ valueSub.push( curJson );
+ });
+ json[ rel.keyDestination ] = valueSub;
+ }
+ else if ( value instanceof Backbone.Model ) {
+ var valueSub = {};
+ _.each( rel.options.includeInJSON, function( key ) {
+ valueSub[ key ] = value.get( key );
+ });
+ json[ rel.keyDestination ] = valueSub;
+ }
+ else {
+ json[ rel.keyDestination ] = null;
+ }
+ }
+ else {
+ delete json[ rel.key ];
+ }
+
+ if ( rel.keyDestination !== rel.key ) {
+ delete json[ rel.key ];
+ }
+ });
+
+ this.release();
+ return json;
+ }
+ },
+ {
+ setup: function( superModel ) {
+ // We don't want to share a relations array with a parent, as this will cause problems with
+ // reverse relations.
+ this.prototype.relations = ( this.prototype.relations || [] ).slice( 0 );
+
+ this._subModels = {};
+ this._superModel = null;
+
+ // If this model has 'subModelTypes' itself, remember them in the store
+ if ( this.prototype.hasOwnProperty( 'subModelTypes' ) ) {
+ Backbone.Relational.store.addSubModels( this.prototype.subModelTypes, this );
+ }
+ // The 'subModelTypes' property should not be inherited, so reset it.
+ else {
+ this.prototype.subModelTypes = null;
+ }
+
+ // Initialize all reverseRelations that belong to this new model.
+ _.each( this.prototype.relations || [], function( rel ) {
+ if ( !rel.model ) {
+ rel.model = this;
+ }
+
+ if ( rel.reverseRelation && rel.model === this ) {
+ var preInitialize = true;
+ if ( _.isString( rel.relatedModel ) ) {
+ /**
+ * The related model might not be defined for two reasons
+ * 1. it never gets defined, e.g. a typo
+ * 2. it is related to itself
+ * In neither of these cases do we need to pre-initialize reverse relations.
+ */
+ var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel );
+ preInitialize = relatedModel && ( relatedModel.prototype instanceof Backbone.RelationalModel );
+ }
+
+ var type = !_.isString( rel.type ) ? rel.type : Backbone[ rel.type ] || Backbone.Relational.store.getObjectByName( rel.type );
+ if ( preInitialize && type && type.prototype instanceof Backbone.Relation ) {
+ new type( null, rel );
+ }
+ }
+ }, this );
+
+ return this;
+ },
+
+ /**
+ * Create a 'Backbone.Model' instance based on 'attributes'.
+ * @param {Object} attributes
+ * @param {Object} [options]
+ * @return {Backbone.Model}
+ */
+ build: function( attributes, options ) {
+ var model = this;
+
+ // 'build' is a possible entrypoint; it's possible no model hierarchy has been determined yet.
+ this.initializeModelHierarchy();
+
+ // Determine what type of (sub)model should be built if applicable.
+ // Lookup the proper subModelType in 'this._subModels'.
+ if ( this._subModels && this.prototype.subModelTypeAttribute in attributes ) {
+ var subModelTypeAttribute = attributes[ this.prototype.subModelTypeAttribute ];
+ var subModelType = this._subModels[ subModelTypeAttribute ];
+ if ( subModelType ) {
+ model = subModelType;
+ }
+ }
+
+ return new model( attributes, options );
+ },
+
+ initializeModelHierarchy: function() {
+ // If we're here for the first time, try to determine if this modelType has a 'superModel'.
+ if ( _.isUndefined( this._superModel ) || _.isNull( this._superModel ) ) {
+ Backbone.Relational.store.setupSuperModel( this );
+
+ // If a superModel has been found, copy relations from the _superModel if they haven't been
+ // inherited automatically (due to a redefinition of 'relations').
+ // Otherwise, make sure we don't get here again for this type by making '_superModel' false so we fail
+ // the isUndefined/isNull check next time.
+ if ( this._superModel ) {
+ //
+ if ( this._superModel.prototype.relations ) {
+ var supermodelRelationsExist = _.any( this.prototype.relations || [], function( rel ) {
+ return rel.model && rel.model !== this;
+ }, this );
+
+ if ( !supermodelRelationsExist ) {
+ this.prototype.relations = this._superModel.prototype.relations.concat( this.prototype.relations );
+ }
+ }
+ }
+ else {
+ this._superModel = false;
+ }
+ }
+
+ // If we came here through 'build' for a model that has 'subModelTypes', and not all of them have been resolved yet, try to resolve each.
+ if ( this.prototype.subModelTypes && _.keys( this.prototype.subModelTypes ).length !== _.keys( this._subModels ).length ) {
+ _.each( this.prototype.subModelTypes || [], function( subModelTypeName ) {
+ var subModelType = Backbone.Relational.store.getObjectByName( subModelTypeName );
+ subModelType && subModelType.initializeModelHierarchy();
+ });
+ }
+ },
+
+ /**
+ * Find an instance of `this` type in 'Backbone.Relational.store'.
+ * - If `attributes` is a string or a number, `findOrCreate` will just query the `store` and return a model if found.
+ * - If `attributes` is an object, the model will be updated with `attributes` if found.
+ * Otherwise, a new model is created with `attributes` (unless `options.create` is explicitly set to `false`).
+ * @param {Object|String|Number} attributes Either a model's id, or the attributes used to create or update a model.
+ * @param {Object} [options]
+ * @param {Boolean} [options.create=true]
+ * @return {Backbone.RelationalModel}
+ */
+ findOrCreate: function( attributes, options ) {
+ var parsedAttributes = (_.isObject( attributes ) && this.prototype.parse) ? this.prototype.parse( attributes ) : attributes;
+ // Try to find an instance of 'this' model type in the store
+ var model = Backbone.Relational.store.find( this, parsedAttributes );
+
+ // If we found an instance, update it with the data in 'item'; if not, create an instance
+ // (unless 'options.create' is false).
+ if ( _.isObject( attributes ) ) {
+ if ( model ) {
+ model.set( parsedAttributes, options );
+ }
+ else if ( !options || ( options && options.create !== false ) ) {
+ model = this.build( attributes, options );
+ }
+ }
+
+ return model;
+ }
+ });
+ _.extend( Backbone.RelationalModel.prototype, Backbone.Semaphore );
+
+ /**
+ * Override Backbone.Collection._prepareModel, so objects will be built using the correct type
+ * if the collection.model has subModels.
+ */
+ Backbone.Collection.prototype.__prepareModel = Backbone.Collection.prototype._prepareModel;
+ Backbone.Collection.prototype._prepareModel = function ( attrs, options ) {
+ var model;
+
+ if ( attrs instanceof Backbone.Model ) {
+ if ( !attrs.collection ) {
+ attrs.collection = this;
+ }
+ model = attrs;
+ }
+ else {
+ options || (options = {});
+ options.collection = this;
+
+ if ( typeof this.model.findOrCreate !== 'undefined' ) {
+ model = this.model.findOrCreate( attrs, options );
+ }
+ else {
+ model = new this.model( attrs, options );
+ }
+
+ if ( !model._validate( attrs, options ) ) {
+ model = false;
+ }
+ }
+
+ return model;
+ };
+
+
+ /**
+ * Override Backbone.Collection.add, so objects fetched from the server multiple times will
+ * update the existing Model. Also, trigger 'relational:add'.
+ */
+ var add = Backbone.Collection.prototype.__add = Backbone.Collection.prototype.add;
+ Backbone.Collection.prototype.add = function( models, options ) {
+ options || (options = {});
+ if ( !_.isArray( models ) ) {
+ models = [ models ];
+ }
+
+ var modelsToAdd = [];
+
+ //console.debug( 'calling add on coll=%o; model=%o, options=%o', this, models, options );
+ _.each( models || [], function( model ) {
+ if ( !( model instanceof Backbone.Model ) ) {
+ // `_prepareModel` attempts to find `model` in Backbone.store through `findOrCreate`,
+ // and sets the new properties on it if is found. Otherwise, a new model is instantiated.
+ model = Backbone.Collection.prototype._prepareModel.call( this, model, options );
+ }
+
+ if ( model instanceof Backbone.Model && !this.get( model ) ) {
+ modelsToAdd.push( model );
+ }
+ }, this );
+
+ // Add 'models' in a single batch, so the original add will only be called once (and thus 'sort', etc).
+ if ( modelsToAdd.length ) {
+ add.call( this, modelsToAdd, options );
+
+ _.each( modelsToAdd || [], function( model ) {
+ this.trigger( 'relational:add', model, this, options );
+ }, this );
+ }
+
+ return this;
+ };
+
+ /**
+ * Override 'Backbone.Collection.remove' to trigger 'relational:remove'.
+ */
+ var remove = Backbone.Collection.prototype.__remove = Backbone.Collection.prototype.remove;
+ Backbone.Collection.prototype.remove = function( models, options ) {
+ options || (options = {});
+ if ( !_.isArray( models ) ) {
+ models = [ models ];
+ }
+ else {
+ models = models.slice( 0 );
+ }
+
+ //console.debug('calling remove on coll=%o; models=%o, options=%o', this, models, options );
+ _.each( models || [], function( model ) {
+ model = this.get( model );
+
+ if ( model instanceof Backbone.Model ) {
+ remove.call( this, model, options );
+ this.trigger('relational:remove', model, this, options);
+ }
+ }, this );
+
+ return this;
+ };
+
+ /**
+ * Override 'Backbone.Collection.reset' to trigger 'relational:reset'.
+ */
+ var reset = Backbone.Collection.prototype.__reset = Backbone.Collection.prototype.reset;
+ Backbone.Collection.prototype.reset = function( models, options ) {
+ reset.call( this, models, options );
+ this.trigger( 'relational:reset', this, options );
+
+ return this;
+ };
+
+ /**
+ * Override 'Backbone.Collection.sort' to trigger 'relational:reset'.
+ */
+ var sort = Backbone.Collection.prototype.__sort = Backbone.Collection.prototype.sort;
+ Backbone.Collection.prototype.sort = function( options ) {
+ sort.call( this, options );
+ this.trigger( 'relational:reset', this, options );
+
+ return this;
+ };
+
+ /**
+ * Override 'Backbone.Collection.trigger' so 'add', 'remove' and 'reset' events are queued until relations
+ * are ready.
+ */
+ var trigger = Backbone.Collection.prototype.__trigger = Backbone.Collection.prototype.trigger;
+ Backbone.Collection.prototype.trigger = function( eventName ) {
+ if ( eventName === 'add' || eventName === 'remove' || eventName === 'reset' ) {
+ var dit = this, args = arguments;
+
+ if (eventName === 'add') {
+ args = _.toArray( args );
+ // the fourth argument in case of a regular add is the option object.
+ // we need to clone it, as it could be modified while we wait on the eventQueue to be unblocked
+ if (_.isObject( args[3] ) ) {
+ args[3] = _.clone( args[3] );
+ }
+ }
+
+ Backbone.Relational.eventQueue.add( function() {
+ trigger.apply( dit, args );
+ });
+ }
+ else {
+ trigger.apply( this, arguments );
+ }
+
+ return this;
+ };
+
+ // Override .extend() to automatically call .setup()
+ Backbone.RelationalModel.extend = function( protoProps, classProps ) {
+ var child = Backbone.Model.extend.apply( this, arguments );
+
+ child.setup( this );
+
+ return child;
+ };
+})();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/backbone.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,42 @@
+// Backbone.js 0.9.9
+
+// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+(function(){var k=this,y=k.Backbone,h=[],z=h.push,r=h.slice,A=h.splice,g;g="undefined"!==typeof exports?exports:k.Backbone={};g.VERSION="0.9.9";var e=k._;!e&&"undefined"!==typeof require&&(e=require("underscore"));g.$=k.jQuery||k.Zepto||k.ender;g.noConflict=function(){k.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var s=/\s+/,n=function(a,b,c,d){if(!c)return!0;if("object"===typeof c)for(var f in c)a[b].apply(a,[f,c[f]].concat(d));else if(s.test(c)){c=c.split(s);f=0;for(var e=c.length;f<
+e;f++)a[b].apply(a,[c[f]].concat(d))}else return!0},t=function(a,b,c){var d,a=-1,f=b.length;switch(c.length){case 0:for(;++a<f;)(d=b[a]).callback.call(d.ctx);break;case 1:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0]);break;case 2:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0],c[1]);break;case 3:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0],c[1],c[2]);break;default:for(;++a<f;)(d=b[a]).callback.apply(d.ctx,c)}},h=g.Events={on:function(a,b,c){if(!n(this,"on",a,[b,c])||!b)return this;this._events||(this._events=
+{});(this._events[a]||(this._events[a]=[])).push({callback:b,context:c,ctx:c||this});return this},once:function(a,b,c){if(!n(this,"once",a,[b,c])||!b)return this;var d=this,f=e.once(function(){d.off(a,f);b.apply(this,arguments)});f._callback=b;this.on(a,f,c);return this},off:function(a,b,c){var d,f,l,g,i,m,h,j;if(!this._events||!n(this,"off",a,[b,c]))return this;if(!a&&!b&&!c)return this._events={},this;g=a?[a]:e.keys(this._events);i=0;for(m=g.length;i<m;i++)if(a=g[i],d=this._events[a]){l=[];if(b||
+c){h=0;for(j=d.length;h<j;h++)f=d[h],(b&&b!==(f.callback._callback||f.callback)||c&&c!==f.context)&&l.push(f)}this._events[a]=l}return this},trigger:function(a){if(!this._events)return this;var b=r.call(arguments,1);if(!n(this,"trigger",a,b))return this;var c=this._events[a],d=this._events.all;c&&t(this,c,b);d&&t(this,d,arguments);return this},listenTo:function(a,b,c){var d=this._listeners||(this._listeners={}),f=a._listenerId||(a._listenerId=e.uniqueId("l"));d[f]=a;a.on(b,c||this,this);return this},
+stopListening:function(a,b,c){var d=this._listeners;if(d){if(a)a.off(b,c,this),!b&&!c&&delete d[a._listenerId];else{for(var f in d)d[f].off(null,null,this);this._listeners={}}return this}}};h.bind=h.on;h.unbind=h.off;e.extend(g,h);var o=g.Model=function(a,b){var c,d=a||{};this.cid=e.uniqueId("c");this.changed={};this.attributes={};this._changes=[];b&&b.collection&&(this.collection=b.collection);b&&b.parse&&(d=this.parse(d));(c=e.result(this,"defaults"))&&e.defaults(d,c);this.set(d,{silent:!0});this._currentAttributes=
+e.clone(this.attributes);this._previousAttributes=e.clone(this.attributes);this.initialize.apply(this,arguments)};e.extend(o.prototype,h,{changed:null,idAttribute:"id",initialize:function(){},toJSON:function(){return e.clone(this.attributes)},sync:function(){return g.sync.apply(this,arguments)},get:function(a){return this.attributes[a]},escape:function(a){return e.escape(this.get(a))},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,f;if(null==a)return this;e.isObject(a)?(f=a,c=
+b):(f={})[a]=b;var a=c&&c.silent,l=c&&c.unset;if(!this._validate(f,c))return!1;this.idAttribute in f&&(this.id=f[this.idAttribute]);var g=this.attributes;for(d in f)b=f[d],l?delete g[d]:g[d]=b,this._changes.push(d,b);this._hasComputed=!1;a||this.change(c);return this},unset:function(a,b){return this.set(a,void 0,e.extend({},b,{unset:!0}))},clear:function(a){var b={},c;for(c in this.attributes)b[c]=void 0;return this.set(b,e.extend({},a,{unset:!0}))},fetch:function(a){a=a?e.clone(a):{};void 0===a.parse&&
+(a.parse=!0);var b=this,c=a.success;a.success=function(d){if(!b.set(b.parse(d),a))return false;c&&c(b,d,a)};return this.sync("read",this,a)},save:function(a,b,c){var d,f,g;null==a||e.isObject(a)?(d=a,c=b):null!=a&&((d={})[a]=b);c=c?e.clone(c):{};if(c.wait){if(d&&!this._validate(d,c))return!1;f=e.clone(this.attributes)}a=e.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c)||!d&&!this._validate(null,c))return!1;var q=this,i=c.success;c.success=function(a){g=true;var b=q.parse(a);c.wait&&(b=e.extend(d||
+{},b));if(!q.set(b,c))return false;i&&i(q,a,c)};b=this.isNew()?"create":c.patch?"patch":"update";"patch"==b&&(c.attrs=d);b=this.sync(b,this,c);!g&&c.wait&&(this.clear(a),this.set(f,a));return b},destroy:function(a){var a=a?e.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};a.success=function(f){(a.wait||b.isNew())&&d();c&&c(b,f,a)};if(this.isNew())return a.success(),!1;var f=this.sync("delete",this,a);a.wait||d();return f},url:function(){var a=e.result(this,"urlRoot")||
+e.result(this.collection,"url")||u();return this.isNew()?a:a+("/"===a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){var b=this._changing;this._changing=!0;var c=this._computeChanges(!0);this._pending=!!c.length;for(var d=c.length-2;0<=d;d-=2)this.trigger("change:"+c[d],this,c[d+1],a);if(b)return this;for(;this._pending;)this._pending=!1,this.trigger("change",
+this,a),this._previousAttributes=e.clone(this.attributes);this._changing=!1;return this},hasChanged:function(a){this._hasComputed||this._computeChanges();return null==a?!e.isEmpty(this.changed):e.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?e.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,f;for(f in a)if(!e.isEqual(d[f],b=a[f]))(c||(c={}))[f]=b;return c},_computeChanges:function(a){this.changed={};for(var b={},c=[],d=this._currentAttributes,f=this._changes,
+e=f.length-2;0<=e;e-=2){var g=f[e],i=f[e+1];b[g]||(b[g]=!0,d[g]!==i&&(this.changed[g]=i,a&&(c.push(g,i),d[g]=i)))}a&&(this._changes=[]);this._hasComputed=!0;return c},previous:function(a){return null==a||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return e.clone(this._previousAttributes)},_validate:function(a,b){if(!this.validate)return!0;var a=e.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error&&b.error(this,c,b);this.trigger("error",
+this,c,b);return!1}});var p=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);void 0!==b.comparator&&(this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,e.extend({silent:!0},b))};e.extend(p.prototype,h,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},sync:function(){return g.sync.apply(this,arguments)},add:function(a,b){var c,d,f,g,h=b&&b.at,i=null==(b&&b.sort)?!0:b.sort,a=e.isArray(a)?
+a.slice():[a];for(c=a.length-1;0<=c;c--)(d=this._prepareModel(a[c],b))?(a[c]=d,(f=null!=d.id&&this._byId[d.id])||this._byCid[d.cid]?(b&&(b.merge&&f)&&(f.set(d.attributes,b),g=i),a.splice(c,1)):(d.on("all",this._onModelEvent,this),this._byCid[d.cid]=d,null!=d.id&&(this._byId[d.id]=d))):(this.trigger("error",this,a[c],b),a.splice(c,1));a.length&&(g=i);this.length+=a.length;c=[null!=h?h:this.models.length,0];z.apply(c,a);A.apply(this.models,c);g&&(this.comparator&&null==h)&&this.sort({silent:!0});if(b&&
+b.silent)return this;for(;d=a.shift();)d.trigger("add",d,this,b);return this},remove:function(a,b){var c,d,f,g;b||(b={});a=e.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],f=this.indexOf(g),this.models.splice(f,1),this.length--,b.silent||(b.index=f,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,e.extend({at:this.length},b));return a},pop:function(a){var b=
+this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,e.extend({at:0},b));return a},shift:function(a){var b=this.at(0);this.remove(b,a);return b},slice:function(a,b){return this.models.slice(a,b)},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]||this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return e.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},
+sort:function(a){if(!this.comparator)throw Error("Cannot sort a set without a comparator");e.isString(this.comparator)||1===this.comparator.length?this.models=this.sortBy(this.comparator,this):this.models.sort(e.bind(this.comparator,this));(!a||!a.silent)&&this.trigger("sort",this,a);return this},pluck:function(a){return e.invoke(this.models,"get",a)},update:function(a,b){var c,d,f,g,h=[],i=[],m={},j=this.model.prototype.idAttribute,b=e.extend({add:!0,merge:!0,remove:!0},b);b.parse&&(a=this.parse(a));
+e.isArray(a)||(a=a?[a]:[]);if(b.add&&!b.remove)return this.add(a,b);d=0;for(f=a.length;d<f;d++)c=a[d],g=this.get(c.id||c.cid||c[j]),b.remove&&g&&(m[g.cid]=!0),(b.add&&!g||b.merge&&g)&&h.push(c);if(b.remove){d=0;for(f=this.models.length;d<f;d++)c=this.models[d],m[c.cid]||i.push(c)}i.length&&this.remove(i,b);h.length&&this.add(h,b);return this},reset:function(a,b){b||(b={});b.parse&&(a=this.parse(a));for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);b.previousModels=this.models;
+this._reset();a&&this.add(a,e.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?e.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d){b[a.update?"update":"reset"](d,a);c&&c(b,d,a)};return this.sync("read",this,a)},create:function(a,b){var c=this,b=b?e.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(a,b,e){e.wait&&c.add(a,e);d&&d(a,b,e)};a.save(null,b);return a},
+parse:function(a){return a},clone:function(){return new this.constructor(this.models)},chain:function(){return e(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){if(a instanceof o)return a.collection||(a.collection=this),a;b||(b={});b.collection=this;var c=new this.model(a,b);return!c._validate(a,b)?!1:c},_removeReference:function(a){this===a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,
+b,c,d){("add"===a||"remove"===a)&&c!==this||("destroy"===a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],null!=b.id&&(this._byId[b.id]=b)),this.trigger.apply(this,arguments))}});e.each("forEach each map collect reduce foldl inject reduceRight foldr find detect filter select reject every all some any include contains invoke max min sortedIndex toArray size first head take initial rest tail last without indexOf shuffle lastIndexOf isEmpty".split(" "),
+function(a){p.prototype[a]=function(){var b=r.call(arguments);b.unshift(this.models);return e[a].apply(e,b)}});e.each(["groupBy","countBy","sortBy"],function(a){p.prototype[a]=function(b,c){var d=e.isFunction(b)?b:function(a){return a.get(b)};return e[a](this.models,d,c)}});var v=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/\((.*?)\)/g,C=/:\w+/g,D=/\*\w+/g,E=/[\-{}\[\]+?.,\\\^$|#\s]/g;e.extend(v.prototype,h,{initialize:function(){},
+route:function(a,b,c){e.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,e.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b);return this},_bindRoutes:function(){if(this.routes)for(var a,b=e.keys(this.routes);null!=(a=b.pop());)this.route(a,this.routes[a])},_routeToRegExp:function(a){a=a.replace(E,"\\$&").replace(B,
+"(?:$1)?").replace(C,"([^/]+)").replace(D,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var j=g.History=function(){this.handlers=[];e.bindAll(this,"checkUrl");"undefined"!==typeof window&&(this.location=window.location,this.history=window.history)},w=/^[#\/]|\s+$/g,F=/^\/+|\/+$/g,G=/msie [\w.]+/,H=/\/$/;j.started=!1;e.extend(j.prototype,h,{interval:50,getHash:function(a){return(a=(a||this).location.href.match(/#(.*)$/))?a[1]:""},getFragment:function(a,
+b){if(null==a)if(this._hasPushState||!this._wantsHashChange||b){var a=this.location.pathname,c=this.root.replace(H,"");a.indexOf(c)||(a=a.substr(c.length))}else a=this.getHash();return a.replace(w,"")},start:function(a){if(j.started)throw Error("Backbone.history has already been started");j.started=!0;this.options=e.extend({},{root:"/"},this.options,a);this.root=this.options.root;this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||
+!this.history||!this.history.pushState);var a=this.getFragment(),b=document.documentMode,b=G.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b);this.root=("/"+this.root+"/").replace(F,"/");b&&this._wantsHashChange&&(this.iframe=g.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a));this._hasPushState?g.$(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?g.$(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&
+(this._checkUrlInterval=setInterval(this.checkUrl,this.interval));this.fragment=a;a=this.location;b=a.pathname.replace(/[^\/]$/,"$&/")===this.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+this.location.search+"#"+this.fragment),!0;this._wantsPushState&&(this._hasPushState&&b&&a.hash)&&(this.fragment=this.getHash().replace(w,""),this.history.replaceState({},document.title,this.root+this.fragment+
+a.search));if(!this.options.silent)return this.loadUrl()},stop:function(){g.$(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);j.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a===this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a===this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},
+loadUrl:function(a){var b=this.fragment=this.getFragment(a);return e.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!j.started)return!1;if(!b||!0===b)b={trigger:b};a=this.getFragment(a||"");if(this.fragment!==a){this.fragment=a;var c=this.root+a;if(this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,c);else if(this._wantsHashChange)this._updateHash(this.location,a,b.replace),this.iframe&&a!==this.getFragment(this.getHash(this.iframe))&&
+(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,a,b.replace));else return this.location.assign(c);b.trigger&&this.loadUrl(a)}},_updateHash:function(a,b,c){c?(c=a.href.replace(/(javascript:|#).*$/,""),a.replace(c+"#"+b)):a.hash="#"+b}});g.history=new j;var x=g.View=function(a){this.cid=e.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},I=/^(\S+)\s*(.*)$/,J="model collection el id attributes className tagName events".split(" ");
+e.extend(x.prototype,h,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},make:function(a,b,c){a=document.createElement(a);b&&g.$(a).attr(b);null!=c&&g.$(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof g.$?a:g.$(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=e.result(this,
+"events"))){this.undelegateEvents();for(var b in a){var c=a[b];e.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(I),f=d[1],d=d[2],c=e.bind(c,this),f=f+(".delegateEvents"+this.cid);""===d?this.$el.bind(f,c):this.$el.delegate(d,f,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=e.extend({},e.result(this,"options"),a));e.extend(this,e.pick(a,J));this.options=a},_ensureElement:function(){if(this.el)this.setElement(e.result(this,
+"el"),!1);else{var a=e.extend({},e.result(this,"attributes"));this.id&&(a.id=e.result(this,"id"));this.className&&(a["class"]=e.result(this,"className"));this.setElement(this.make(e.result(this,"tagName"),a),!1)}}});var K={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=K[a];e.defaults(c||(c={}),{emulateHTTP:g.emulateHTTP,emulateJSON:g.emulateJSON});var f={type:d,dataType:"json"};c.url||(f.url=e.result(b,"url")||u());if(null==c.data&&b&&("create"===
+a||"update"===a||"patch"===a))f.contentType="application/json",f.data=JSON.stringify(c.attrs||b.toJSON(c));c.emulateJSON&&(f.contentType="application/x-www-form-urlencoded",f.data=f.data?{model:f.data}:{});if(c.emulateHTTP&&("PUT"===d||"DELETE"===d||"PATCH"===d)){f.type="POST";c.emulateJSON&&(f.data._method=d);var h=c.beforeSend;c.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d);if(h)return h.apply(this,arguments)}}"GET"!==f.type&&!c.emulateJSON&&(f.processData=!1);var j=c.success;
+c.success=function(a,d,e){j&&j(a,d,e);b.trigger("sync",b,a,c)};var i=c.error;c.error=function(a){i&&i(b,a,c);b.trigger("error",b,a,c)};a=g.ajax(e.extend(f,c));b.trigger("request",b,a,c);return a};g.ajax=function(){return g.$.ajax.apply(g.$,arguments)};o.extend=p.extend=v.extend=x.extend=j.extend=function(a,b){var c=this,d;d=a&&e.has(a,"constructor")?a.constructor:function(){c.apply(this,arguments)};e.extend(d,c,b);var f=function(){this.constructor=d};f.prototype=c.prototype;d.prototype=new f;a&&e.extend(d.prototype,
+a);d.__super__=c.prototype;return d};var u=function(){throw Error('A "url" property or function must be specified');}}).call(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/jquery.min.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.2 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(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;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}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=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,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=m.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.7.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.add(a);return this},eq:function(a){a=+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(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");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!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(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;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(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(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},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,"ms-").replace(v,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(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.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:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([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&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=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,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.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.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),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,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=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},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.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}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.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,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?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}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,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.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,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);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),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 z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
+a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.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]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),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]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.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!!m(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 b<c[3]-0},gt:function(a,b,c){return b>c[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=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&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=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null: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=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=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(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.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:[]}},o.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&&(o.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 href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[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}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.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 m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-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)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));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(S(c[0])||S(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);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).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 V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},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){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):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
+.clean(arguments);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.clean(arguments));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){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?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,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.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,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),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&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.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("<div>").append(c.replace(bM,"")).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||bN.test(this.nodeName)||bH.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(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(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?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},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},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),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>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),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.Callbacks("once memory"),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=bG.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.add,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(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.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]!=="*"?", "+bW+"; 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=bZ(bT,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){if(s<2)w(-1,z);else throw 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)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.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(cd,l),b.url===j&&(e&&(k=k.replace(cd,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 ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,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,ce&&delete cg[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);try{m.text=h.responseText}catch(a){}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=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.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=cx.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&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/jquery.mousewheel.min.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,12 @@
+/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
+ * Licensed under the MIT License (LICENSE.txt).
+ *
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
+ *
+ * Version: 3.0.6
+ *
+ * Requires: 1.2.2+
+ */
+(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=b.length;a;)this.removeEventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery)
Binary file server/src/main/webapp/static/lib/paper.js has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/underscore-min.js Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,32 @@
+// Underscore.js 1.3.3
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
+c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
+g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,
+c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&&
+a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
+c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
+a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
+function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&
+(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
+j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,
+0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,
+e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
+i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<=
+1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=
+i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=
+g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));
+return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
+c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
+function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
+b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
+b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
+function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
+u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
+b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
+this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectSyncsRepositoryTest.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,156 @@
+package org.iri_research.renkan.test.repositories;
+
+
+import java.util.ArrayList;
+
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.ProjectSync;
+import org.iri_research.renkan.repositories.ProjectSyncsRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("repositories-context.xml")
+public class ProjectSyncsRepositoryTest {
+
+ private Logger logger = LoggerFactory.getLogger(ProjectSyncsRepositoryTest.class);
+
+ @Autowired
+ private ProjectsRepository projectRepository;
+
+ @Autowired
+ private ProjectSyncsRepository projectSyncsRepository;
+
+
+ private ArrayList<Project> testProjects = new ArrayList<Project>();
+
+ public ProjectSyncsRepositoryTest() {
+ }
+
+ @Before
+ public void setup() {
+
+ logger.debug("Setup");
+ ArrayList<Project> pl = new ArrayList<Project>();
+ pl.add(new Project(null, "test1", "desc1", "http://localhost:8080/rest/projects/id1"));
+ pl.add(new Project(null, "test2", "desc2", "http://localhost:8080/rest/projects/id2"));
+ logger.debug("Setup : new Project ");
+ for(Project p: projectRepository.save(pl)) {
+ this.testProjects.add(p);
+ }
+ }
+
+ @After
+ public void teardown() {
+ logger.debug("Teardown");
+ projectRepository.deleteAll();
+ projectSyncsRepository.deleteAll();
+ }
+
+
+ @Test
+ public void testGetCollection() {
+ String collectionName = this.projectSyncsRepository.getCollection().getName();
+
+ Assert.assertEquals("The collection name should be projectSyncs", "projectSyncs", collectionName);
+
+ }
+
+ @Test
+ public void testGetProjectSync() throws RenkanException {
+
+ Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+ String data = "{\"example\":\"this is an example\"}";
+
+ ProjectSync ps = projectSyncsRepository.getProjectSync(data, p);
+
+ ps = this.projectSyncsRepository.save(ps);
+
+
+ ps = this.projectSyncsRepository.findOne(ps.getId());
+
+ Assert.assertNotNull(ps);
+ Assert.assertEquals(data, ps.getData());
+
+ }
+
+
+ @Test
+ public void testGetProjectSyncRevision() throws RenkanException {
+
+ Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+ String data = "{\"example\":\"this is an example\"}";
+
+ ProjectSync ps = projectSyncsRepository.getProjectSync(data, p);
+
+ ps = this.projectSyncsRepository.save(ps);
+ ps = this.projectSyncsRepository.findOne(ps.getId());
+
+ p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+ Assert.assertNotNull(ps.getProject());
+ Assert.assertEquals(p.getId(), ps.getProject().getId());
+ Assert.assertEquals("Revision of the project sync mustbe one less tha the rev counter pf the project", p.getRevCounter()-1, ps.getRevision());
+
+ Assert.assertEquals("Revision of the project sync mustbe one less tha the rev counter of its project", ps.getProject().getRevCounter()-1, ps.getRevision());
+
+ }
+
+ @Test(expected=RenkanException.class)
+ public void testGetProjectSyncExceptionNullProject() throws RenkanException {
+
+ String data = "{\"example\":\"this is an example\"}";
+ Project p = null;
+ ProjectSync ps = projectSyncsRepository.getProjectSync(data, p);
+
+ // shold never be executed.
+ Assert.assertNull(ps);
+ }
+
+ @Test(expected=RenkanException.class)
+ public void testGetProjectSyncExceptionNullId() throws RenkanException {
+
+ String data = "{\"example\":\"this is an example\"}";
+ String project_id = null;
+ ProjectSync ps = projectSyncsRepository.getProjectSync(data, project_id);
+
+ // shold never be executed.
+ Assert.assertNull(ps);
+ }
+
+ @Test(expected=RenkanException.class)
+ public void testGetProjectSyncExceptionEmptyId() throws RenkanException {
+
+ String data = "{\"example\":\"this is an example\"}";
+ String project_id = "";
+ ProjectSync ps = projectSyncsRepository.getProjectSync(data, project_id);
+
+ // shold never be executed.
+ Assert.assertNull(ps);
+ }
+
+ @Test(expected=RenkanException.class)
+ public void testGetProjectSyncExceptionBadId() throws RenkanException {
+
+ String data = "{\"example\":\"this is an example\"}";
+ String project_id = "BAD_ID";
+ ProjectSync ps = projectSyncsRepository.getProjectSync(data, project_id);
+
+ // shold never be executed.
+ Assert.assertNull(ps);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,111 @@
+package org.iri_research.renkan.test.repositories;
+
+
+import java.util.ArrayList;
+
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("repositories-context.xml")
+public class ProjectsRepositoryTest {
+
+ private Logger logger = LoggerFactory.getLogger(ProjectsRepositoryTest.class);
+
+ @Autowired
+ private ProjectsRepository projectRepository;
+
+ private ArrayList<Project> testProjects = new ArrayList<Project>();
+
+ public ProjectsRepositoryTest() {
+ }
+
+ @Before
+ public void setup() {
+
+ logger.debug("Setup");
+ ArrayList<Project> pl = new ArrayList<Project>();
+ pl.add(new Project(null, "test1", "desc1", "http://localhost:8080/rest/projects/id1"));
+ pl.add(new Project(null, "test2", "desc2", "http://localhost:8080/rest/projects/id2"));
+ logger.debug("Setup : new Project ");
+ for(Project p: projectRepository.save(pl)) {
+ this.testProjects.add(p);
+ }
+ }
+
+ @After
+ public void teardown() {
+ logger.debug("Teardown");
+ projectRepository.deleteAll();
+ }
+
+ @Test
+ public void testInitialRevCounter() {
+
+ Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+ Assert.assertEquals("Initial rev counter should be 1", 1, p.getRevCounter());
+ }
+
+ @Test
+ public void testIncrementRevCounter() {
+
+ int revCounter = projectRepository.getRevCounter(this.testProjects.get(0).getId());
+ Assert.assertEquals("After 1 call rev counter should be 1", 1, revCounter);
+ revCounter = projectRepository.getRevCounter(this.testProjects.get(0).getId());
+ Assert.assertEquals("After 2 calls rev counter should be 2", 2, revCounter);
+
+ for(int i=0; i<10; i++) {
+ revCounter = projectRepository.getRevCounter(this.testProjects.get(0).getId());
+ }
+
+ Assert.assertEquals("After 10 more calls rev counter should be 12", 12, revCounter);
+
+ Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+ Assert.assertEquals("next rev counter should be 13", 13, p.getRevCounter());
+
+ p = projectRepository.findOne(this.testProjects.get(1).getId());
+
+ Assert.assertEquals("other project next rev counter should be 1", 1, p.getRevCounter());
+
+ }
+
+
+ @Test
+ public void testIncrementNonExisting() {
+
+ int revCounter = projectRepository.getRevCounter("aaaa");
+ Assert.assertEquals("Rev counter non existing == -1", -1, revCounter);
+
+ }
+
+ @Test
+ public void testIncrementNull() {
+
+ int revCounter = projectRepository.getRevCounter(null);
+ Assert.assertEquals("Rev counter null == -1", -1, revCounter);
+
+ }
+
+ @Test
+ public void testIncrementEmpty() {
+
+ int revCounter = projectRepository.getRevCounter("");
+ Assert.assertEquals("Rev counter empty == -1", -1, revCounter);
+
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/resources/log4j.xml Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n"/>
+ </layout>
+ </appender>
+ <logger name="org.iri_research.renkan">
+ <level value="DEBUG" />
+ </logger>
+ <logger name="org.eclipse.jetty.util.log">
+ <level value="INFO" />
+ </logger>
+ <logger name="org.springframework.test">
+ <level value="DEBUG" />
+ </logger>
+ <root>
+ <priority value ="WARN" />
+ <appender-ref ref="console" />
+ </root>
+ <!--
+log4j.rootCategory=INFO, stdout
+
+log4j.appender.stdout=org.springframework.data.document.mongodb.log4j.MongoLog4jAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
+log4j.appender.stdout.host = localhost
+log4j.appender.stdout.port = 27017
+log4j.appender.stdout.database = logs
+log4j.appender.stdout.collectionPattern = %X{year}%X{month}
+log4j.appender.stdout.applicationId = my.application
+log4j.appender.stdout.warnOrHigherWriteConcern = FSYNC_SAFE
+
+log4j.category.org.apache.activemq=ERROR
+log4j.category.org.springframework.batch=DEBUG
+log4j.category.org.springframework.data.document.mongodb=DEBUG
+log4j.category.org.springframework.transaction=INFO
+-->
+
+</log4j:configuration>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/resources/org/iri_research/renkan/test/repositories/mongo-config.xml Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:jpa="http://www.springframework.org/schema/data/jpa"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/data/mongo
+ http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/data/jpa
+ http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
+ <!-- Default bean name is 'mongo' -->
+ <mongo:mongo host="localhost" port="27017"/>
+
+ <!-- Offers convenience methods and automatic mapping between MongoDB JSON documents and your domain classes. -->
+ <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
+ <constructor-arg ref="mongo"/>
+ <constructor-arg value="renkan_test"/>
+ <property name="writeResultChecking" value="EXCEPTION"/>
+ </bean>
+
+ <mongo:repositories base-package="org.iri_research.renkan" factory-class="org.iri_research.renkan.repositories.RenkanRepositoryFactoryBean" />
+
+</beans>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/resources/org/iri_research/renkan/test/repositories/repositories-context.xml Mon Dec 31 13:37:31 2012 +0100
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+ <!-- Activates various annotations to be detected in bean classes -->
+ <context:annotation-config />
+
+ <!-- Configures the annotation-driven Spring MVC Controller programming model.
+ Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
+
+ <!-- Loads MongoDB configuraton -->
+ <import resource="mongo-config.xml"/>
+
+ <!--bean id="bayeuxServer" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
+ <property name="options">
+ <map>
+ <entry key="logLevel" value="3" />
+ <entry key="timeout" value="15000" />
+ </map>
+ </property>
+ </bean-->
+ <bean id="springConfigurer"
+ class="org.iri_research.renkan.coweb.SpringConfigurer"
+ factory-method="getInstance" />
+
+ <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
+ For example @Controller and @Service. Make sure to set the correct base-package-->
+ <context:component-scan base-package="org.iri_research.renkan.rest" />
+ <context:component-scan base-package="org.iri_research.renkan.coweb" />
+
+</beans>
\ No newline at end of file