Initial commit
authorKostas Papadimitriou <kpap@grnet.gr>
Wed, 22 Feb 2012 16:05:50 +0000 (18:05 +0200)
committerKostas Papadimitriou <kpap@grnet.gr>
Wed, 22 Feb 2012 16:05:50 +0000 (18:05 +0200)
86 files changed:
cloudcms/__init__.py [new file with mode: 0644]
cloudcms/admin.py [new file with mode: 0644]
cloudcms/astakos_cms.py [new file with mode: 0644]
cloudcms/cms.py [new file with mode: 0644]
cloudcms/common_settings.py [new file with mode: 0644]
cloudcms/content.py [new file with mode: 0644]
cloudcms/context_processors.py [new file with mode: 0644]
cloudcms/migrate/__init__.py [new file with mode: 0644]
cloudcms/migrate/cloudcmsblog/0001_initial.py [new file with mode: 0644]
cloudcms/migrate/cloudcmsblog/__init__.py [new file with mode: 0644]
cloudcms/migrate/medialibrary/0001_initial.py [new file with mode: 0644]
cloudcms/migrate/medialibrary/__init__.py [new file with mode: 0644]
cloudcms/migrate/page/0001_initial.py [new file with mode: 0644]
cloudcms/migrate/page/__init__.py [new file with mode: 0644]
cloudcms/models.py [new file with mode: 0644]
cloudcms/static/cloudcms/css/home-icon.png [new file with mode: 0644]
cloudcms/static/cloudcms/css/okeanos.css [new file with mode: 0644]
cloudcms/static/cloudcms/css/servicesbar.css [new file with mode: 0644]
cloudcms/static/cloudcms/css/styles.css [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/border1.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/border2.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomCenter.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomLeft.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomRight.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleLeft.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleRight.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderTopCenter.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderTopLeft.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/ie6/borderTopRight.png [new file with mode: 0644]
cloudcms/static/cloudcms/images/colorbox/loading.gif [new file with mode: 0644]
cloudcms/static/cloudcms/images/loading.gif [new file with mode: 0644]
cloudcms/static/cloudcms/js/bootstrap-tooltip.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/colorbox/README.md [new file with mode: 0644]
cloudcms/static/cloudcms/js/colorbox/jquery.colorbox.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/form-errors.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/jquery-1.7.1.min.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/jquery.cookie.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/jquery.infieldlabel.js [new file with mode: 0755]
cloudcms/static/cloudcms/js/jquery.labelify.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/modernizr-2.0.6.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/servicesbar.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/twitter/ba-linkify.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/twitter/jquery.timeago.js [new file with mode: 0644]
cloudcms/static/cloudcms/js/twitter/jquery.twitter.js [new file with mode: 0644]
cloudcms/static/cloudcms/less/bootstrap.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/cloudbox.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/django_forms.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/forms.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/mixins.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/patterns.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/reset.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/scaffolding.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/servicesbar.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/styles.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/tables.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/type.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/variables.less [new file with mode: 0644]
cloudcms/static/cloudcms/less/xtra.less [new file with mode: 0644]
cloudcms/templates/cms/base.html [new file with mode: 0644]
cloudcms/templates/cms/pages/about.html [new file with mode: 0644]
cloudcms/templates/cms/pages/blog.html [new file with mode: 0644]
cloudcms/templates/cms/pages/intro.html [new file with mode: 0644]
cloudcms/templates/cms/pages/onecol.html [new file with mode: 0644]
cloudcms/templates/cms/pages/page.html [new file with mode: 0644]
cloudcms/templates/cms/pages/twocolwide.html [new file with mode: 0644]
cloudcms/templates/content/about_block.html [new file with mode: 0644]
cloudcms/templates/content/login_form.html [new file with mode: 0644]
cloudcms/templates/content/section/block.html [new file with mode: 0644]
cloudcms/templates/content/twitter_feed.html [new file with mode: 0644]
cloudcms/templates/content/videosection.html [new file with mode: 0644]
cloudcms/templates/form_render.html [new file with mode: 0644]
cloudcms/tests.py [new file with mode: 0644]
cloudcms/urls.py [new file with mode: 0644]
cloudcms/views.py [new file with mode: 0644]
cloudcmsblog/__init__.py [new file with mode: 0644]
cloudcmsblog/admin.py [new file with mode: 0644]
cloudcmsblog/models.py [new file with mode: 0644]
cloudcmsblog/navigation_extensions.py [new file with mode: 0644]
cloudcmsblog/sitemap.py [new file with mode: 0644]
cloudcmsblog/templates/cloudcmsblog/archive.html [new file with mode: 0644]
cloudcmsblog/templates/cloudcmsblog/detail.html [new file with mode: 0644]
cloudcmsblog/tests.py [new file with mode: 0644]
cloudcmsblog/urls.py [new file with mode: 0644]
cloudcmsblog/views.py [new file with mode: 0644]
fabfile.py [new file with mode: 0644]
setup.py [new file with mode: 0644]

diff --git a/cloudcms/__init__.py b/cloudcms/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcms/admin.py b/cloudcms/admin.py
new file mode 100644 (file)
index 0000000..37f2f92
--- /dev/null
@@ -0,0 +1,10 @@
+from django.contrib import admin
+from cloudcms import models
+
+
+class ApplicationAdmin(admin.ModelAdmin):
+    raw_id_fields = ('logo', )
+
+
+admin.site.register(models.Application, ApplicationAdmin)
+
diff --git a/cloudcms/astakos_cms.py b/cloudcms/astakos_cms.py
new file mode 100644 (file)
index 0000000..958534f
--- /dev/null
@@ -0,0 +1,16 @@
+from feincms.module.page.extensions.navigation import NavigationExtension, \
+        PagePretender
+from django.utils.translation import ugettext as _
+
+ASTAKOS_NAVIGATION = (
+        ('Profile', 'astakos-profile'),
+        ('Change password', 'astakos-profile')
+)
+
+class AstakosNavigationExtension(NavigationExtension):
+    name = _('astakos pages')
+
+    def children(self, page, **kwargs):
+        from django.core.urlresolvers import reverse
+        for title, url in dict(ASTAKOS_NAVIGATION).iteritems():
+            yield PagePretender(title=title, url='/im/profile')
diff --git a/cloudcms/cms.py b/cloudcms/cms.py
new file mode 100644 (file)
index 0000000..a11cb40
--- /dev/null
@@ -0,0 +1,121 @@
+import mptt
+
+from django import forms
+from django.db import models
+from django.utils.text import capfirst
+from django.utils.translation import ugettext_lazy as _
+
+from feincms.module.page.models import Page
+from feincms.content.raw.models import RawContent
+from feincms.content.richtext.models import RichTextContent
+from feincms.content.image.models import ImageContent
+from feincms.content.application.models import ApplicationContent
+from feincms.module.page.extensions.navigation import NavigationExtension, \
+        PagePretender
+from feincms.content.application.models import reverse
+from feincms.content.medialibrary.v2 import MediaFileContent
+from feincms.content.section.models import SectionContent
+from feincms.content.table.models import TableContent
+from feincms.content.template.models import TemplateContent
+from feincms.content.video.models import VideoContent
+from feincms.content.richtext.models import RichTextContent
+
+from cloudcmsblog.models import Entry
+from cloudcms.content import *
+
+Page.register_extensions(
+    'changedate',
+    'datepublisher',
+    'translations',
+    'seo',
+    'symlinks',
+    'navigation',
+    'sites',
+    'titles'
+)
+
+# Feincms Page templates declaration
+TEMPLATES = [{
+    'key': 'basic',
+    'title': 'Basic 2 columns template',
+    'path': 'cms/pages/page.html',
+    'regions': (
+        ('main', 'Main region'),
+        ('sidebar', 'Sidebar', 'inherited'),
+        ),
+    },
+    {
+    'key': 'twocolwide',
+    'title': 'Basic 2 columns template (wider)',
+    'path': 'cms/pages/twocolwide.html',
+    'regions': (
+        ('main', 'Main region'),
+        ('sidebar', 'Sidebar', 'inherited'),
+        ),
+    },
+    {
+    'key': 'intro',
+    'title': 'Intro page Template',
+    'path': 'cms/pages/intro.html',
+    'regions': (
+        ('main', 'Main region'),
+        ('sidebar', 'Sidebar', 'inherited'),
+        ),
+    },
+    {
+    'key': 'singlecol',
+    'title': 'Basic 1 column template',
+    'path': 'cms/pages/onecol.html',
+    'regions': (
+        ('main', 'Main region'),
+        ),
+    },
+    {
+    'key': 'blog',
+    'title': 'Blog template',
+    'path': 'cms/pages/blog.html',
+    'regions': (
+        ('main', 'Main region'),
+        ('sidebar', 'Sidebar', 'inherited'),
+        ),
+    },
+]
+
+# register templates
+map(Page.register_templates, TEMPLATES)
+
+Page.create_content_type(RichTextContent)
+Page.create_content_type(RawContent)
+Page.create_content_type(SectionContent, TYPE_CHOICES=(('block', 'Block'),))
+Page.create_content_type(TemplateContent)
+Page.create_content_type(TwitterFeed)
+Page.create_content_type(VideoContent)
+Page.create_content_type(VideoSection)
+Page.create_content_type(ImageContent, POSITION_CHOICES=(
+    ('default', 'Default position'),
+))
+Page.create_content_type(MediaFileContent, TYPE_CHOICES=(
+  ('lightbox', 'lightbox'),
+  ('download', 'as download')
+))
+Page.create_content_type(ApplicationContent, APPLICATIONS=(
+    ('cloudcmsblog', 'Cloud blog', {'urls': 'cloudcmsblog.urls'}),))
+
+
+# cloudcms specific content registration
+Page.create_content_type(LoginForm)
+Page.create_content_type(AboutBlock)
+
+
+# Feincms specific registrations for our blog entry model
+Entry.register_regions(
+    ('main', _('Main content area')),
+    ('sidebar', _('Right column')),
+)
+Entry.create_content_type(RichTextContent, cleanse=False, regions=('main',))
+Entry.create_content_type(TemplateContent)
+Entry.create_content_type(VideoContent)
+Entry.create_content_type(TwitterFeed)
+Entry.create_content_type(RawContent)
+Entry.create_content_type(SectionContent, TYPE_CHOICES=(('block', 'Block'),))
+
diff --git a/cloudcms/common_settings.py b/cloudcms/common_settings.py
new file mode 100644 (file)
index 0000000..57ad6fa
--- /dev/null
@@ -0,0 +1,46 @@
+CLOUDCMS_APPS = [
+    'cloudcms',
+    'cloudcmsblog',
+    'pagination',
+
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.admin',
+    'django.contrib.admindocs',
+    'django.contrib.sitemaps',
+
+    'south',
+
+    'feincms',
+    'feincms.module.page',
+    'feincms.module.medialibrary',
+]
+CLOUDCMS_MIDDLEWARES = [
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'pagination.middleware.PaginationMiddleware'
+]
+CLOUDCMS_STATICFILES = {
+        'cloudcms': '',
+        'feincms': ''
+}
+CLOUDCMS_CONTEXT_PROCESSORS = [
+    'cloudcms.context_processors.application',
+    'cloudcms.context_processors.cloudbar'
+]
+
+
+# Django settings
+SOUTH_MIGRATION_MODULES = {
+    'page': 'cloudcms.migrate.page',
+    'medialibrary': 'cloudcms.migrate.medialibrary',
+    'cloudcmsblog': 'cloudcms.migrate.cloudcmsblog',
+}
+
+CLOUDBAR_URL = '/static/im/cloudbar/cloudbar.js'
+CLOUDBAR_ACTIVE_SERVICE = 'okeanos_cms'
diff --git a/cloudcms/content.py b/cloudcms/content.py
new file mode 100644 (file)
index 0000000..81ac790
--- /dev/null
@@ -0,0 +1,142 @@
+from django.contrib.markup.templatetags.markup import textile
+from django.db import models
+from django import forms
+from django.conf import settings
+from django.utils.translation import ugettext_lazy as _
+from django.template.loader import render_to_string
+from django.utils import simplejson
+
+from feincms.admin.editor import ItemEditorForm
+from feincms.module.page.models import Page
+from feincms.module.medialibrary.models import MediaFile
+from feincms.content.medialibrary.models import MediaFileWidget
+from feincms.module.medialibrary.fields import MediaFileForeignKey
+
+
+DEFAULT_JQ_TWITTER_URL = settings.MEDIA_URL + 'cloudcms/' + 'js/' + 'twitter/' + \
+                        'jquery.twitter.js'
+DEFAULT_LINKIFY_URL = settings.MEDIA_URL + 'cloudcms/' + 'js/' + 'twitter/' + \
+                        'ba-linkify.js'
+DEFAULT_JQ_TIMEAGO_URL = settings.MEDIA_URL + 'cloudcms/' + 'js/' + 'twitter/' + \
+                        'jquery.timeago.js'
+JQUERY_TWITTER_URL = getattr(settings, "JQUERY_TWITTER_URL",
+        DEFAULT_JQ_TWITTER_URL)
+LINKIFY_JS_URL = getattr(settings, "LINKIFY_JS_URL",
+        DEFAULT_LINKIFY_URL)
+JQUERY_TIMEAGO_URL = getattr(settings, "JQUERY_TIMEAGO_URL",
+        DEFAULT_JQ_TIMEAGO_URL)
+
+
+class VideoSection(models.Model):
+    section_title = models.CharField(max_length=200, blank=True)
+    video_title = models.CharField(max_length=200, blank=True)
+    video_link = models.CharField(max_length=200, blank=True)
+    video_width = models.PositiveIntegerField(default=700)
+    video_height = models.PositiveIntegerField(default=550)
+    image = MediaFileForeignKey(MediaFile, blank=True, null=True,
+    related_name="as_image_for_video_section")
+    image_hover = MediaFileForeignKey(MediaFile, blank=True, null=True,
+            related_name="as_hover_for_video_section")
+    alt_text = models.TextField(null=True, blank=True)
+    extra_url_params = models.CharField(max_length=200, blank=True)
+
+    class Meta:
+        abstract = True
+        verbose_name = _('video section')
+        verbose_name_plural = _('video sections')
+
+    def render(self, **kwargs):
+        return render_to_string(['content/videosection.html'], {'content': self})
+
+
+class TwitterFeed(models.Model):
+    title = models.CharField(max_length=200, blank=True)
+    account = models.CharField(max_length=200, blank=True)
+    nots = models.CharField(max_length=200, help_text="Ugly words", blank=True)
+    query = models.CharField(max_length=200, blank=True,
+            help_text="Filter query")
+    tag = models.CharField(max_length=200, blank=True, help_text="Hashtag")
+    limit = models.PositiveIntegerField(default=10)
+    replies = models.BooleanField(default=True)
+    retweets = models.BooleanField(default=True)
+    avatar = models.BooleanField(default=False)
+    extra_params = models.TextField(blank=True,
+            help_text="Json object to append to "
+                      "JQuery-twitter-plugin settings. Change "
+                      "this only if you know what you are doing.")
+
+    class Meta:
+        abstract = True
+        verbose_name = _('twitter feed')
+        verbose_name_plural = _('twitter feeds')
+
+    @property
+    def media(self):
+        return forms.Media(js=(
+                LINKIFY_JS_URL, JQUERY_TWITTER_URL, JQUERY_TIMEAGO_URL
+            ))
+
+    def js_conf(self):
+        conf = {}
+        if self.account:
+            conf['from'] = self.account
+
+        for f in ['nots', 'query', 'tag', 'limit', 'replies', 'retweets', 'avatar']:
+            if type(getattr(self, f)) == bool:
+                conf[f] = getattr(self, f)
+
+            if getattr(self, f):
+                conf[f] = getattr(self, f)
+
+        xtraconf = {}
+        try:
+            xtraconf = simplejson.loads(self.extra_params)
+        except:
+            pass
+
+        conf.update(xtraconf)
+        return simplejson.dumps(conf)
+
+
+    def render(self, **kwargs):
+        return render_to_string(['content/twitter_feed.html'], {'content': self})
+
+
+class AboutBlock(models.Model):
+
+    title = models.CharField(max_length=200, blank=False)
+    content = models.TextField(blank=False)
+    image = MediaFileForeignKey(MediaFile, blank=True, null=True)
+    image_position = models.CharField(max_length=200,
+            choices=(('top', 'Top'), ('left', 'Left'), ('right', 'Right')))
+    color = models.CharField(max_length=200, blank=False)
+    offset_left = models.IntegerField(null=True, blank=True)
+    offset_top = models.IntegerField(null=True, blank=True)
+
+    class Meta:
+        abstract = True
+        verbose_name = _('about page block')
+        verbose_name_plural = _('about page blocks')
+
+    def render(self, **kwargs):
+        return render_to_string(['content/about_block.html'], {'content': self})
+
+
+class LoginForm(models.Model):
+    """
+    Login form
+    """
+
+    title = models.CharField(_('title'), max_length=200, blank=False)
+    action_url = models.CharField(_('im url'), max_length=100, blank=False)
+    display_forgot_password = models.BooleanField(default=False, null=False)
+    next_url = models.CharField(max_length=255, null=True, blank=True)
+
+    class Meta:
+        abstract = True
+        verbose_name = _('login form')
+        verbose_name_plural = _('login forms')
+
+    def render(self, **kwargs):
+        return render_to_string(['content/login_form.html'], {'content': self})
+
diff --git a/cloudcms/context_processors.py b/cloudcms/context_processors.py
new file mode 100644 (file)
index 0000000..3e4b33c
--- /dev/null
@@ -0,0 +1,17 @@
+from django.conf import settings
+
+from cloudcms.models import Application
+
+def cloudbar(request):
+    return {
+        'CLOUDBAR_BASE_URL': getattr(settings, 'CLOUDBAR_BASE_URL', ''),
+        'CLOUDBAR_ACTIVE_SERVICE': getattr(settings,
+                                    'CLOUDBAR_ACTIVE_SERVICE', 'okeanos_cms'),
+    }
+
+def application(request):
+    try:
+        return {'APP': Application.current()}
+    except:
+        return {'APP': None}
+
diff --git a/cloudcms/migrate/__init__.py b/cloudcms/migrate/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcms/migrate/cloudcmsblog/0001_initial.py b/cloudcms/migrate/cloudcmsblog/0001_initial.py
new file mode 100644 (file)
index 0000000..80f34c1
--- /dev/null
@@ -0,0 +1,337 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding model 'Category'
+        db.create_table('cloudcmsblog_category', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('ordering', self.gf('django.db.models.fields.SmallIntegerField')(default=0)),
+            ('display_on_menu', self.gf('django.db.models.fields.BooleanField')(default=False)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['Category'])
+
+        # Adding model 'CategoryTranslation'
+        db.create_table('cloudcmsblog_categorytranslation', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', to=orm['cloudcmsblog.Category'])),
+            ('language_code', self.gf('django.db.models.fields.CharField')(default='en', max_length=10)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, db_index=True)),
+            ('description', self.gf('django.db.models.fields.CharField')(max_length=250, blank=True)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['CategoryTranslation'])
+
+        # Adding model 'Entry'
+        db.create_table('cloudcmsblog_entry', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('is_featured', self.gf('django.db.models.fields.BooleanField')(default=False)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=100, db_index=True)),
+            ('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='blogentries', to=orm['auth.User'])),
+            ('language', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('intro_text', self.gf('django.db.models.fields.TextField')(max_length=255, blank=True)),
+            ('image', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(to=orm['medialibrary.MediaFile'], null=True, blank=True)),
+            ('published_on', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, null=True, blank=True)),
+            ('last_changed', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['Entry'])
+
+        # Adding M2M table for field application on 'Entry'
+        db.create_table('cloudcmsblog_entry_application', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('entry', models.ForeignKey(orm['cloudcmsblog.entry'], null=False)),
+            ('application', models.ForeignKey(orm['cloudcms.application'], null=False))
+        ))
+        db.create_unique('cloudcmsblog_entry_application', ['entry_id', 'application_id'])
+
+        # Adding M2M table for field categories on 'Entry'
+        db.create_table('cloudcmsblog_entry_categories', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('entry', models.ForeignKey(orm['cloudcmsblog.entry'], null=False)),
+            ('category', models.ForeignKey(orm['cloudcmsblog.category'], null=False))
+        ))
+        db.create_unique('cloudcmsblog_entry_categories', ['entry_id', 'category_id'])
+
+        # Adding model 'RichTextContent'
+        db.create_table('cloudcmsblog_entry_richtextcontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('text', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='richtextcontent_set', to=orm['cloudcmsblog.Entry'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['RichTextContent'])
+
+        # Adding model 'TemplateContent'
+        db.create_table('cloudcmsblog_entry_templatecontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('filename', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='templatecontent_set', to=orm['cloudcmsblog.Entry'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['TemplateContent'])
+
+        # Adding model 'VideoContent'
+        db.create_table('cloudcmsblog_entry_videocontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('video', self.gf('django.db.models.fields.URLField')(max_length=200)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='videocontent_set', to=orm['cloudcmsblog.Entry'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['VideoContent'])
+
+        # Adding model 'TwitterFeed'
+        db.create_table('cloudcmsblog_entry_twitterfeed', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('account', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('nots', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('query', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('tag', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('limit', self.gf('django.db.models.fields.PositiveIntegerField')(default=10)),
+            ('replies', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('retweets', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('avatar', self.gf('django.db.models.fields.BooleanField')(default=False)),
+            ('extra_params', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='twitterfeed_set', to=orm['cloudcmsblog.Entry'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['TwitterFeed'])
+
+        # Adding model 'RawContent'
+        db.create_table('cloudcmsblog_entry_rawcontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('text', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='rawcontent_set', to=orm['cloudcmsblog.Entry'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['RawContent'])
+
+        # Adding model 'SectionContent'
+        db.create_table('cloudcmsblog_entry_sectioncontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('richtext', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sectioncontent_set', to=orm['cloudcmsblog.Entry'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('mediafile', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='cloudcmsblog_sectioncontent_set', null=True, to=orm['medialibrary.MediaFile'])),
+            ('type', self.gf('django.db.models.fields.CharField')(default='block', max_length=10)),
+        ))
+        db.send_create_signal('cloudcmsblog', ['SectionContent'])
+
+
+    def backwards(self, orm):
+        
+        # Deleting model 'Category'
+        db.delete_table('cloudcmsblog_category')
+
+        # Deleting model 'CategoryTranslation'
+        db.delete_table('cloudcmsblog_categorytranslation')
+
+        # Deleting model 'Entry'
+        db.delete_table('cloudcmsblog_entry')
+
+        # Removing M2M table for field application on 'Entry'
+        db.delete_table('cloudcmsblog_entry_application')
+
+        # Removing M2M table for field categories on 'Entry'
+        db.delete_table('cloudcmsblog_entry_categories')
+
+        # Deleting model 'RichTextContent'
+        db.delete_table('cloudcmsblog_entry_richtextcontent')
+
+        # Deleting model 'TemplateContent'
+        db.delete_table('cloudcmsblog_entry_templatecontent')
+
+        # Deleting model 'VideoContent'
+        db.delete_table('cloudcmsblog_entry_videocontent')
+
+        # Deleting model 'TwitterFeed'
+        db.delete_table('cloudcmsblog_entry_twitterfeed')
+
+        # Deleting model 'RawContent'
+        db.delete_table('cloudcmsblog_entry_rawcontent')
+
+        # Deleting model 'SectionContent'
+        db.delete_table('cloudcmsblog_entry_sectioncontent')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'cloudcms.application': {
+            'Meta': {'object_name': 'Application'},
+            'app_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'facebook_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'linked_in_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}),
+            'show_twitter_feed_on_top': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
+        },
+        'cloudcmsblog.category': {
+            'Meta': {'ordering': "['-ordering']", 'object_name': 'Category'},
+            'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'})
+        },
+        'cloudcmsblog.categorytranslation': {
+            'Meta': {'ordering': "['title']", 'object_name': 'CategoryTranslation'},
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsblog.Category']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'cloudcmsblog.entry': {
+            'Meta': {'ordering': "['-published_on']", 'object_name': 'Entry'},
+            'application': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'blogentries'", 'symmetrical': 'False', 'to': "orm['cloudcms.Application']"}),
+            'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'blogentries'", 'to': "orm['auth.User']"}),
+            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'blogentries'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['cloudcmsblog.Category']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}),
+            'intro_text': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'last_changed': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'published_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'cloudcmsblog.rawcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'RawContent', 'db_table': "'cloudcmsblog_entry_rawcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rawcontent_set'", 'to': "orm['cloudcmsblog.Entry']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+        },
+        'cloudcmsblog.richtextcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'RichTextContent', 'db_table': "'cloudcmsblog_entry_richtextcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'richtextcontent_set'", 'to': "orm['cloudcmsblog.Entry']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+        },
+        'cloudcmsblog.sectioncontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'SectionContent', 'db_table': "'cloudcmsblog_entry_sectioncontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'mediafile': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'cloudcmsblog_sectioncontent_set'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectioncontent_set'", 'to': "orm['cloudcmsblog.Entry']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'richtext': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'default': "'block'", 'max_length': '10'})
+        },
+        'cloudcmsblog.templatecontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'TemplateContent', 'db_table': "'cloudcmsblog_entry_templatecontent'"},
+            'filename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'templatecontent_set'", 'to': "orm['cloudcmsblog.Entry']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'cloudcmsblog.twitterfeed': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'TwitterFeed', 'db_table': "'cloudcmsblog_entry_twitterfeed'"},
+            'account': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'avatar': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'extra_params': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'limit': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10'}),
+            'nots': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'twitterfeed_set'", 'to': "orm['cloudcmsblog.Entry']"}),
+            'query': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'replies': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'retweets': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'tag': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'})
+        },
+        'cloudcmsblog.videocontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'VideoContent', 'db_table': "'cloudcmsblog_entry_videocontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videocontent_set'", 'to': "orm['cloudcmsblog.Entry']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'video': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'medialibrary.category': {
+            'Meta': {'ordering': "['parent__title', 'title']", 'object_name': 'Category'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'medialibrary.mediafile': {
+            'Meta': {'object_name': 'MediaFile'},
+            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}),
+            'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+            'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '12'})
+        },
+        'sites.site': {
+            'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
+            'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['cloudcmsblog']
diff --git a/cloudcms/migrate/cloudcmsblog/__init__.py b/cloudcms/migrate/cloudcmsblog/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcms/migrate/medialibrary/0001_initial.py b/cloudcms/migrate/medialibrary/0001_initial.py
new file mode 100644 (file)
index 0000000..e5e1c22
--- /dev/null
@@ -0,0 +1,93 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding model 'Category'
+        db.create_table('medialibrary_category', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='children', null=True, to=orm['medialibrary.Category'])),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=150, db_index=True)),
+        ))
+        db.send_create_signal('medialibrary', ['Category'])
+
+        # Adding model 'MediaFile'
+        db.create_table('medialibrary_mediafile', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=255)),
+            ('type', self.gf('django.db.models.fields.CharField')(max_length=12)),
+            ('created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+            ('copyright', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('file_size', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+        ))
+        db.send_create_signal('medialibrary', ['MediaFile'])
+
+        # Adding M2M table for field categories on 'MediaFile'
+        db.create_table('medialibrary_mediafile_categories', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('mediafile', models.ForeignKey(orm['medialibrary.mediafile'], null=False)),
+            ('category', models.ForeignKey(orm['medialibrary.category'], null=False))
+        ))
+        db.create_unique('medialibrary_mediafile_categories', ['mediafile_id', 'category_id'])
+
+        # Adding model 'MediaFileTranslation'
+        db.create_table('medialibrary_mediafiletranslation', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', to=orm['medialibrary.MediaFile'])),
+            ('language_code', self.gf('django.db.models.fields.CharField')(default='en', max_length=10)),
+            ('caption', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('description', self.gf('django.db.models.fields.TextField')(blank=True)),
+        ))
+        db.send_create_signal('medialibrary', ['MediaFileTranslation'])
+
+
+    def backwards(self, orm):
+        
+        # Deleting model 'Category'
+        db.delete_table('medialibrary_category')
+
+        # Deleting model 'MediaFile'
+        db.delete_table('medialibrary_mediafile')
+
+        # Removing M2M table for field categories on 'MediaFile'
+        db.delete_table('medialibrary_mediafile_categories')
+
+        # Deleting model 'MediaFileTranslation'
+        db.delete_table('medialibrary_mediafiletranslation')
+
+
+    models = {
+        'medialibrary.category': {
+            'Meta': {'ordering': "['parent__title', 'title']", 'object_name': 'Category'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'medialibrary.mediafile': {
+            'Meta': {'object_name': 'MediaFile'},
+            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}),
+            'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+            'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '12'})
+        },
+        'medialibrary.mediafiletranslation': {
+            'Meta': {'object_name': 'MediaFileTranslation'},
+            'caption': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['medialibrary.MediaFile']"})
+        }
+    }
+
+    complete_apps = ['medialibrary']
diff --git a/cloudcms/migrate/medialibrary/__init__.py b/cloudcms/migrate/medialibrary/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcms/migrate/page/0001_initial.py b/cloudcms/migrate/page/0001_initial.py
new file mode 100644 (file)
index 0000000..2bb17c1
--- /dev/null
@@ -0,0 +1,422 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding model 'Page'
+        db.create_table('page_page', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
+            ('rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
+            ('tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
+            ('level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
+            ('active', self.gf('django.db.models.fields.BooleanField')(default=False)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=150, db_index=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='children', null=True, to=orm['page.Page'])),
+            ('in_navigation', self.gf('django.db.models.fields.BooleanField')(default=False)),
+            ('override_url', self.gf('django.db.models.fields.CharField')(max_length=300, blank=True)),
+            ('redirect_to', self.gf('django.db.models.fields.CharField')(max_length=300, blank=True)),
+            ('_cached_url', self.gf('django.db.models.fields.CharField')(default='', max_length=300, db_index=True, blank=True)),
+            ('creation_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
+            ('modification_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
+            ('publication_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2012, 2, 22, 16, 0))),
+            ('publication_end_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+            ('language', self.gf('django.db.models.fields.CharField')(default='en', max_length=10)),
+            ('translation_of', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='translations', null=True, to=orm['page.Page'])),
+            ('meta_keywords', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('meta_description', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('symlinked_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='page_page_symlinks', null=True, to=orm['page.Page'])),
+            ('navigation_extension', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
+            ('site', self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['sites.Site'])),
+            ('_content_title', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('_page_title', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
+            ('template_key', self.gf('django.db.models.fields.CharField')(default='basic', max_length=255)),
+        ))
+        db.send_create_signal('page', ['Page'])
+
+        # Adding model 'RichTextContent'
+        db.create_table('page_page_richtextcontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('text', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='richtextcontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['RichTextContent'])
+
+        # Adding model 'RawContent'
+        db.create_table('page_page_rawcontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('text', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='rawcontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['RawContent'])
+
+        # Adding model 'SectionContent'
+        db.create_table('page_page_sectioncontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('richtext', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sectioncontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('mediafile', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='page_sectioncontent_set', null=True, to=orm['medialibrary.MediaFile'])),
+            ('type', self.gf('django.db.models.fields.CharField')(default='block', max_length=10)),
+        ))
+        db.send_create_signal('page', ['SectionContent'])
+
+        # Adding model 'TemplateContent'
+        db.create_table('page_page_templatecontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('filename', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='templatecontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['TemplateContent'])
+
+        # Adding model 'TwitterFeed'
+        db.create_table('page_page_twitterfeed', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('account', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('nots', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('query', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('tag', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('limit', self.gf('django.db.models.fields.PositiveIntegerField')(default=10)),
+            ('replies', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('retweets', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('avatar', self.gf('django.db.models.fields.BooleanField')(default=False)),
+            ('extra_params', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='twitterfeed_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['TwitterFeed'])
+
+        # Adding model 'VideoContent'
+        db.create_table('page_page_videocontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('video', self.gf('django.db.models.fields.URLField')(max_length=200)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='videocontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['VideoContent'])
+
+        # Adding model 'VideoSection'
+        db.create_table('page_page_videosection', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('section_title', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('video_title', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('video_link', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('video_width', self.gf('django.db.models.fields.PositiveIntegerField')(default=700)),
+            ('video_height', self.gf('django.db.models.fields.PositiveIntegerField')(default=550)),
+            ('image', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(blank=True, related_name='as_image_for_video_section', null=True, to=orm['medialibrary.MediaFile'])),
+            ('image_hover', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(blank=True, related_name='as_hover_for_video_section', null=True, to=orm['medialibrary.MediaFile'])),
+            ('alt_text', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+            ('extra_url_params', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='videosection_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['VideoSection'])
+
+        # Adding model 'ImageContent'
+        db.create_table('page_page_imagecontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='imagecontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('position', self.gf('django.db.models.fields.CharField')(default='default', max_length=10)),
+        ))
+        db.send_create_signal('page', ['ImageContent'])
+
+        # Adding model 'MediaFileContent'
+        db.create_table('page_page_mediafilecontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('mediafile', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(related_name='+', to=orm['medialibrary.MediaFile'])),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='mediafilecontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('type', self.gf('django.db.models.fields.CharField')(default='lightbox', max_length=20)),
+        ))
+        db.send_create_signal('page', ['MediaFileContent'])
+
+        # Adding model 'ApplicationContent'
+        db.create_table('page_page_applicationcontent', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('parameters', self.gf('feincms.contrib.fields.JSONField')(null=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='applicationcontent_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+            ('urlconf_path', self.gf('django.db.models.fields.CharField')(max_length=100)),
+        ))
+        db.send_create_signal('page', ['ApplicationContent'])
+
+        # Adding model 'LoginForm'
+        db.create_table('page_page_loginform', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('action_url', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('display_forgot_password', self.gf('django.db.models.fields.BooleanField')(default=False)),
+            ('next_url', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='loginform_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['LoginForm'])
+
+        # Adding model 'AboutBlock'
+        db.create_table('page_page_aboutblock', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('content', self.gf('django.db.models.fields.TextField')()),
+            ('image', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(to=orm['medialibrary.MediaFile'], null=True, blank=True)),
+            ('image_position', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('color', self.gf('django.db.models.fields.CharField')(max_length=200)),
+            ('offset_left', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+            ('offset_top', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+            ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='aboutblock_set', to=orm['page.Page'])),
+            ('region', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
+        ))
+        db.send_create_signal('page', ['AboutBlock'])
+
+
+    def backwards(self, orm):
+        
+        # Deleting model 'Page'
+        db.delete_table('page_page')
+
+        # Deleting model 'RichTextContent'
+        db.delete_table('page_page_richtextcontent')
+
+        # Deleting model 'RawContent'
+        db.delete_table('page_page_rawcontent')
+
+        # Deleting model 'SectionContent'
+        db.delete_table('page_page_sectioncontent')
+
+        # Deleting model 'TemplateContent'
+        db.delete_table('page_page_templatecontent')
+
+        # Deleting model 'TwitterFeed'
+        db.delete_table('page_page_twitterfeed')
+
+        # Deleting model 'VideoContent'
+        db.delete_table('page_page_videocontent')
+
+        # Deleting model 'VideoSection'
+        db.delete_table('page_page_videosection')
+
+        # Deleting model 'ImageContent'
+        db.delete_table('page_page_imagecontent')
+
+        # Deleting model 'MediaFileContent'
+        db.delete_table('page_page_mediafilecontent')
+
+        # Deleting model 'ApplicationContent'
+        db.delete_table('page_page_applicationcontent')
+
+        # Deleting model 'LoginForm'
+        db.delete_table('page_page_loginform')
+
+        # Deleting model 'AboutBlock'
+        db.delete_table('page_page_aboutblock')
+
+
+    models = {
+        'medialibrary.category': {
+            'Meta': {'ordering': "['parent__title', 'title']", 'object_name': 'Category'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'medialibrary.mediafile': {
+            'Meta': {'object_name': 'MediaFile'},
+            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}),
+            'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+            'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '12'})
+        },
+        'page.aboutblock': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'AboutBlock', 'db_table': "'page_page_aboutblock'"},
+            'color': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'content': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}),
+            'image_position': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'offset_left': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'offset_top': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'aboutblock_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'page.applicationcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'ApplicationContent', 'db_table': "'page_page_applicationcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parameters': ('feincms.contrib.fields.JSONField', [], {'null': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'applicationcontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'urlconf_path': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'page.imagecontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'ImageContent', 'db_table': "'page_page_imagecontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'imagecontent_set'", 'to': "orm['page.Page']"}),
+            'position': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '10'}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'page.loginform': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'LoginForm', 'db_table': "'page_page_loginform'"},
+            'action_url': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'display_forgot_password': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'next_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'loginform_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'page.mediafilecontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'MediaFileContent', 'db_table': "'page_page_mediafilecontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'mediafile': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'related_name': "'+'", 'to': "orm['medialibrary.MediaFile']"}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'mediafilecontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'default': "'lightbox'", 'max_length': '20'})
+        },
+        'page.page': {
+            'Meta': {'ordering': "['tree_id', 'lft']", 'object_name': 'Page'},
+            '_cached_url': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'db_index': 'True', 'blank': 'True'}),
+            '_content_title': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            '_page_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}),
+            'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'meta_description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'meta_keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'modification_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'navigation_extension': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'override_url': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['page.Page']"}),
+            'publication_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 2, 22, 16, 0)'}),
+            'publication_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+            'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'site': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['sites.Site']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}),
+            'symlinked_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'page_page_symlinks'", 'null': 'True', 'to': "orm['page.Page']"}),
+            'template_key': ('django.db.models.fields.CharField', [], {'default': "'basic'", 'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'translation_of': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'translations'", 'null': 'True', 'to': "orm['page.Page']"}),
+            'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
+        },
+        'page.rawcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'RawContent', 'db_table': "'page_page_rawcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rawcontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+        },
+        'page.richtextcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'RichTextContent', 'db_table': "'page_page_richtextcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'richtextcontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+        },
+        'page.sectioncontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'SectionContent', 'db_table': "'page_page_sectioncontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'mediafile': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'page_sectioncontent_set'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectioncontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'richtext': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'default': "'block'", 'max_length': '10'})
+        },
+        'page.templatecontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'TemplateContent', 'db_table': "'page_page_templatecontent'"},
+            'filename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'templatecontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'page.twitterfeed': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'TwitterFeed', 'db_table': "'page_page_twitterfeed'"},
+            'account': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'avatar': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'extra_params': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'limit': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10'}),
+            'nots': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'twitterfeed_set'", 'to': "orm['page.Page']"}),
+            'query': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'replies': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'retweets': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'tag': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'})
+        },
+        'page.videocontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'VideoContent', 'db_table': "'page_page_videocontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videocontent_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'video': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+        },
+        'page.videosection': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'VideoSection', 'db_table': "'page_page_videosection'"},
+            'alt_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'extra_url_params': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_image_for_video_section'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}),
+            'image_hover': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_hover_for_video_section'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videosection_set'", 'to': "orm['page.Page']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'section_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'video_height': ('django.db.models.fields.PositiveIntegerField', [], {'default': '550'}),
+            'video_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'video_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'video_width': ('django.db.models.fields.PositiveIntegerField', [], {'default': '700'})
+        },
+        'sites.site': {
+            'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
+            'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['page']
diff --git a/cloudcms/migrate/page/__init__.py b/cloudcms/migrate/page/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcms/models.py b/cloudcms/models.py
new file mode 100644 (file)
index 0000000..d07f83a
--- /dev/null
@@ -0,0 +1,37 @@
+from django.db import models
+from django.conf import settings
+from django.contrib.sites import models as sites_models
+
+from feincms.module.medialibrary.fields import MediaFileForeignKey
+from feincms.module.medialibrary.models import MediaFile
+
+
+class Application(models.Model):
+    code = models.CharField('Identifier', max_length=100, null=False, blank=False,
+            help_text="Just a codename of the application, to be used in "\
+                    "several places where no free text is allowed"\
+                    "(e.g. urls, paths, etc)")
+    title = models.CharField(max_length=255, null=False, blank=False,
+            help_text="The title of the application")
+
+    logo = MediaFileForeignKey(MediaFile, blank=True, null=True)
+    site = models.ForeignKey(sites_models.Site)
+    app_url = models.URLField(help_text="The url of the application UI (not "\
+            "the cms", verify_exists=False, blank=True, null=True)
+
+    linked_in_username = models.CharField(max_length=255, blank=True)
+    twitter_username = models.CharField(max_length=255, blank=True)
+    facebook_username = models.CharField(max_length=255, blank=True)
+
+    show_twitter_feed_on_top = models.BooleanField(default=False)
+
+    @classmethod
+    def current(cls):
+        return cls.objects.get(site__pk=settings.SITE_ID)
+
+    def __unicode__(self):
+        return self.title
+
+# hook for feincms configuration, is this appropriate place ??? who knows
+from cloudcms.cms import *
+
diff --git a/cloudcms/static/cloudcms/css/home-icon.png b/cloudcms/static/cloudcms/css/home-icon.png
new file mode 100644 (file)
index 0000000..a371d6f
Binary files /dev/null and b/cloudcms/static/cloudcms/css/home-icon.png differ
diff --git a/cloudcms/static/cloudcms/css/okeanos.css b/cloudcms/static/cloudcms/css/okeanos.css
new file mode 100644 (file)
index 0000000..596abaa
--- /dev/null
@@ -0,0 +1,4 @@
+body {
+    background-color: #4085A5;
+    background-position: 20px 34px;
+}
diff --git a/cloudcms/static/cloudcms/css/servicesbar.css b/cloudcms/static/cloudcms/css/servicesbar.css
new file mode 100644 (file)
index 0000000..fb5ddae
--- /dev/null
@@ -0,0 +1,297 @@
+/*!
+ * Bootstrap @VERSION
+ *
+ * Copyright 2011 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ * Date: @DATE
+ */
+/* Reset.less
+ * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here      that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc).
+ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
+html, body {
+  margin: 0;
+  padding: 0;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+dd,
+dl,
+dt,
+li,
+ol,
+ul,
+fieldset,
+form,
+label,
+legend,
+button,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-weight: normal;
+  font-style: normal;
+  font-size: 100%;
+  line-height: 1;
+  font-family: inherit;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+ol, ul {
+  list-style: none;
+}
+q:before,
+q:after,
+blockquote:before,
+blockquote:after {
+  content: "";
+}
+html {
+  overflow-y: scroll;
+  font-size: 100%;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%;
+}
+a:focus {
+  outline: thin dotted;
+}
+a:hover, a:active {
+  outline: 0;
+}
+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;
+}
+sub, sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup {
+  top: -0.5em;
+}
+sub {
+  bottom: -0.25em;
+}
+img {
+  border: 0;
+  -ms-interpolation-mode: bicubic;
+}
+button,
+input,
+select,
+textarea {
+  font-size: 100%;
+  margin: 0;
+  vertical-align: baseline;
+  *vertical-align: middle;
+}
+button, input {
+  line-height: normal;
+  *overflow: visible;
+}
+button::-moz-focus-inner, input::-moz-focus-inner {
+  border: 0;
+  padding: 0;
+}
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  cursor: pointer;
+  -webkit-appearance: button;
+}
+input[type="search"] {
+  -webkit-appearance: textfield;
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+textarea {
+  overflow: auto;
+  vertical-align: top;
+}
+/* Variables.less
+ * Variables to customize the look and feel of Bootstrap
+ * ----------------------------------------------------- */
+/* Mixins.less
+ * Snippets of reusable CSS to develop faster and keep code readable
+ * ----------------------------------------------------------------- */
+.makeRow {
+  zoom: 1;
+  margin-left: -22px;
+}
+.makeRow:before, .makeRow:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.makeRow:after {
+  clear: both;
+}
+.button {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  background-color: #3582ac;
+  color: #ffffff;
+  border: none;
+  padding: 0.8em 22px;
+  font-size: 1em;
+}
+.button:hover {
+  background-color: #f89a1c;
+}
+.servicesbar {
+  font-family: arial, sans-serif;
+  font-size: 11px;
+  letter-spacing: 0px;
+  zoom: 1;
+  color: #ccc;
+  z-index: 1000;
+  border-bottom: 1px solid #444;
+  background-color: #000000;
+  position: relative;
+}
+.servicesbar:before, .servicesbar:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.servicesbar:after {
+  clear: both;
+}
+.servicesbar a {
+  color: #e6e6e6;
+  text-decoration: none;
+  display: block;
+  float: left;
+  padding: 11px;
+}
+.servicesbar a:hover {
+  background-color: #444;
+}
+.servicesbar a.active {
+  font-weight: bold;
+  background-color: #333;
+}
+.servicesbar .services {
+  zoom: 1;
+}
+.servicesbar .services:before, .servicesbar .services:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.servicesbar .services:after {
+  clear: both;
+}
+.servicesbar .profile {
+  margin-top: -34px;
+  zoom: 1;
+  text-align: right;
+  min-width: 200px;
+  background-color: #000000;
+  zoom: 1;
+  position: absolute;
+  right: 0;
+  float: right;
+}
+.servicesbar .profile:before, .servicesbar .profile:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.servicesbar .profile:after {
+  clear: both;
+}
+.servicesbar .profile a {
+  float: none;
+}
+.servicesbar .profile ul {
+  display: none;
+}
+.servicesbar .profile ul li {
+  width: 100%;
+  border-bottom: 1px solid #444;
+  background-color: #333;
+}
+.servicesbar .profile ul li a {
+  float: none;
+  display: block;
+}
+.servicesbar .profile:hover {
+  background-color: #222;
+}
+.servicesbar .profile:hover ul {
+  display: block;
+}
+.servicesbar .profile:before, .servicesbar .profile:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.servicesbar .profile:after {
+  clear: both;
+}
diff --git a/cloudcms/static/cloudcms/css/styles.css b/cloudcms/static/cloudcms/css/styles.css
new file mode 100644 (file)
index 0000000..8006685
--- /dev/null
@@ -0,0 +1,1213 @@
+/*!
+ * Bootstrap @VERSION
+ *
+ * Copyright 2011 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ * Date: @DATE
+ */
+/* Reset.less
+ * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here      that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc).
+ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
+html, body {
+  margin: 0;
+  padding: 0;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+dd,
+dl,
+dt,
+li,
+ol,
+ul,
+fieldset,
+form,
+label,
+legend,
+button,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-weight: normal;
+  font-style: normal;
+  font-size: 100%;
+  line-height: 1;
+  font-family: inherit;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+ol, ul {
+  list-style: none;
+}
+q:before,
+q:after,
+blockquote:before,
+blockquote:after {
+  content: "";
+}
+html {
+  overflow-y: scroll;
+  font-size: 100%;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%;
+}
+a:focus {
+  outline: thin dotted;
+}
+a:hover, a:active {
+  outline: 0;
+}
+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;
+}
+sub, sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup {
+  top: -0.5em;
+}
+sub {
+  bottom: -0.25em;
+}
+img {
+  border: 0;
+  -ms-interpolation-mode: bicubic;
+}
+button,
+input,
+select,
+textarea {
+  font-size: 100%;
+  margin: 0;
+  vertical-align: baseline;
+  *vertical-align: middle;
+}
+button, input {
+  line-height: normal;
+  *overflow: visible;
+}
+button::-moz-focus-inner, input::-moz-focus-inner {
+  border: 0;
+  padding: 0;
+}
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  cursor: pointer;
+  -webkit-appearance: button;
+}
+input[type="search"] {
+  -webkit-appearance: textfield;
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+textarea {
+  overflow: auto;
+  vertical-align: top;
+}
+/* Variables.less
+ * Variables to customize the look and feel of Bootstrap
+ * ----------------------------------------------------- */
+/* Mixins.less
+ * Snippets of reusable CSS to develop faster and keep code readable
+ * ----------------------------------------------------------------- */
+.makeRow {
+  zoom: 1;
+  margin-left: -22px;
+}
+.makeRow:before, .makeRow:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.makeRow:after {
+  clear: both;
+}
+.button {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  background-color: #3582ac;
+  color: #ffffff;
+  border: none;
+  padding: 0.8em 22px;
+  font-size: 1em;
+}
+.button:hover {
+  background-color: #f89a1c;
+}
+/*addon to style django forms rendered with as_p filter*/
+/*
+ * Tables.less
+ * Tables for, you guessed it, tabular data
+ * ---------------------------------------- */
+table {
+  width: 100%;
+  margin-bottom: 22px;
+  padding: 0;
+  font-size: 14px;
+  border-collapse: collapse;
+}
+table th, table td {
+  padding: 10px 10px 9px;
+  line-height: 22px;
+  text-align: left;
+}
+table th {
+  padding-top: 9px;
+  font-weight: bold;
+  vertical-align: middle;
+}
+table td {
+  vertical-align: top;
+  border-top: 1px solid #ddd;
+}
+table tbody th {
+  border-top: 1px solid #ddd;
+  vertical-align: top;
+}
+.condensed-table th, .condensed-table td {
+  padding: 5px 5px 4px;
+}
+.bordered-table {
+  border: 1px solid #ddd;
+  border-collapse: separate;
+  *border-collapse: collapse;
+  /* IE7, collapse table to remove spacing */
+
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+}
+.bordered-table th + th, .bordered-table td + td, .bordered-table th + td {
+  border-left: 1px solid #ddd;
+}
+.bordered-table thead tr:first-child th:first-child, .bordered-table tbody tr:first-child td:first-child {
+  -webkit-border-radius: 4px 0 0 0;
+  -moz-border-radius: 4px 0 0 0;
+  border-radius: 4px 0 0 0;
+}
+.bordered-table thead tr:first-child th:last-child, .bordered-table tbody tr:first-child td:last-child {
+  -webkit-border-radius: 0 4px 0 0;
+  -moz-border-radius: 0 4px 0 0;
+  border-radius: 0 4px 0 0;
+}
+.bordered-table tbody tr:last-child td:first-child {
+  -webkit-border-radius: 0 0 0 4px;
+  -moz-border-radius: 0 0 0 4px;
+  border-radius: 0 0 0 4px;
+}
+.bordered-table tbody tr:last-child td:last-child {
+  -webkit-border-radius: 0 0 4px 0;
+  -moz-border-radius: 0 0 4px 0;
+  border-radius: 0 0 4px 0;
+}
+table .span1 {
+  width: 40px;
+}
+table .span2 {
+  width: 120px;
+}
+table .span3 {
+  width: 200px;
+}
+table .span4 {
+  width: 280px;
+}
+table .span5 {
+  width: 360px;
+}
+table .span6 {
+  width: 440px;
+}
+table .span7 {
+  width: 520px;
+}
+table .span8 {
+  width: 600px;
+}
+table .span9 {
+  width: 680px;
+}
+table .span10 {
+  width: 760px;
+}
+table .span11 {
+  width: 840px;
+}
+table .span12 {
+  width: 920px;
+}
+table .span13 {
+  width: 1000px;
+}
+table .span14 {
+  width: 1080px;
+}
+table .span15 {
+  width: 1160px;
+}
+table .span16 {
+  width: 1240px;
+}
+.zebra-striped tbody tr:nth-child(odd) td, .zebra-striped tbody tr:nth-child(odd) th {
+  background-color: #f9f9f9;
+}
+.zebra-striped tbody tr:hover td, .zebra-striped tbody tr:hover th {
+  background-color: #f5f5f5;
+}
+table .header {
+  cursor: pointer;
+}
+table .header:after {
+  content: "";
+  float: right;
+  margin-top: 7px;
+  border-width: 0 4px 4px;
+  border-style: solid;
+  border-color: #000 transparent;
+  visibility: hidden;
+}
+table .headerSortUp, table .headerSortDown {
+  background-color: rgba(141, 192, 219, 0.25);
+  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
+}
+table .header:hover:after {
+  visibility: visible;
+}
+table .headerSortDown:after, table .headerSortDown:hover:after {
+  visibility: visible;
+  filter: alpha(opacity=60);
+  -khtml-opacity: 0.6;
+  -moz-opacity: 0.6;
+  opacity: 0.6;
+}
+table .headerSortUp:after {
+  border-bottom: none;
+  border-left: 4px solid transparent;
+  border-right: 4px solid transparent;
+  border-top: 4px solid #000;
+  visibility: visible;
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+  filter: alpha(opacity=60);
+  -khtml-opacity: 0.6;
+  -moz-opacity: 0.6;
+  opacity: 0.6;
+}
+table .blue {
+  color: #3582ac;
+  border-bottom-color: #3582ac;
+}
+table .headerSortUp.blue, table .headerSortDown.blue {
+  background-color: #c1ddec;
+}
+table .green {
+  color: #46a546;
+  border-bottom-color: #46a546;
+}
+table .headerSortUp.green, table .headerSortDown.green {
+  background-color: #cdeacd;
+}
+table .red {
+  color: #9d261d;
+  border-bottom-color: #9d261d;
+}
+table .headerSortUp.red, table .headerSortDown.red {
+  background-color: #f4c8c5;
+}
+table .yellow {
+  color: #ffc40d;
+  border-bottom-color: #ffc40d;
+}
+table .headerSortUp.yellow, table .headerSortDown.yellow {
+  background-color: #fff6d9;
+}
+table .orange {
+  color: #f89406;
+  border-bottom-color: #f89406;
+}
+table .headerSortUp.orange, table .headerSortDown.orange {
+  background-color: #fee9cc;
+}
+table .purple {
+  color: #7a43b6;
+  border-bottom-color: #7a43b6;
+}
+table .headerSortUp.purple, table .headerSortDown.purple {
+  background-color: #e2d5f0;
+}
+/*
+    ColorBox Core Style:
+    The following CSS is consistent between example themes and should not be altered.
+*/
+#colorbox, #cboxOverlay, #cboxWrapper {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 9999;
+  overflow: hidden;
+}
+#cboxOverlay {
+  position: fixed;
+  width: 100%;
+  height: 100%;
+}
+#cboxMiddleLeft, #cboxBottomLeft {
+  clear: left;
+}
+#cboxContent {
+  position: relative;
+}
+#cboxLoadedContent {
+  overflow: auto;
+}
+#cboxTitle {
+  margin: 0;
+}
+#cboxLoadingOverlay, #cboxLoadingGraphic {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+#cboxPrevious,
+#cboxNext,
+#cboxClose,
+#cboxSlideshow {
+  cursor: pointer;
+}
+.cboxPhoto {
+  float: left;
+  margin: auto;
+  border: 0;
+  display: block;
+}
+.cboxIframe {
+  width: 100%;
+  height: 100%;
+  display: block;
+  border: 0;
+}
+/* 
+    User Style:
+    Change the following styles to modify the appearance of ColorBox.  They are
+    ordered & tabbed in a way that represents the nesting of the generated HTML.
+*/
+#cboxOverlay {
+  background: #222;
+}
+#cboxTopLeft {
+  width: 25px;
+  height: 25px;
+  background: url(../images/colorbox/border1.png) no-repeat 0 0;
+}
+#cboxTopCenter {
+  height: 25px;
+  background: url(../images/colorbox/border1.png) repeat-x 0 -50px;
+}
+#cboxTopRight {
+  width: 25px;
+  height: 25px;
+  background: url(../images/colorbox/border1.png) no-repeat -25px 0;
+}
+#cboxBottomLeft {
+  width: 25px;
+  height: 25px;
+  background: url(../images/colorbox/border1.png) no-repeat 0 -25px;
+}
+#cboxBottomCenter {
+  height: 25px;
+  background: url(../images/colorbox/border1.png) repeat-x 0 -75px;
+}
+#cboxBottomRight {
+  width: 25px;
+  height: 25px;
+  background: url(../images/colorbox/border1.png) no-repeat -25px -25px;
+}
+#cboxMiddleLeft {
+  width: 25px;
+  background: url(../images/colorbox/border2.png) repeat-y 0 0;
+}
+#cboxMiddleRight {
+  width: 25px;
+  background: url(../images/colorbox/border2.png) repeat-y -25px 0;
+}
+#cboxContent {
+  background: #fff;
+  overflow: hidden;
+}
+.cboxIframe {
+  background: #fff;
+}
+#cboxError {
+  padding: 50px;
+  border: 1px solid #ccc;
+}
+#cboxLoadedContent {
+  margin-bottom: 20px;
+}
+#cboxTitle {
+  position: absolute;
+  bottom: 0px;
+  left: 0;
+  text-align: center;
+  width: 100%;
+  color: #999;
+}
+#cboxCurrent {
+  position: absolute;
+  bottom: 0px;
+  left: 100px;
+  color: #999;
+}
+#cboxSlideshow {
+  position: absolute;
+  bottom: 0px;
+  right: 42px;
+  color: #444;
+}
+#cboxPrevious {
+  position: absolute;
+  bottom: 0px;
+  left: 0;
+  color: #444;
+}
+#cboxNext {
+  position: absolute;
+  bottom: 0px;
+  left: 63px;
+  color: #444;
+}
+#cboxLoadingOverlay {
+  background: #ffffff url(../images/colorbox/loading.gif) no-repeat 5px 5px;
+}
+#cboxClose {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  display: block;
+  color: #444;
+}
+/*
+  The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
+  when an alpha filter (opacity change) is set on the element or ancestor element.  This style is not applied to or needed in IE9.
+  See: http://jacklmoore.com/notes/ie-transparency-problems/
+*/
+body {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+}
+.topbar {
+  background-color: #cfcdc7;
+}
+.topbar .head {
+  float: left;
+  padding: 6px;
+}
+.topbar .links {
+  zoom: 1;
+  float: right;
+}
+.topbar .links:before, .topbar .links:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.topbar .links:after {
+  clear: both;
+}
+.topbar .links a {
+  color: #000000;
+  text-decoration: none;
+  display: block;
+  float: left;
+  margin-left: 10px;
+  padding: 12px;
+}
+.topbar .links a:hover {
+  background-color: #1a1a1a;
+  color: #ffffff;
+}
+section a,
+p a,
+form a,
+.section a {
+  color: #000000;
+  text-decoration: none;
+  border-bottom: 1px solid #f89a1c;
+}
+section a:hover,
+p a:hover,
+form a:hover,
+.section a:hover {
+  color: #f89a1c;
+}
+section a.noborder,
+p a.noborder,
+form a.noborder,
+.section a.noborder {
+  border: none;
+}
+section a em,
+p a em,
+form a em,
+.section a em {
+  color: #3582ac;
+}
+a.simple {
+  border: none;
+}
+a.action {
+  color: #f89a1c;
+  border-bottom: none;
+}
+a img {
+  border-bottom: none;
+}
+.content-border {
+  border-right: 1px solid #808080;
+  border-left: 1px solid #808080;
+}
+.hidden {
+  display: none !important;
+}
+.container, .topbar, .footer {
+  width: 796px;
+  margin-left: auto;
+  margin-right: auto;
+  zoom: 1;
+  border-right: 1px solid #808080;
+  border-left: 1px solid #808080;
+  padding: 0 82px;
+}
+.container:before,
+.topbar:before,
+.footer:before,
+.container:after,
+.topbar:after,
+.footer:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.container:after, .topbar:after, .footer:after {
+  clear: both;
+}
+.container {
+  padding-bottom: 82px;
+  background-color: #ffffff;
+}
+div.header {
+  position: relative;
+  margin-top: 88px;
+  margin-bottom: 22px;
+}
+div.header h1 {
+  color: #cfcdc7;
+  display: inline;
+  font-size: 2.3em;
+  border-bottom: 1px solid #cfcdc7;
+  padding-bottom: 3px;
+}
+.mainlogo img {
+  margin-left: -10px;
+}
+.footer {
+  border-bottom: 1px solid #808080;
+  border-top: 1px solid #a6a6a6;
+  padding-top: 22px;
+  padding-bottom: 22px;
+}
+ul.inline {
+  zoom: 1;
+}
+ul.inline:before, ul.inline:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+ul.inline:after {
+  clear: both;
+}
+ul.inline li {
+  display: block;
+  float: left;
+  margin-right: 1em;
+}
+.mainnav.quicknav {
+  position: absolute;
+  right: 0;
+  top: -57.2px;
+  margin: 0;
+}
+.mainnav.quicknav li {
+  margin-right: 0;
+  margin-left: 1em;
+}
+.mainnav {
+  font-size: 1.2em;
+}
+.mainnav.subnav {
+  margin-bottom: -22px;
+}
+.mainnav.subnav li {
+  margin-top: 1.2em;
+}
+.mainnav li {
+  margin-top: 66px;
+}
+.mainnav li.active a {
+  /*border-bottom: 1px solid @linkColor;*/
+
+  border-bottom: none;
+  color: #f89a1c;
+}
+.mainnav a {
+  color: #000000;
+  text-decoration: none;
+}
+.mainnav a:hover {
+  border-bottom: 1px solid #f89a1c;
+}
+.mainnav a.active, .mainnav a:active {
+  border-bottom: 1px solid #f89a1c;
+  color: #f89a1c;
+}
+.page {
+  zoom: 1;
+  margin-left: -22px;
+  margin-top: 132px;
+  font-size: 1.1em;
+}
+.page:before, .page:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.page:after {
+  clear: both;
+}
+.page .page-inner {
+  position: relative;
+}
+.maincol {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 388px;
+}
+.maincol.wide {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 470px;
+}
+.maincol.full {
+  zoom: 1;
+  margin-left: -22px;
+  margin-left: 0;
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 798px;
+}
+.maincol.full:before, .maincol.full:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.maincol.full:after {
+  clear: both;
+}
+.appbar {
+  height: 30px;
+  background-color: #3582ac;
+}
+.rightcol {
+  margin-left: 511px;
+  width: 306px;
+}
+.rightcol.narrow {
+  margin-left: 593px;
+  width: 224px;
+}
+.rightcol input[type=text], .rightcol input[type=password] {
+  width: 273px;
+}
+/* generic form styles */
+input, textarea {
+  background-color: #ffffff;
+  color: #808080;
+  border-color: #000000;
+}
+#forms .input, #forms input {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  border: 1px solid #808080;
+  margin-bottom: -1px;
+  padding: 0.8em;
+  padding-left: 1.5em;
+  z-index: 2;
+}
+#forms .input:focus, #forms input:focus {
+  position: relative;
+  border: 1px solid #000;
+  z-index: 100;
+}
+#forms .input:focus label, #forms input:focus label {
+  z-index: 300;
+}
+.altcol {
+  background-color: #c3c3b9 !important;
+}
+.altcol:hover {
+  background-color: #f89a1c !important;
+}
+.section {
+  margin-bottom: 66px;
+}
+.section.positioned {
+  margin-bottom: 0;
+}
+.section.positioned .content {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 306px;
+}
+.section.positioned.withimg .img {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 306px;
+}
+.section.positioned.withimg img {
+  float: left;
+}
+.section.positioned h3 {
+  font-size: 1.2em;
+  margin-bottom: 22px;
+}
+.section.positioned .text {
+  color: #000000;
+}
+.section .left, .section .right {
+  width: 50%;
+  float: left;
+}
+.section.imagelist {
+  margin-top: 2em;
+  zoom: 1;
+}
+.section.imagelist:before, .section.imagelist:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.section.imagelist:after {
+  clear: both;
+}
+.section.imagelist img {
+  float: left;
+  margin-right: 4em;
+  vertical-align: middle;
+}
+input[readonly=true] {
+  background-color: #ddd;
+  color: #5e5e5e;
+}
+form.withlabels label {
+  width: 224px;
+  display: block;
+  float: left;
+  padding-top: 1em;
+}
+form.withlabels input[type=text], form.withlabels input[type=password], form.withlabels textarea {
+  width: 224px;
+}
+form.withlabels input[type=text].long, form.withlabels input[type=password].long, form.withlabels textarea.long {
+  width: 224px;
+}
+form.login {
+  margin-bottom: 3em;
+}
+form h2 {
+  color: #000000;
+  margin-bottom: 22px;
+  font-size: 1.1em;
+}
+form h2 span {
+  padding-bottom: 3px;
+}
+form .form-row {
+  position: relative;
+}
+form .form-row.submit {
+  margin-top: 22px;
+}
+form .form-row .extra-link {
+  color: #808080;
+  text-decoration: none;
+  border: none;
+  font-size: 0.8em;
+  margin-top: 1.3em;
+  float: right;
+}
+form.innerlabels label {
+  position: absolute;
+  top: 1em;
+  left: 1.5em;
+  color: #aaa;
+}
+form.innerlabels p {
+  position: relative;
+}
+form textarea,
+form input.text,
+form input[type="text"],
+form input[type="password"] {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  border: 1px solid #808080;
+  margin-bottom: -1px;
+  padding: 0.8em;
+  padding-left: 1.5em;
+  z-index: 2;
+}
+form textarea:focus,
+form input.text:focus,
+form input[type="text"]:focus,
+form input[type="password"]:focus {
+  position: relative;
+  border: 1px solid #000;
+  z-index: 100;
+}
+form textarea:focus label,
+form input.text:focus label,
+form input[type="text"]:focus label,
+form input[type="password"]:focus label {
+  z-index: 300;
+}
+form input.submit, form input[type="submit"] {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  background-color: #3582ac;
+  color: #ffffff;
+  border: none;
+  padding: 0.8em 22px;
+  font-size: 1em;
+}
+form input.submit:hover, form input[type="submit"]:hover {
+  background-color: #f89a1c;
+}
+form .with-errors input, form .with-errors textarea, form .with-errors select {
+  color: #9d261d;
+}
+form .with-errors label {
+  color: #e4776f;
+}
+.form-error {
+  background-color: #9d261d;
+  color: #fff;
+  font-size: 0.8em;
+  padding: 5px 5px;
+}
+.form-errors.all .form-error {
+  position: relative;
+  border-radius: 0;
+  margin-bottom: 1.3em;
+  padding: 0.5em;
+}
+div.form-stacked {
+  margin-bottom: 4em;
+}
+.section h2 {
+  font-size: 1.1em;
+  margin-bottom: 33px;
+}
+.section h2 a {
+  color: #4085A6;
+  border: none;
+  line-height: 1.3em;
+}
+.section p {
+  line-height: 1.7em;
+}
+.messages {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 798px;
+  margin-bottom: 2em;
+  background-color: #ddd;
+}
+.messages li {
+  padding: 1em;
+}
+.messages li.success {
+  background-color: #46a546;
+  color: #ffffff;
+}
+.messages li.error {
+  background-color: #9d261d;
+  color: #ffffff;
+}
+.messages li.warning {
+  background-color: #ffc40d;
+  color: #000000;
+}
+.service-desc {
+  margin-top: 4em;
+}
+table td.consumed {
+  color: #9d261d;
+}
+table tr.consumed td.consumed {
+  color: #46a546;
+}
+.row {
+  zoom: 1;
+  margin-left: -22px;
+}
+.row:before, .row:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.row:after {
+  clear: both;
+}
+.footer:hover a {
+  color: #808080 !important;
+  -webkit-transition: color 0.15s linear;
+  transition: color 0.15s linear;
+}
+.footer a {
+  color: #b3b3b3;
+  -webkit-transition: color 0.15s linear;
+  transition: color 0.15s linear;
+  text-decoration: none;
+}
+.footer a:hover {
+  color: #000000;
+}
+.footer li {
+  margin-bottom: 11px;
+}
+.footer li.header {
+  margin-bottom: 22px;
+}
+.footer .col {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 306px;
+}
+.footer .col:last-child, .footer .col.last {
+  width: 140px;
+  margin-right: 0;
+}
+.footer .bottom.row .col {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 142px;
+}
+.footer .bottom.row .col:last-child, .footer .bottom.row .col.last {
+  width: 140px;
+  margin-right: 0;
+}
+/*pagination*/
+/*blog styles*/
+.blog-entry {
+  margin-bottom: 66px;
+  zoom: 1;
+  margin-bottom: 44px;
+}
+.blog-entry.positioned {
+  margin-bottom: 0;
+}
+.blog-entry.positioned .content {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 306px;
+}
+.blog-entry.positioned.withimg .img {
+  display: inline;
+  float: left;
+  margin-left: 22px;
+  width: 306px;
+}
+.blog-entry.positioned.withimg img {
+  float: left;
+}
+.blog-entry.positioned h3 {
+  font-size: 1.2em;
+  margin-bottom: 22px;
+}
+.blog-entry.positioned .text {
+  color: #000000;
+}
+.blog-entry .left, .blog-entry .right {
+  width: 50%;
+  float: left;
+}
+.blog-entry.imagelist {
+  margin-top: 2em;
+  zoom: 1;
+}
+.blog-entry.imagelist:before, .blog-entry.imagelist:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.blog-entry.imagelist:after {
+  clear: both;
+}
+.blog-entry.imagelist img {
+  float: left;
+  margin-right: 4em;
+  vertical-align: middle;
+}
+.blog-entry h2 {
+  font-size: 1.1em;
+  margin-bottom: 33px;
+}
+.blog-entry h2 a {
+  color: #4085A6;
+  border: none;
+  line-height: 1.3em;
+}
+.blog-entry p {
+  line-height: 1.7em;
+}
+.blog-entry:before, .blog-entry:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.blog-entry:after {
+  clear: both;
+}
+.blog-entry .title {
+  margin-bottom: 1em;
+  font-size: 1.1em;
+  line-height: 1.4em;
+}
+.blog-entry .media img {
+  border: 1px solid #808080;
+}
+.blog-entry .intro-content, .blog-entry .content {
+  margin-top: 22px;
+}
+.blog-entry .intro-content object, .blog-entry .content object {
+  margin: 22px 0;
+}
+.blog-entry .entry-info {
+  font-size: 0.7em;
+  margin-top: 22px;
+}
+.blog-entry.single .entry-info {
+  margin-top: 0;
+  margin-bottom: 22px;
+}
+.section.twitter-feed .tweet {
+  line-height: 1.3em;
+  font-size: 0.9em;
+  margin-bottom: 22px;
+  color: #808080;
+}
+.section.twitter-feed .tweet .date {
+  display: block;
+  font-size: 0.7em;
+}
+.section.twitter-feed .tweet .date a {
+  text-decoration: none !important;
+  border: none;
+}
+.pagination .page {
+  margin-left: 0;
+}
diff --git a/cloudcms/static/cloudcms/images/colorbox/border1.png b/cloudcms/static/cloudcms/images/colorbox/border1.png
new file mode 100644 (file)
index 0000000..0ddc704
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/border1.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/border2.png b/cloudcms/static/cloudcms/images/colorbox/border2.png
new file mode 100644 (file)
index 0000000..aa62a0b
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/border2.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomCenter.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomCenter.png
new file mode 100644 (file)
index 0000000..12e0e9a
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomCenter.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomLeft.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomLeft.png
new file mode 100644 (file)
index 0000000..b7a474a
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomLeft.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomRight.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomRight.png
new file mode 100644 (file)
index 0000000..6b6cb15
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderBottomRight.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleLeft.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleLeft.png
new file mode 100644 (file)
index 0000000..8d0eb73
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleLeft.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleRight.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleRight.png
new file mode 100644 (file)
index 0000000..d65509e
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderMiddleRight.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopCenter.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopCenter.png
new file mode 100644 (file)
index 0000000..35d8da2
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopCenter.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopLeft.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopLeft.png
new file mode 100644 (file)
index 0000000..ae9bda0
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopLeft.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopRight.png b/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopRight.png
new file mode 100644 (file)
index 0000000..0d88683
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/ie6/borderTopRight.png differ
diff --git a/cloudcms/static/cloudcms/images/colorbox/loading.gif b/cloudcms/static/cloudcms/images/colorbox/loading.gif
new file mode 100644 (file)
index 0000000..602ce3c
Binary files /dev/null and b/cloudcms/static/cloudcms/images/colorbox/loading.gif differ
diff --git a/cloudcms/static/cloudcms/images/loading.gif b/cloudcms/static/cloudcms/images/loading.gif
new file mode 100644 (file)
index 0000000..602ce3c
Binary files /dev/null and b/cloudcms/static/cloudcms/images/loading.gif differ
diff --git a/cloudcms/static/cloudcms/js/bootstrap-tooltip.js b/cloudcms/static/cloudcms/js/bootstrap-tooltip.js
new file mode 100644 (file)
index 0000000..21f2311
--- /dev/null
@@ -0,0 +1,270 @@
+/* ===========================================================
+ * bootstrap-tooltip.js v2.0.0
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ===========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+!function( $ ) {
+
+  "use strict"
+
+ /* TOOLTIP PUBLIC CLASS DEFINITION
+  * =============================== */
+
+  var Tooltip = function ( element, options ) {
+    this.init('tooltip', element, options)
+  }
+
+  Tooltip.prototype = {
+
+    constructor: Tooltip
+
+  , init: function ( type, element, options ) {
+      var eventIn
+        , eventOut
+
+      this.type = type
+      this.$element = $(element)
+      this.options = this.getOptions(options)
+      this.enabled = true
+
+      if (this.options.trigger != 'manual') {
+        eventIn  = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
+        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
+        this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
+        this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
+      }
+
+      this.options.selector ?
+        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+        this.fixTitle()
+    }
+
+  , getOptions: function ( options ) {
+      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
+
+      if (options.delay && typeof options.delay == 'number') {
+        options.delay = {
+          show: options.delay
+        , hide: options.delay
+        }
+      }
+
+      return options
+    }
+
+  , enter: function ( e ) {
+      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+      if (!self.options.delay || !self.options.delay.show) {
+        self.show()
+      } else {
+        self.hoverState = 'in'
+        setTimeout(function() {
+          if (self.hoverState == 'in') {
+            self.show()
+          }
+        }, self.options.delay.show)
+      }
+    }
+
+  , leave: function ( e ) {
+      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+      if (!self.options.delay || !self.options.delay.hide) {
+        self.hide()
+      } else {
+        self.hoverState = 'out'
+        setTimeout(function() {
+          if (self.hoverState == 'out') {
+            self.hide()
+          }
+        }, self.options.delay.hide)
+      }
+    }
+
+  , show: function () {
+      var $tip
+        , inside
+        , pos
+        , actualWidth
+        , actualHeight
+        , placement
+        , tp
+
+      if (this.hasContent() && this.enabled) {
+        $tip = this.tip()
+        this.setContent()
+
+        if (this.options.animation) {
+          $tip.addClass('fade')
+        }
+
+        placement = typeof this.options.placement == 'function' ?
+          this.options.placement.call(this, $tip[0], this.$element[0]) :
+          this.options.placement
+
+        inside = /in/.test(placement)
+
+        $tip
+          .remove()
+          .css({ top: 0, left: 0, display: 'block' })
+          .appendTo(inside ? this.$element : document.body)
+
+        pos = this.getPosition(inside)
+
+        actualWidth = $tip[0].offsetWidth
+        actualHeight = $tip[0].offsetHeight
+
+        switch (inside ? placement.split(' ')[1] : placement) {
+          case 'bottom':
+            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
+            break
+          case 'top':
+            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
+            break
+          case 'left':
+            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
+            break
+          case 'right':
+            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
+            break
+        }
+
+        $tip
+          .css(tp)
+          .addClass(placement)
+          .addClass('in')
+      }
+    }
+
+  , setContent: function () {
+      var $tip = this.tip()
+      $tip.find('.tooltip-inner').html(this.getTitle())
+      $tip.removeClass('fade in top bottom left right')
+    }
+
+  , hide: function () {
+      var that = this
+        , $tip = this.tip()
+
+      $tip.removeClass('in')
+
+      function removeWithAnimation() {
+        var timeout = setTimeout(function () {
+          $tip.off($.support.transition.end).remove()
+        }, 500)
+
+        $tip.one($.support.transition.end, function () {
+          clearTimeout(timeout)
+          $tip.remove()
+        })
+      }
+
+      $.support.transition && this.$tip.hasClass('fade') ?
+        removeWithAnimation() :
+        $tip.remove()
+    }
+
+  , fixTitle: function () {
+      var $e = this.$element
+      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
+        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
+      }
+    }
+
+  , hasContent: function () {
+      return this.getTitle()
+    }
+
+  , getPosition: function (inside) {
+      return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
+        width: this.$element[0].offsetWidth
+      , height: this.$element[0].offsetHeight
+      })
+    }
+
+  , getTitle: function () {
+      var title
+        , $e = this.$element
+        , o = this.options
+
+      title = $e.attr('data-original-title')
+        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
+
+      title = title.toString().replace(/(^\s*|\s*$)/, "")
+
+      return title
+    }
+
+  , tip: function () {
+      return this.$tip = this.$tip || $(this.options.template)
+    }
+
+  , validate: function () {
+      if (!this.$element[0].parentNode) {
+        this.hide()
+        this.$element = null
+        this.options = null
+      }
+    }
+
+  , enable: function () {
+      this.enabled = true
+    }
+
+  , disable: function () {
+      this.enabled = false
+    }
+
+  , toggleEnabled: function () {
+      this.enabled = !this.enabled
+    }
+
+  , toggle: function () {
+      this[this.tip().hasClass('in') ? 'hide' : 'show']()
+    }
+
+  }
+
+
+ /* TOOLTIP PLUGIN DEFINITION
+  * ========================= */
+
+  $.fn.tooltip = function ( option ) {
+    return this.each(function () {
+      var $this = $(this)
+        , data = $this.data('tooltip')
+        , options = typeof option == 'object' && option
+      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.tooltip.Constructor = Tooltip
+
+  $.fn.tooltip.defaults = {
+    animation: true
+  , delay: 0
+  , selector: false
+  , placement: 'top'
+  , trigger: 'hover'
+  , title: ''
+  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
+  }
+
+}( window.jQuery )
diff --git a/cloudcms/static/cloudcms/js/colorbox/README.md b/cloudcms/static/cloudcms/js/colorbox/README.md
new file mode 100644 (file)
index 0000000..2a53fea
--- /dev/null
@@ -0,0 +1,318 @@
+## About ColorBox:
+A customizable lightbox plugin for jQuery.  See the [project page](http://jacklmoore.com/colorbox/) for documentation and a demonstration, and the [FAQ](http://jacklmoore.com/colorbox/faq/) for solutions and examples to common issues.  Released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).
+
+## Changelog:
+
+### Version 1.3.19 - December 08 2011
+Files Changed:jquery.colorbox.js/jquery.colorbox-min.js, colorbox.css (all)
+
+* Fixed bug related to using the 'fixed' property.
+* Optimized the setup procedure to be more efficient.
+* Removed $.colorbox.init() as it will no longer be needed (will self-init when called).
+* Removed use of $.browser.
+
+### Version 1.3.18 - October 07 2011
+Files Changed:jquery.colorbox.js/jquery.colorbox-min.js, colorbox.css (all) and example 1's controls.png
+
+* Fixed a regression where Flash content displayed in ColorBox would be reloaded if the browser window was resized.
+* Added safety check to make sure that ColorBox's markup is only added to the DOM a single time, even if $.colorbox.init() is called multiple times.  This will allow site owners to manually initialize ColorBox if they need it before the DOM has finished loading.
+* Updated the example index.html files to be HTML5 compliant.
+* Changed the slideshow behavior so that it immediately moves to the next slide when the slideshow is started.
+* Minor regex bugfix to allow automatic detection of image URLs that include fragments.
+
+### Version 1.3.17 - May 11 2011
+Files Changed:jquery.colorbox.js/jquery.colorbox-min.js
+
+* Added properties "top", "bottom", "left" and "right" to specify a position relative to the viewport, rather than using the default centering.
+* Added property "data" to specify GET or POST data when using Ajax.  ColorBox's ajax functionality is handled by jQuery's .load() method, so the data property works the same way as it does with .load().
+* Added property "fixed" which can provide fixed positioning for ColorBox, rather than absolute positioning.  This will allow ColorBox to remain in a fixed position within the visitors viewport, despite scrolling.  IE6 support for this was not added, it will continue to use the default absolute positioning.
+* Fixed ClearType problem with IE7.
+* Minor fixes.
+
+### Version 1.3.16 - March 01 2011
+Files Changed:jquery.colorbox.js/jquery.colorbox-min.js, colorbox.css (all) and example 4 background png files
+
+* Better IE related transparency workarounds.  IE7 and up now uses the same background image sprite as other browsers.
+* Added error handling for broken image links. A message will be displayed telling the user that the image could not be loaded.
+* Added new property: 'fastIframe' and set it to true by default.  Setting to fastIframe:false will delay the loading graphic removal and onComplete event until iframe has completely loaded.
+* Ability to redefine $.colorbox.close (or prev, or next) at any time.
+
+### Version 1.3.15 - October 27 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Minor fixes for specific cases.
+
+### Version 1.3.14 - October 27 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* In IE6, closing an iframe when using HTTPS no longer generates a security warning.
+
+### Version 1.3.13 - October 22 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Changed the index.html example files to use YouTube's new embedded link format.
+* By default, ColorBox returns focus to the element it was launched from once it closes.  This can now be disabled by setting the 'returnFocus' property to false.  Focus was causing problems for some users who had their anchor elements inside animated containers.
+* Minor bug fix involved in using a combination of slideshow and non-slideshow content.
+
+### Version 1.3.12 - October 20 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Minor bug fix involved in preloading images when using a function as a value for the href property.
+
+### Version 1.3.11 - October 19 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Fixed the slideshow functionality that broke with 1.3.10
+* The slideshow now respects the loop property.
+
+### Version 1.3.10 - October 16 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Fixed compatibility with jQuery 1.4.3
+* The 'open' property now accepts a function as a value, like all of the other properties.
+* Preloading now loads the correct href for images when using a dynamic (function) value for the href property.
+* Fixed bug in Safari 3 for Win where ColorBox centered on the document, rather than the visitor's viewport.
+* May have fixed an issue in Opera 10.6+ where ColorBox would rarely/randomly freeze up while switching between photos in a group.
+* Some functionality better encapsulated & minor performance improvements.
+
+### Version 1.3.9 - July 7 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/ all colorbox.css (the core styles)
+
+* Fixed a problem where iframed youtube videos would cause a security alert in IE.
+* More code is event driven now, making the source easier to grasp.
+* Removed some unnecessary style from the core CSS.
+
+### Version 1.3.8 - June 21 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Fixed a bug in Chrome where it would sometimes render photos at 0 by 0 width and height (behavior introduced in recent update to Chrome).
+* Fixed a bug where the onClosed callback would fire twice (only affected 1.3.7).
+* Fixed a bug in IE7 that existed with some iframed websites that use JS to reposition the viewport caused ColorBox to move out of position.
+* Abstracted the identifiers (HTML ids & classes, and JS plugin name, method, and events) so that the plugin can be easily rebranded.
+* Small changes to improve either code readability or compression.
+
+### Version 1.3.7 - June 13 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/index.html
+
+* $.colorbox can now be used for direct calls and accessing public methods. Example: $.colorbox.close();
+* Resize now accepts 'width', 'innerWidth', 'height' and 'innerHeight'. Example: $.colorbox.resize({width:"100%"})
+* Added option (loop:false) to disable looping in a group.
+* Added options (escKey:false, arrowKey:false) to disable esc-key and arrow-key bindings.
+* Added method for removing ColorBox from a document: $.colorbox.remove();
+* Fixed a bug where iframed URLs would be truncated if they contained an unencoded apostrophe.
+* Now uses the exact href specified on an anchor, rather than the version returned by 'this.href'. This was causing "#example" to be normalized to "http://domain/#example" which interfered with how some users were setting up links to inline content.
+* Changed example documents over to HTML5.
+
+### Version 1.3.6 - Jan 13 2010
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Small change to make ColorBox compatible with jQuery 1.4
+
+### Version 1.3.5 - December 15 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Fixed a bug introduced in 1.3.4 with IE7's display of example 2 and 3, and auto-width in Opera.
+* Fixed a bug introduced in 1.3.4 where colorbox could not be launched by triggering an element's click event through JavaScript.
+* Minor refinements.
+
+### Version 1.3.4 - December 5 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Event delegation is now used for elements that ColorBox is assigned to, rather than individual click events.
+* Additional callbacks have been added to represent other stages of ColorBox's lifecycle. Available callbacks, in order of their execution: onOpen, onLoad, onComplete, onCleanup, onClosed These take place at the same time as the event hooks, but will be better suited than the hooks for targeting specific instances of ColorBox.
+* Ajax content is now immediately added to the DOM to be more compatible if that content contains script tags.
+* Focus is now returned to the calling element on closing.
+* Fixed a bug where maxHeight and maxWidth did not work for non-photo content.
+* Direct calls no longer need 'open:true', it is assumed.  Example: `$.fn.colorbox({html:'<p>Hi</p>'});`
+
+### Version 1.3.3 - November 7 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Changed $.fn.colorbox.element() to return a jQuery object rather the DOM element.
+* jQuery.colorbox-min.js is compressed with Google's Closure Compiler rather than YUI Compressor.
+
+### Version 1.3.2 - October 27 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Added 'innerWidth' and 'innerHeight' options to allow people to easily set the size dimensions for ColorBox, without having to anticipate the size of the borders and buttons.
+* Renamed 'scrollbars' option to 'scrolling' to be in keeping with the existing HTML attribute. The option now also applies to iframes.
+* Bug fix: In Safari, positioning occassionally incorrect when using '100%' dimensions.
+* Bug fix: In IE6, the background overlay is briefly not full size when first viewing.
+* Bug fix: In Firefox, opening ColorBox causes a split second shift with a small minority of webpage layouts.
+* Simplified code in a few areas.
+
+### Version 1.3.1 - September 16 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/colorbox.css/colorbox-ie.css(removed)
+
+* Removed the IE-only stylesheets and conditional comments for example styles 1 & 4.  All CSS is handled by a single CSS file for all examples.
+* Removed user-agent sniffing from the js and replaced it with feature detection.  This will allow correct rendering for visitors masking their agent type.
+
+### Version 1.3.0 - September 15 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/colorbox.css
+
+* Added $.fn.colorbox.resize() method to allow ColorBox to resize it's height if it's contents change.
+* Added 'scrollbars' option to allow users to turn off scrollbars when using the resize() method.
+* Renamed the 'resize' option to be less ambiguous.  It's now 'scalePhotos'.
+* Renamed the 'cbox_close' event to be less ambiguous.  It's now 'cbox_cleanup'.  It is the first thing to happen in the close method while the 'cbox_closed' event is the last to happen.
+* Fixed a bug with the slideshow mouseover graphics that appeared after ColorBox is opened a 2nd time.
+* Fixed a bug where ClearType may not work in IE6&7 if using the fade transition.
+* Minor code optimizations to increase compression.
+
+### Version 1.2.9 - August 7 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Minor change to enable use with $.getScript();
+* Minor change to the timing of the 'cbox_load' event so that it is more useful.
+* Added a direct link to a YouTube video to the examples.
+
+### Version 1.2.8 - August 5 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Fixed a bug with the overlay in IE6
+* Fixed a bug where left & right keypress events might be prematurely unbound.
+
+### Version 1.2.7 - July 31 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js, example stylesheets and background images (core styles have not changed and the updates will not affect existing user themes / old example themes)
+
+* Code cleanup and reduction, better organization and documentation in the full source.
+* Added ability to use functions in place of static values for ColorBox's options (thanks Ken!).
+* Added an option for straight HTML.  Example: `$.fn.colorbox({html:'<p>Howdy</p>', open:true})`
+* Added an event for the beginning of the closing process.  This is in addition to the event that already existed for when ColorBox had completely closed.  'cbox_close' and 'cbox_closed' respectively.
+* Fixed a minor bug in IE6 that would cause a brief content shift in the parent document when opening ColorBox.
+* Fixed a minor bug in IE6 that would reveal select elements that had a hidden visibility after closing ColorBox.
+* The 'esc' key is unbound now when ColorBox is not open, to avoid any potential conflicts.
+* Used background sprites for examples 1 & 4.  Put IE-only (non-sprite) background images in a separate folder.
+* Example themes 1, 3, & 4 received slight visual tweaks.
+* Optimized pngs for smaller file size.
+* Added slices, grid, and correct sizing to the Adobe Illustrator file, all theme files are now export ready!
+
+### Version 1.2.6 - July 15 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Fixed a bug with fixed width/height images in Opera 9.64.
+* Fixed a bug with trying to set a value for rel during a direct call to ColorBox. Example: `$.fn.colorbox({rel:'foo', open:true});`
+* Changed how href/rel/title settings are determined to avoid users having to manually update ColorBox settings if they use JavaScript to update any of those attributes, after ColorBox has been defined.
+* Fixed a FF3 bug where the back button was disabled after closing an iframe.
+
+### Version 1.2.5 - June 23 2009
+Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
+
+* Changed the point at which iframe srcs are set (to eliminate the need to refresh the iframe once it has been added to the DOM).
+* Removed unnecessary return values for a very slight code reduction.
+
+### Version 1.2.4 - June 9 2009
+Files Changed: jquery.colorbox.js, jquery.colorbox-min.js
+
+* Fixed an issue where ColorBox may not close completely if it is closed during a transition animation.
+* Minor code reduction.
+
+### Version 1.2.3 - June 4 2009
+* Fixed a png transparency stacking issue in IE.
+* More accurate Ajax auto-sizing if the user was depending on the #cboxLoadedContent ID for CSS styling.
+* Added a public function for returning the current html element that ColorBox is associated with. Example use: var that = $.fn.colorbox.element();
+* Added bicubic scaling for resized images in the original IE7.
+* Removed the IE6 stylesheet and png files from Example 3.  It now uses the same png file for the controls that the rest of the browsers use (an alpha transparency PNG8).  This example now only has 2 graphics files and 1 stylesheet.
+
+### Version 1.2.2 - May 28 2009
+* Fixed an issue with the 'resize' option.
+
+### Version 1.2.1 - May 28 2009
+* Note: If you are upgrading, update your jquery.colorbox.js and colorbox.css files.
+* Added photo resizing.
+* Added a maximum width and maximum height. Example: {height:800, maxHeight:'100%'}, would allow the box to be a maximum potential height of 800px, instead of a fixed height of 800px.  With maxHeight of 100% the height of ColorBox cannot exceed the height of the browser window.
+* Added 'rel' setting to add the ability to set an alternative rel for any ColorBox call.  This allows the user to group any combination of elements together for a gallery, or to override an existing rel. attribute so those element are not grouped together, without having to alter their rel in the HTML.
+* Added a 'photo' setting to force ColorBox to display a link as a photo.  Use this when automatic photo detection fails (such as using a url like 'photo.php' instead of 'photo.jpg', 'photo.jpg#1', or 'photo.jpg?pic=1')
+* Removed the need to ever create disposable elements to call colorbox on.  ColorBox can now be called directly, without being associated with any existing element, by using the following format:
+  `$.fn.colorbox({open:true, href:'yourLink.xxx'});`
+* ColorBox settings are now persistent and unique for each element.  This allows for extremely flexible options for individual elements.  You could use this to create a gallery in which each page in the gallery has different settings.  One could be a photo with a fade transition, next could be an inline element with an elastic transition with a set width and height, etc.
+* For user callbacks, 'this' now refers to the element colorbox was opened from.
+* Fixed a minor grouping issue with IE6, when transition type is set to 'none'.
+* Added an Adobe Illustrator file that contains the borders and buttons used in the various examples.
+
+### Version 1.2 - May 13 2009
+* Added a slideshow feature.
+* Added re-positioning on browser resize.  If the browser is resized, ColorBox will recenter itself onscreen.
+* Added hooks for key events: cbox_open, cbox_load, cbox_complete, cbox_closed.
+* Fixed an IE transparency-stacking problem, where transparent PNGs would show through to the background overlay.
+* Fixed an IE iframe issue where the ifame might shift up and to the left under certain circumstances.
+* Fixed an IE6 bug where the loading overlay was not at full height.
+* Removed the delay in switching between same-sized gallery content when using transitions.
+* Changed how iframes are loaded to make it more compatible with iframed pages that use DOM dependent JavaScript.
+* Changed how the JS is structured to be better organized and increase compression.  Increased documentation.
+* Changed CSS :hover states to a .hover class.  This sidesteps a minor IE8 bug with css hover states and allows easier access to hover state user styles from the JavaScript.
+* Changed: elements added to the DOM have new ID's.  The naming is more consistent and less likely to cause conflicts with existing website stylesheets.  All stylesheets have been updated.
+* Changed the behavior for prev/next links so that ColorBox does not get hung up on broken links.  A visitor can now skip through broken or long-loading links by clicking prev/next buttons.
+* Changed the naming of variables in the parameter map to be more concise and intuitive.
+* Removed colorbox.css.  Combined the colorbox.css styles with jquery.colorbox.js: the css file was not large enough to warrant being a separate file.
+
+### Version 1.1.6 - April 28 2009
+* Prevented the default action of the next & previous anchors and the left and right keys for gallery mode.
+* Fixed a bug where the title element was being added back to the DOM when closing ColorBox while using inline content.
+* Fixed a bug where IE7 would crash for example 2.
+* Smaller filesize: removed a small amount of unused code and rewrote the HTML injection with less syntax.
+* Added a public method for closing ColorBox: $.fn.colorbox.close().  This will allow iframe users to add an event to close ColorBox without having to create an additional function.
+
+### Version 1.1.5 - April 11 2009
+* Fixed minor issues with exiting ColorBox.
+### Version 1.1.4 - April 08 2009
+* Fixed a bug in the fade transition where ColorBox not close completely if instructed to close during the fade-in portion of the transition.
+
+### Version 1.1.3 - April 06 2009
+* Fixed an IE6&7 issue with using ColorBox to display animated GIFs.
+
+### Version 1.1.2 - April 05 2009
+* Added ability to change content when ColorBox is already open.
+* Added vertical photo centering now works for all browsers (this feature previously excluded IE6&7).
+* Added namespacing to the esc-key keydown event for people who want to disable it: "keydown.colorClose"
+* Added 'title' setting to add the ability to set an alternative title for any ColorBox call.
+* Fixed rollover navigation issue with IE8. (Added JS-based rollover state due to a browser-bug.)
+* Fixed an overflow issue for when the fixed width/height is smaller than the size of a photo.
+* Fixed a bug in the fade transition where the border would still come up if ColorBox was closed mid-transition.
+* Switch from JSMin to Yui Compressor for minification.  Minified code now under 7KB.
+
+### Version 1.1.1 - March 31 2009
+* More robust image detection regex.  Now detects image file types with url fragments and/or query strings.
+* Added 'nofollow' exception to rel grouping.
+* Changed how images are loaded into the DOM to prevent premature size calculation by ColorBox.
+* Added timestamp to iframe name to prevent caching - this was a problem in some browsers if the user had multiple iframes and the visitor left the page and came back, or if they refreshed the page.
+
+### Version 1.1.0 - March 21 2009
+* Animation is now much smoother and less resource intensive.
+* Added support for % sizing.
+* Callback option added.
+* Inline content now preserves JavaScript events, and changes made while ColorBox is open are also preserved.
+* Added 'href' setting to add the ability to set an alternative href for any anchor, or to assign the ColorBox event to non-anchors. 
+  Example: $('button').colorbox({'href':'process.php'})
+  Example: $('a[href='http://msn.com']).colorbox({'href':'http://google.com', iframe:true});
+* Photos are now horizontally centered if they are smaller than the lightbox size.  Also vertically centered for browsers newer than IE7.
+* Buttons in the examples are now included in the 'protected zone'.  The lightbox will never expand it's borders or buttons beyond an accessible area of the screen.
+* Keypress events don't queue up by holding down the arrow keys.
+* Added option to close ColorBox by clicking on the background overlay.
+* Added 'none' transition setting.
+* Changed 'contentIframe' and 'contentInline' to 'inline' and 'iframe'.  Removed 'contentAjax' because it  is automatically assumed for non-image file types.
+* Changed 'contentWidth' and 'contentHeight' to 'fixedWidth' and 'fixedHeight'.  These sizes now reflect  the total size of the lightbox, not just the inner content.  This is so users can accurately anticipate  % sizes without fear of creating scrollbars.
+* Clicking on a photo will now switch to the next photo in a set.
+* Loading.gif is more stable in it's position.
+* Added a minified version.
+* Code passes JSLint.
+
+### Version 1.0.5 - March 11 2009
+* Redo: Fixed a bug where IE would cut off the bottom portion of a photo, if the photo was larger than the document dimensions.
+
+### Version 1.0.4 - March 10 2009
+* Added an option to allow users to automatically open the lightbox. Example usage: $(".colorbox").colorbox({open:true});
+* Fixed a bug where IE would cut off the bottom portion of a photo, if the photo was larger than the document dimensions.
+
+### Version 1.0.3 - March 09 2009
+* Fixed vertical centering for Safari 3.0.x.
+
+### Version 1.0.2 - March 06 2009
+* Corrected a typo.
+* Changed the content-type check so that it does not assume all links to photos should actually display photos. This allows for Ajax/inline/and iframe calls on anchors linking to picture file types.
+
+### Version 1.0.1 - March 05 2009
+* Fixed keydown events (esc, left arrow, right arrow) for Webkit browsers.
+
+### Version 1.0 - March 03 2009
+* First release
diff --git a/cloudcms/static/cloudcms/js/colorbox/jquery.colorbox.js b/cloudcms/static/cloudcms/js/colorbox/jquery.colorbox.js
new file mode 100644 (file)
index 0000000..d855da8
--- /dev/null
@@ -0,0 +1,888 @@
+// ColorBox v1.3.19 - jQuery lightbox plugin
+// (c) 2011 Jack Moore - jacklmoore.com
+// License: http://www.opensource.org/licenses/mit-license.php
+(function ($, document, window) {
+    var
+    // Default settings object.        
+    // See http://jacklmoore.com/colorbox for details.
+    defaults = {
+        transition: "elastic",
+        speed: 300,
+        width: false,
+        initialWidth: "600",
+        innerWidth: false,
+        maxWidth: false,
+        height: false,
+        initialHeight: "450",
+        innerHeight: false,
+        maxHeight: false,
+        scalePhotos: true,
+        scrolling: true,
+        inline: false,
+        html: false,
+        iframe: false,
+        fastIframe: true,
+        photo: false,
+        href: false,
+        title: false,
+        rel: false,
+        opacity: 0.9,
+        preloading: true,
+        current: "image {current} of {total}",
+        previous: "previous",
+        next: "next",
+        close: "close",
+        open: false,
+        returnFocus: true,
+        reposition: true,
+        loop: true,
+        slideshow: false,
+        slideshowAuto: true,
+        slideshowSpeed: 2500,
+        slideshowStart: "start slideshow",
+        slideshowStop: "stop slideshow",
+        onOpen: false,
+        onLoad: false,
+        onComplete: false,
+        onCleanup: false,
+        onClosed: false,
+        overlayClose: true,            
+        escKey: true,
+        arrowKey: true,
+        top: false,
+        bottom: false,
+        left: false,
+        right: false,
+        fixed: false,
+        data: undefined
+    },
+       
+    // Abstracting the HTML and event identifiers for easy rebranding
+    colorbox = 'colorbox',
+    prefix = 'cbox',
+    boxElement = prefix + 'Element',
+    
+    // Events  
+    event_open = prefix + '_open',
+    event_load = prefix + '_load',
+    event_complete = prefix + '_complete',
+    event_cleanup = prefix + '_cleanup',
+    event_closed = prefix + '_closed',
+    event_purge = prefix + '_purge',
+    
+    // Special Handling for IE
+    isIE = !$.support.opacity && !$.support.style, // IE7 & IE8
+    isIE6 = isIE && !window.XMLHttpRequest, // IE6
+    event_ie6 = prefix + '_IE6',
+
+    // Cached jQuery Object Variables
+    $overlay,
+    $box,
+    $wrap,
+    $content,
+    $topBorder,
+    $leftBorder,
+    $rightBorder,
+    $bottomBorder,
+    $related,
+    $window,
+    $loaded,
+    $loadingBay,
+    $loadingOverlay,
+    $title,
+    $current,
+    $slideshow,
+    $next,
+    $prev,
+    $close,
+    $groupControls,
+    
+    // Variables for cached values or use across multiple functions
+    settings,
+    interfaceHeight,
+    interfaceWidth,
+    loadedHeight,
+    loadedWidth,
+    element,
+    index,
+    photo,
+    open,
+    active,
+    closing,
+    loadingTimer,
+    publicMethod,
+    div = "div",
+    init;
+
+       // ****************
+       // HELPER FUNCTIONS
+       // ****************
+    
+       // Convience function for creating new jQuery objects
+    function $tag(tag, id, css) {
+               var element = document.createElement(tag);
+
+               if (id) {
+                       element.id = prefix + id;
+               }
+
+               if (css) {
+                       element.style.cssText = css;
+               }
+
+               return $(element);
+    }
+
+       // Determine the next and previous members in a group.
+       function getIndex(increment) {
+               var 
+               max = $related.length, 
+               newIndex = (index + increment) % max;
+               
+               return (newIndex < 0) ? max + newIndex : newIndex;
+       }
+
+       // Convert '%' and 'px' values to integers
+       function setSize(size, dimension) {
+               return Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : $window.height()) / 100) : 1) * parseInt(size, 10));
+       }
+       
+       // Checks an href to see if it is a photo.
+       // There is a force photo option (photo: true) for hrefs that cannot be matched by this regex.
+       function isImage(url) {
+               return settings.photo || /\.(gif|png|jpe?g|bmp|ico)((#|\?).*)?$/i.test(url);
+       }
+       
+       // Assigns function results to their respective properties
+       function makeSettings() {
+        var i;
+        settings = $.extend({}, $.data(element, colorbox));
+        
+               for (i in settings) {
+                       if ($.isFunction(settings[i]) && i.slice(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time.
+                           settings[i] = settings[i].call(element);
+                       }
+               }
+        
+               settings.rel = settings.rel || element.rel || 'nofollow';
+               settings.href = settings.href || $(element).attr('href');
+               settings.title = settings.title || element.title;
+        
+        if (typeof settings.href === "string") {
+            settings.href = $.trim(settings.href);
+        }
+       }
+
+       function trigger(event, callback) {
+               $.event.trigger(event);
+               if (callback) {
+                       callback.call(element);
+               }
+       }
+
+       // Slideshow functionality
+       function slideshow() {
+               var
+               timeOut,
+               className = prefix + "Slideshow_",
+               click = "click." + prefix,
+               start,
+               stop,
+               clear;
+               
+               if (settings.slideshow && $related[1]) {
+                       start = function () {
+                               $slideshow
+                                       .text(settings.slideshowStop)
+                                       .unbind(click)
+                                       .bind(event_complete, function () {
+                                               if (settings.loop || $related[index + 1]) {
+                                                       timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
+                                               }
+                                       })
+                                       .bind(event_load, function () {
+                                               clearTimeout(timeOut);
+                                       })
+                                       .one(click + ' ' + event_cleanup, stop);
+                               $box.removeClass(className + "off").addClass(className + "on");
+                               timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed);
+                       };
+                       
+                       stop = function () {
+                               clearTimeout(timeOut);
+                               $slideshow
+                                       .text(settings.slideshowStart)
+                                       .unbind([event_complete, event_load, event_cleanup, click].join(' '))
+                                       .one(click, function () {
+                                               publicMethod.next();
+                                               start();
+                                       });
+                               $box.removeClass(className + "on").addClass(className + "off");
+                       };
+                       
+                       if (settings.slideshowAuto) {
+                               start();
+                       } else {
+                               stop();
+                       }
+               } else {
+            $box.removeClass(className + "off " + className + "on");
+        }
+       }
+
+       function launch(target) {
+               if (!closing) {
+                       
+                       element = target;
+                       
+                       makeSettings();
+                       
+                       $related = $(element);
+                       
+                       index = 0;
+                       
+                       if (settings.rel !== 'nofollow') {
+                               $related = $('.' + boxElement).filter(function () {
+                                       var relRelated = $.data(this, colorbox).rel || this.rel;
+                                       return (relRelated === settings.rel);
+                               });
+                               index = $related.index(element);
+                               
+                               // Check direct calls to ColorBox.
+                               if (index === -1) {
+                                       $related = $related.add(element);
+                                       index = $related.length - 1;
+                               }
+                       }
+                       
+                       if (!open) {
+                               open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.
+                               
+                               $box.show();
+                               
+                               if (settings.returnFocus) {
+                                       $(element).blur().one(event_closed, function () {
+                                               $(this).focus();
+                                       });
+                               }
+                               
+                               // +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5'
+                               $overlay.css({"opacity": +settings.opacity, "cursor": settings.overlayClose ? "pointer" : "auto"}).show();
+                               
+                               // Opens inital empty ColorBox prior to content being loaded.
+                               settings.w = setSize(settings.initialWidth, 'x');
+                               settings.h = setSize(settings.initialHeight, 'y');
+                               publicMethod.position();
+                               
+                               if (isIE6) {
+                                       $window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () {
+                                               $overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()});
+                                       }).trigger('resize.' + event_ie6);
+                               }
+                               
+                               trigger(event_open, settings.onOpen);
+                               
+                               $groupControls.add($title).hide();
+                               
+                               $close.html(settings.close).show();
+                       }
+                       
+                       publicMethod.load(true);
+               }
+       }
+
+       // ColorBox's markup needs to be added to the DOM prior to being called
+       // so that the browser will go ahead and load the CSS background images.
+       function appendHTML() {
+               if (!$box && document.body) {
+                       init = false;
+
+                       $window = $(window);
+                       $box = $tag(div).attr({id: colorbox, 'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : ''}).hide();
+                       $overlay = $tag(div, "Overlay", isIE6 ? 'position:absolute' : '').hide();
+                       $wrap = $tag(div, "Wrapper");
+                       $content = $tag(div, "Content").append(
+                               $loaded = $tag(div, "LoadedContent", 'width:0; height:0; overflow:hidden'),
+                               $loadingOverlay = $tag(div, "LoadingOverlay").add($tag(div, "LoadingGraphic")),
+                               $title = $tag(div, "Title"),
+                               $current = $tag(div, "Current"),
+                               $next = $tag(div, "Next"),
+                               $prev = $tag(div, "Previous"),
+                               $slideshow = $tag(div, "Slideshow").bind(event_open, slideshow),
+                               $close = $tag(div, "Close")
+                       );
+                       
+                       $wrap.append( // The 3x3 Grid that makes up ColorBox
+                               $tag(div).append(
+                                       $tag(div, "TopLeft"),
+                                       $topBorder = $tag(div, "TopCenter"),
+                                       $tag(div, "TopRight")
+                               ),
+                               $tag(div, false, 'clear:left').append(
+                                       $leftBorder = $tag(div, "MiddleLeft"),
+                                       $content,
+                                       $rightBorder = $tag(div, "MiddleRight")
+                               ),
+                               $tag(div, false, 'clear:left').append(
+                                       $tag(div, "BottomLeft"),
+                                       $bottomBorder = $tag(div, "BottomCenter"),
+                                       $tag(div, "BottomRight")
+                               )
+                       ).find('div div').css({'float': 'left'});
+                       
+                       $loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none');
+                       
+                       $groupControls = $next.add($prev).add($current).add($slideshow);
+
+                       $(document.body).append($overlay, $box.append($wrap, $loadingBay));
+               }
+       }
+
+       // Add ColorBox's event bindings
+       function addBindings() {
+               if ($box) {
+                       if (!init) {
+                               init = true;
+
+                               // Cache values needed for size calculations
+                               interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6
+                               interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
+                               loadedHeight = $loaded.outerHeight(true);
+                               loadedWidth = $loaded.outerWidth(true);
+                               
+                               // Setting padding to remove the need to do size conversions during the animation step.
+                               $box.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth});
+
+                               // Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.
+                               $next.click(function () {
+                                       publicMethod.next();
+                               });
+                               $prev.click(function () {
+                                       publicMethod.prev();
+                               });
+                               $close.click(function () {
+                                       publicMethod.close();
+                               });
+                               $overlay.click(function () {
+                                       if (settings.overlayClose) {
+                                               publicMethod.close();
+                                       }
+                               });
+                               
+                               // Key Bindings
+                               $(document).bind('keydown.' + prefix, function (e) {
+                                       var key = e.keyCode;
+                                       if (open && settings.escKey && key === 27) {
+                                               e.preventDefault();
+                                               publicMethod.close();
+                                       }
+                                       if (open && settings.arrowKey && $related[1]) {
+                                               if (key === 37) {
+                                                       e.preventDefault();
+                                                       $prev.click();
+                                               } else if (key === 39) {
+                                                       e.preventDefault();
+                                                       $next.click();
+                                               }
+                                       }
+                               });
+
+                               $('.' + boxElement, document).live('click', function (e) {
+                               // ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.
+                               // See: http://jacklmoore.com/notes/click-events/
+                               if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey)) {
+                                   e.preventDefault();
+                                   launch(this);
+                               }
+                           });
+                       }
+                       return true;
+               }
+               return false;
+       }
+
+       // Don't do anything if ColorBox already exists.
+       if ($.colorbox) {
+               return;
+       }
+
+       // Append the HTML when the DOM loads
+       $(appendHTML);
+
+
+       // ****************
+       // PUBLIC FUNCTIONS
+       // Usage format: $.fn.colorbox.close();
+       // Usage from within an iframe: parent.$.fn.colorbox.close();
+       // ****************
+       
+       publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
+               var $this = this;
+               
+        options = options || {};
+        
+        appendHTML();
+
+               if (addBindings()) {
+                       if (!$this[0]) {
+                               if ($this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit.
+                       return $this;
+                   }
+                   // if no selector was given (ie. $.colorbox()), create a temporary element to work with
+                               $this = $('<a/>');
+                               options.open = true; // assume an immediate open
+                       }
+                       
+                       if (callback) {
+                               options.onComplete = callback;
+                       }
+                       
+                       $this.each(function () {
+                               $.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options));
+                       }).addClass(boxElement);
+                       
+               if (($.isFunction(options.open) && options.open.call($this)) || options.open) {
+                               launch($this[0]);
+                       }
+               }
+        
+               return $this;
+       };
+
+       publicMethod.position = function (speed, loadedCallback) {
+        var 
+        top = 0, 
+        left = 0, 
+        offset = $box.offset(),
+        scrollTop = $window.scrollTop(), 
+        scrollLeft = $window.scrollLeft();
+        
+        $window.unbind('resize.' + prefix);
+
+        // remove the modal so that it doesn't influence the document width/height        
+        $box.css({top: -9e4, left: -9e4});
+
+        if (settings.fixed && !isIE6) {
+                       offset.top -= scrollTop;
+                       offset.left -= scrollLeft;
+            $box.css({position: 'fixed'});
+        } else {
+            top = scrollTop;
+            left = scrollLeft;
+            $box.css({position: 'absolute'});
+        }
+
+               // keeps the top and left positions within the browser's viewport.
+        if (settings.right !== false) {
+            left += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0);
+        } else if (settings.left !== false) {
+            left += setSize(settings.left, 'x');
+        } else {
+            left += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2);
+        }
+        
+        if (settings.bottom !== false) {
+            top += Math.max($window.height() - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0);
+        } else if (settings.top !== false) {
+            top += setSize(settings.top, 'y');
+        } else {
+            top += Math.round(Math.max($window.height() - settings.h - loadedHeight - interfaceHeight, 0) / 2);
+        }
+
+        $box.css({top: offset.top, left: offset.left});
+
+               // setting the speed to 0 to reduce the delay between same-sized content.
+               speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed || 0;
+        
+               // this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
+               // but it has to be shrank down around the size of div#colorbox when it's done.  If not,
+               // it can invoke an obscure IE bug when using iframes.
+               $wrap[0].style.width = $wrap[0].style.height = "9999px";
+               
+               function modalDimensions(that) {
+                       $topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width;
+                       $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height;
+               }
+               
+               $box.dequeue().animate({width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: top, left: left}, {
+                       duration: speed,
+                       complete: function () {
+                               modalDimensions(this);
+                               
+                               active = false;
+                               
+                               // shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
+                               $wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
+                               $wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";
+                
+                if (settings.reposition) {
+                       setTimeout(function () {  // small delay before binding onresize due to an IE8 bug.
+                           $window.bind('resize.' + prefix, publicMethod.position);
+                       }, 1);
+                   }
+
+                               if (loadedCallback) {
+                                       loadedCallback();
+                               }
+                       },
+                       step: function () {
+                               modalDimensions(this);
+                       }
+               });
+       };
+
+       publicMethod.resize = function (options) {
+               if (open) {
+                       options = options || {};
+                       
+                       if (options.width) {
+                               settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
+                       }
+                       if (options.innerWidth) {
+                               settings.w = setSize(options.innerWidth, 'x');
+                       }
+                       $loaded.css({width: settings.w});
+                       
+                       if (options.height) {
+                               settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
+                       }
+                       if (options.innerHeight) {
+                               settings.h = setSize(options.innerHeight, 'y');
+                       }
+                       if (!options.innerHeight && !options.height) {
+                               $loaded.css({height: "auto"});
+                               settings.h = $loaded.height();
+                       }
+                       $loaded.css({height: settings.h});
+                       
+                       publicMethod.position(settings.transition === "none" ? 0 : settings.speed);
+               }
+       };
+
+       publicMethod.prep = function (object) {
+               if (!open) {
+                       return;
+               }
+               
+               var callback, speed = settings.transition === "none" ? 0 : settings.speed;
+               
+               $loaded.remove();
+               $loaded = $tag(div, 'LoadedContent').append(object);
+               
+               function getWidth() {
+                       settings.w = settings.w || $loaded.width();
+                       settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
+                       return settings.w;
+               }
+               function getHeight() {
+                       settings.h = settings.h || $loaded.height();
+                       settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
+                       return settings.h;
+               }
+               
+               $loaded.hide()
+               .appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
+               .css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'})
+               .css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
+               .prependTo($content);
+               
+               $loadingBay.hide();
+               
+               // floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
+               //$(photo).css({'float': 'none', marginLeft: 'auto', marginRight: 'auto'});
+               
+        $(photo).css({'float': 'none'});
+        
+               // Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay.
+               if (isIE6) {
+                       $('select').not($box.find('select')).filter(function () {
+                               return this.style.visibility !== 'hidden';
+                       }).css({'visibility': 'hidden'}).one(event_cleanup, function () {
+                               this.style.visibility = 'inherit';
+                       });
+               }
+               
+               callback = function () {
+            var preload, i, total = $related.length, iframe, frameBorder = 'frameBorder', allowTransparency = 'allowTransparency', complete, src, img;
+            
+            if (!open) {
+                return;
+            }
+            
+            function removeFilter() {
+                if (isIE) {
+                    $box[0].style.removeAttribute('filter');
+                }
+            }
+            
+            complete = function () {
+                clearTimeout(loadingTimer);
+                $loadingOverlay.hide();
+                trigger(event_complete, settings.onComplete);
+            };
+            
+            if (isIE) {
+                //This fadeIn helps the bicubic resampling to kick-in.
+                if (photo) {
+                    $loaded.fadeIn(100);
+                }
+            }
+            
+            $title.html(settings.title).add($loaded).show();
+            
+            if (total > 1) { // handle grouping
+                if (typeof settings.current === "string") {
+                    $current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show();
+                }
+                
+                $next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next);
+                $prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous);
+                               
+                if (settings.slideshow) {
+                    $slideshow.show();
+                }
+                               
+                // Preloads images within a rel group
+                if (settings.preloading) {
+                                       preload = [
+                                               getIndex(-1),
+                                               getIndex(1)
+                                       ];
+                                       while (i = $related[preload.pop()]) {
+                                               src = $.data(i, colorbox).href || i.href;
+                                               if ($.isFunction(src)) {
+                                                       src = src.call(i);
+                                               }
+                                               if (isImage(src)) {
+                                                       img = new Image();
+                                                       img.src = src;
+                                               }
+                                       }
+                }
+            } else {
+                $groupControls.hide();
+            }
+            
+            if (settings.iframe) {
+                iframe = $tag('iframe')[0];
+                
+                if (frameBorder in iframe) {
+                    iframe[frameBorder] = 0;
+                }
+                if (allowTransparency in iframe) {
+                    iframe[allowTransparency] = "true";
+                }
+                // give the iframe a unique name to prevent caching
+                iframe.name = prefix + (+new Date());
+                if (settings.fastIframe) {
+                    complete();
+                } else {
+                    $(iframe).one('load', complete);
+                }
+                iframe.src = settings.href;
+                if (!settings.scrolling) {
+                    iframe.scrolling = "no";
+                }
+                $(iframe).addClass(prefix + 'Iframe').appendTo($loaded).one(event_purge, function () {
+                    iframe.src = "//about:blank";
+                });
+            } else {
+                complete();
+            }
+            
+            if (settings.transition === 'fade') {
+                $box.fadeTo(speed, 1, removeFilter);
+            } else {
+                removeFilter();
+            }
+               };
+               
+               if (settings.transition === 'fade') {
+                       $box.fadeTo(speed, 0, function () {
+                               publicMethod.position(0, callback);
+                       });
+               } else {
+                       publicMethod.position(speed, callback);
+               }
+       };
+
+       publicMethod.load = function (launched) {
+               var href, setResize, prep = publicMethod.prep;
+               
+               active = true;
+               
+               photo = false;
+               
+               element = $related[index];
+               
+               if (!launched) {
+                       makeSettings();
+               }
+               
+               trigger(event_purge);
+               
+               trigger(event_load, settings.onLoad);
+               
+               settings.h = settings.height ?
+                               setSize(settings.height, 'y') - loadedHeight - interfaceHeight :
+                               settings.innerHeight && setSize(settings.innerHeight, 'y');
+               
+               settings.w = settings.width ?
+                               setSize(settings.width, 'x') - loadedWidth - interfaceWidth :
+                               settings.innerWidth && setSize(settings.innerWidth, 'x');
+               
+               // Sets the minimum dimensions for use in image scaling
+               settings.mw = settings.w;
+               settings.mh = settings.h;
+               
+               // Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
+               // If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
+               if (settings.maxWidth) {
+                       settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth;
+                       settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
+               }
+               if (settings.maxHeight) {
+                       settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight;
+                       settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
+               }
+               
+               href = settings.href;
+               
+        loadingTimer = setTimeout(function () {
+            $loadingOverlay.show();
+        }, 100);
+        
+               if (settings.inline) {
+                       // Inserts an empty placeholder where inline content is being pulled from.
+                       // An event is bound to put inline content back when ColorBox closes or loads new content.
+                       $tag(div).hide().insertBefore($(href)[0]).one(event_purge, function () {
+                               $(this).replaceWith($loaded.children());
+                       });
+                       prep($(href));
+               } else if (settings.iframe) {
+                       // IFrame element won't be added to the DOM until it is ready to be displayed,
+                       // to avoid problems with DOM-ready JS that might be trying to run in that iframe.
+                       prep(" ");
+               } else if (settings.html) {
+                       prep(settings.html);
+               } else if (isImage(href)) {
+                       $(photo = new Image())
+                       .addClass(prefix + 'Photo')
+                       .error(function () {
+                               settings.title = false;
+                               prep($tag(div, 'Error').text('This image could not be loaded'));
+                       })
+                       .load(function () {
+                               var percent;
+                               photo.onload = null; //stops animated gifs from firing the onload repeatedly.
+                               
+                               if (settings.scalePhotos) {
+                                       setResize = function () {
+                                               photo.height -= photo.height * percent;
+                                               photo.width -= photo.width * percent;   
+                                       };
+                                       if (settings.mw && photo.width > settings.mw) {
+                                               percent = (photo.width - settings.mw) / photo.width;
+                                               setResize();
+                                       }
+                                       if (settings.mh && photo.height > settings.mh) {
+                                               percent = (photo.height - settings.mh) / photo.height;
+                                               setResize();
+                                       }
+                               }
+                               
+                               if (settings.h) {
+                                       photo.style.marginTop = Math.max(settings.h - photo.height, 0) / 2 + 'px';
+                               }
+                               
+                               if ($related[1] && (settings.loop || $related[index + 1])) {
+                                       photo.style.cursor = 'pointer';
+                                       photo.onclick = function () {
+                        publicMethod.next();
+                    };
+                               }
+                               
+                               if (isIE) {
+                                       photo.style.msInterpolationMode = 'bicubic';
+                               }
+                               
+                               setTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise.
+                                       prep(photo);
+                               }, 1);
+                       });
+                       
+                       setTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise.
+                               photo.src = href;
+                       }, 1);
+               } else if (href) {
+                       $loadingBay.load(href, settings.data, function (data, status, xhr) {
+                               prep(status === 'error' ? $tag(div, 'Error').text('Request unsuccessful: ' + xhr.statusText) : $(this).contents());
+                       });
+               }
+       };
+        
+       // Navigates to the next page/image in a set.
+       publicMethod.next = function () {
+               if (!active && $related[1] && (settings.loop || $related[index + 1])) {
+                       index = getIndex(1);
+                       publicMethod.load();
+               }
+       };
+       
+       publicMethod.prev = function () {
+               if (!active && $related[1] && (settings.loop || index)) {
+                       index = getIndex(-1);
+                       publicMethod.load();
+               }
+       };
+
+       // Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close();
+       publicMethod.close = function () {
+               if (open && !closing) {
+                       
+                       closing = true;
+                       
+                       open = false;
+                       
+                       trigger(event_cleanup, settings.onCleanup);
+                       
+                       $window.unbind('.' + prefix + ' .' + event_ie6);
+                       
+                       $overlay.fadeTo(200, 0);
+                       
+                       $box.stop().fadeTo(300, 0, function () {
+                 
+                               $box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide();
+                               
+                               trigger(event_purge);
+                               
+                               $loaded.remove();
+                               
+                               setTimeout(function () {
+                                       closing = false;
+                                       trigger(event_closed, settings.onClosed);
+                               }, 1);
+                       });
+               }
+       };
+
+       // Removes changes ColorBox made to the document, but does not remove the plugin
+       // from jQuery.
+       publicMethod.remove = function () {
+               $([]).add($box).add($overlay).remove();
+               $box = null;
+               $('.' + boxElement)
+                       .removeData(colorbox)
+                       .removeClass(boxElement)
+                       .die();
+       };
+
+       // A method for fetching the current element ColorBox is referencing.
+       // returns a jQuery object.
+       publicMethod.element = function () {
+               return $(element);
+       };
+
+       publicMethod.settings = defaults;
+
+}(jQuery, document, this));
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/js/form-errors.js b/cloudcms/static/cloudcms/js/form-errors.js
new file mode 100644 (file)
index 0000000..c36e7bc
--- /dev/null
@@ -0,0 +1,52 @@
+(function($){
+
+  $.fn.formErrors = function(options) {  
+    return this.each(function() {
+        var $this = $(this);
+
+        // does the field has any errors ?
+        var errors = $this.find(".errorlist");
+        if (errors.length == 0) {
+            return;
+        }
+        
+        // create the custom error message block
+        // and copy the contents of the original
+        // error list
+        var el = $('<div class="form-error" />');
+        errors.find("li").each(function(){
+            el.html(el.html() + $(this).text() + "<br />");
+        })
+        
+        var formel = $this.find("input, select");
+        var lbl = $this.find("label");
+        var form = $this.closest("form");
+
+
+        // append element on form row 
+        // and apply the appropriate styles
+        formel.closest(".form-row").append(el);
+        errors.remove();
+        var left = formel.width();
+        var top = formel.height();
+        var marginleft = lbl.width();
+        
+        // identify the position
+        // forms with innerlbales class
+        // display the label within the input fields
+        if ($(form).hasClass("innerlabels")) {
+            marginleft = 0;
+        }
+        
+        var styles = {
+            left: left + "px", 
+            top: top + "px", 
+            width: formel.outerWidth() - 10,
+            marginLeft: marginleft,
+            marginBottom: 5
+        }
+        el.css(styles);
+    });
+
+  };
+})( jQuery );
diff --git a/cloudcms/static/cloudcms/js/jquery-1.7.1.min.js b/cloudcms/static/cloudcms/js/jquery-1.7.1.min.js
new file mode 100644 (file)
index 0000000..198b3ff
--- /dev/null
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 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 cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(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 cb(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 ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(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 b$(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===bT,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=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),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 bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}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;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function 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].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}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)?parseFloat(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.1",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&&typeof a=="object"&&"setInterval"in a},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){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){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},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=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"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(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]){i&&f<=k&&(k--,f<=l&&l--),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)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};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,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.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:q.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},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});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=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},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){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return 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()}});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,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},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.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];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=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&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},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=/\bhover(\.\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),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),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=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}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){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!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=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.call(this,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.type+"."+e.namespace:e.type,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){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));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.POS,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|canvas|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+")","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){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){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){if(a===b)return this[0]&&this[0].nodeType===1?this[0].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(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},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,bp)}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||!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;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},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 bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","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=bv.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(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.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(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$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)));return c}),c.documentElement.currentStyle&&(bB=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)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,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)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.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(bN,"")).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||bO.test(this.nodeName)||bI.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(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\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:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},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:bZ(bT),ajaxTransport:bZ(bU),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?cb(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=cc(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=bH.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(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.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]!=="*"?", "+bX+"; 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=b$(bU,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)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.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(ce,l),b.url===j&&(e&&(k=k.replace(ce,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 cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,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,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("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._data(d,"olddisplay",cv(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(cu("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(cu("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;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),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||cv(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],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,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:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("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,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},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=cr||cs(),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(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=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=cr||cs(),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(cp),cp=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(["width","height"],function(a,b){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 cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},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(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/js/jquery.cookie.js b/cloudcms/static/cloudcms/js/jquery.cookie.js
new file mode 100644 (file)
index 0000000..883e714
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * jQuery Cookie plugin - https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright (c) 2010 Klaus Hartl, @carhartl
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+(function($) {
+    $.cookie = function(key, value, options) {
+
+        // key and at least value given, set cookie...
+        if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
+            options = $.extend({}, options);
+
+            if (value === null || value === undefined) {
+                options.expires = -1;
+            }
+
+            if (typeof options.expires === 'number') {
+                var days = options.expires, t = options.expires = new Date();
+                t.setDate(t.getDate() + days);
+            }
+
+            value = String(value);
+
+            return (document.cookie = [
+                encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
+                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+                options.path    ? '; path=' + options.path : '',
+                options.domain  ? '; domain=' + options.domain : '',
+                options.secure  ? '; secure' : ''
+            ].join(''));
+        }
+
+        // key and possibly options given, get cookie...
+        options = value || {};
+        var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
+
+        var pairs = document.cookie.split('; ');
+        for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
+            if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
+        }
+        return null;
+    };
+})(jQuery);
diff --git a/cloudcms/static/cloudcms/js/jquery.infieldlabel.js b/cloudcms/static/cloudcms/js/jquery.infieldlabel.js
new file mode 100755 (executable)
index 0000000..8664c1f
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * In-Field Label jQuery Plugin
+ * http://fuelyourcoding.com/scripts/infield.html
+ *
+ * Copyright (c) 2009 Doug Neiner
+ * Dual licensed under the MIT and GPL licenses.
+ * Uses the same license as jQuery, see:
+ * http://docs.jquery.com/License
+ *
+ * @version 0.1
+ */
+(function($){
+       
+    $.InFieldLabels = function(label,field, options){
+        // To avoid scope issues, use 'base' instead of 'this'
+        // to reference this class from internal events and functions.
+        var base = this;
+        
+        // Access to jQuery and DOM versions of each element
+        base.$label = $(label);
+        base.label = label;
+
+               base.$field = $(field);
+               base.field = field;
+        
+               base.$label.data("InFieldLabels", base);
+               base.showing = true;
+        
+        base.init = function(){
+                       // Merge supplied options with default options
+            base.options = $.extend({},$.InFieldLabels.defaultOptions, options);
+
+                       // Check if the field is already filled in
+                       if(base.$field.val() != ""){
+                               base.$label.hide();
+                               base.showing = false;
+                       };
+                       base.$field.focus(function(){
+                               base.fadeOnFocus();
+                       }).blur(function(){
+                               base.checkForEmpty(true);
+                       }).bind('keydown.infieldlabel',function(e){
+                               // Use of a namespace (.infieldlabel) allows us to
+                               // unbind just this method later
+                               base.hideOnChange(e);
+                       }).change(function(e){
+                               base.checkForEmpty();
+                       }).bind('onPropertyChange', function(){
+                               base.checkForEmpty();
+                       });
+        };
+
+               // If the label is currently showing
+               // then fade it down to the amount
+               // specified in the settings
+               base.fadeOnFocus = function(){
+                       if(base.showing){
+                               base.setOpacity(base.options.fadeOpacity);
+                       };
+               };
+               
+               base.setOpacity = function(opacity){
+                       base.$label.stop().animate({ opacity: opacity }, base.options.fadeDuration);
+                       base.showing = (opacity > 0.0);
+               };
+               
+               // Checks for empty as a fail safe
+               // set blur to true when passing from
+               // the blur event
+               base.checkForEmpty = function(blur){
+                       if(base.$field.val() == ""){
+                               base.prepForShow();
+                               base.setOpacity( blur ? 1.0 : base.options.fadeOpacity );
+                       } else {
+                               base.setOpacity(0.0);
+                       };
+               };
+               
+               base.prepForShow = function(e){
+                       if(!base.showing) {
+                               // Prepare for a animate in...
+                               base.$label.css({opacity: 0.0}).show();
+                               
+                               // Reattach the keydown event
+                               base.$field.bind('keydown.infieldlabel',function(e){
+                                       base.hideOnChange(e);
+                               });
+                       };
+               };
+
+               base.hideOnChange = function(e){
+                       if(
+                               (e.keyCode == 16) || // Skip Shift
+                               (e.keyCode == 9) // Skip Tab
+                         ) return; 
+                       
+                       if(base.showing){
+                               base.$label.hide();
+                               base.showing = false;
+                       };
+                       
+                       // Remove keydown event to save on CPU processing
+                       base.$field.unbind('keydown.infieldlabel');
+               };
+      
+               // Run the initialization method
+        base.init();
+    };
+       
+    $.InFieldLabels.defaultOptions = {
+        fadeOpacity: 0.5, // Once a field has focus, how transparent should the label be
+               fadeDuration: 300 // How long should it take to animate from 1.0 opacity to the fadeOpacity
+    };
+       
+
+    $.fn.inFieldLabels = function(options){
+        return this.each(function(){
+                       // Find input or textarea based on for= attribute
+                       // The for attribute on the label must contain the ID
+                       // of the input or textarea element
+                       var for_attr = $(this).attr('for');
+                       if( !for_attr ) return; // Nothing to attach, since the for field wasn't used
+                       
+                       
+                       // Find the referenced input or textarea element
+                       var $field = $(
+                               "input#" + for_attr + "[type='text']," + 
+                               "input#" + for_attr + "[type='password']," + 
+                               "textarea#" + for_attr
+                               );
+                       
+                       if( $field.length == 0) return; // Again, nothing to attach
+
+                       // Only create object for input[text], input[password], or textarea
+            (new $.InFieldLabels(this, $field[0], options));
+        });
+    };
+       
+})(jQuery);
diff --git a/cloudcms/static/cloudcms/js/jquery.labelify.js b/cloudcms/static/cloudcms/js/jquery.labelify.js
new file mode 100644 (file)
index 0000000..8d9e228
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+ * jQuery.labelify - Display in-textbox hints
+ * Stuart Langridge, http://www.kryogenix.org/
+ * Released into the public domain
+ * Date: 25th June 2008
+ * @author Stuart Langridge
+ * @version 1.3
+ *
+ *
+ * Basic calling syntax: $("input").labelify();
+ * Defaults to taking the in-field label from the field's title attribute
+ *
+ * You can also pass an options object with the following keys:
+ *   text
+ *     "title" to get the in-field label from the field's title attribute 
+ *      (this is the default)
+ *     "label" to get the in-field label from the inner text of the field's label
+ *      (note that the label must be attached to the field with for="fieldid")
+ *     a function which takes one parameter, the input field, and returns
+ *      whatever text it likes
+ *
+ *   labelledClass
+ *     a class that will be applied to the input field when it contains the
+ *      label and removed when it contains user input. Defaults to blank.
+ *  
+ */
+jQuery.fn.labelify = function(settings) {
+  settings = jQuery.extend({
+    text: "title",
+    labelledClass: ""
+  }, settings);
+  var lookups = {
+    title: function(input) {
+      return $(input).attr("title");
+    },
+    label: function(input) {
+      return $("label[for=" + input.id +"]").text();
+    }
+  };
+  var lookup;
+  var jQuery_labellified_elements = $(this);
+  return $(this).each(function() {
+    if (typeof settings.text === "string") {
+      lookup = lookups[settings.text]; // what if not there?
+    } else {
+      lookup = settings.text; // what if not a fn?
+    };
+    // bail if lookup isn't a function or if it returns undefined
+    if (typeof lookup !== "function") { return; }
+    var lookupval = lookup(this);
+    if (!lookupval) { return; }
+
+    // need to strip newlines because the browser strips them
+    // if you set textbox.value to a string containing them    
+    $(this).data("label",lookup(this).replace(/\n/g,''));
+    $(this).focus(function() {
+      if (this.value === $(this).data("label")) {
+        this.value = this.defaultValue;
+        $(this).removeClass(settings.labelledClass);
+      }
+    }).blur(function(){
+      if (this.value === this.defaultValue) {
+        this.value = $(this).data("label");
+        $(this).addClass(settings.labelledClass);
+      }
+    });
+    
+    var removeValuesOnExit = function() {
+      jQuery_labellified_elements.each(function(){
+        if (this.value === $(this).data("label")) {
+          this.value = this.defaultValue;
+          $(this).removeClass(settings.labelledClass);
+        }
+      })
+    };
+    
+    $(this).parents("form").submit(removeValuesOnExit);
+    $(window).unload(removeValuesOnExit);
+    
+    if (this.value !== this.defaultValue) {
+      // user already started typing; don't overwrite their work!
+      return;
+    }
+    // actually set the value
+    this.value = $(this).data("label");
+    $(this).addClass(settings.labelledClass);
+
+  });
+};
diff --git a/cloudcms/static/cloudcms/js/modernizr-2.0.6.js b/cloudcms/static/cloudcms/js/modernizr-2.0.6.js
new file mode 100644 (file)
index 0000000..f9e57c8
--- /dev/null
@@ -0,0 +1,1116 @@
+/*!
+ * Modernizr v2.0.6
+ * http://www.modernizr.com
+ *
+ * Copyright (c) 2009-2011 Faruk Ates, Paul Irish, Alex Sexton
+ * Dual-licensed under the BSD or MIT licenses: www.modernizr.com/license/
+ */
+
+/*
+ * Modernizr tests which native CSS3 and HTML5 features are available in
+ * the current UA and makes the results available to you in two ways:
+ * as properties on a global Modernizr object, and as classes on the
+ * <html> element. This information allows you to progressively enhance
+ * your pages with a granular level of control over the experience.
+ *
+ * Modernizr has an optional (not included) conditional resource loader
+ * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
+ * To get a build that includes Modernizr.load(), as well as choosing
+ * which tests to include, go to www.modernizr.com/download/
+ *
+ * Authors        Faruk Ates, Paul Irish, Alex Sexton, 
+ * Contributors   Ryan Seddon, Ben Alman
+ */
+
+window.Modernizr = (function( window, document, undefined ) {
+
+    var version = '2.0.6',
+
+    Modernizr = {},
+    
+    // option for enabling the HTML classes to be added
+    enableClasses = true,
+
+    docElement = document.documentElement,
+    docHead = document.head || document.getElementsByTagName('head')[0],
+
+    /**
+     * Create our "modernizr" element that we do most feature tests on.
+     */
+    mod = 'modernizr',
+    modElem = document.createElement(mod),
+    mStyle = modElem.style,
+
+    /**
+     * Create the input element for various Web Forms feature tests.
+     */
+    inputElem = document.createElement('input'),
+
+    smile = ':)',
+
+    toString = Object.prototype.toString,
+
+    // List of property values to set for css tests. See ticket #21
+    prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
+
+    // Following spec is to expose vendor-specific style properties as:
+    //   elem.style.WebkitBorderRadius
+    // and the following would be incorrect:
+    //   elem.style.webkitBorderRadius
+
+    // Webkit ghosts their properties in lowercase but Opera & Moz do not.
+    // Microsoft foregoes prefixes entirely <= IE8, but appears to
+    //   use a lowercase `ms` instead of the correct `Ms` in IE9
+
+    // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
+    domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
+
+    ns = {'svg': 'http://www.w3.org/2000/svg'},
+
+    tests = {},
+    inputs = {},
+    attrs = {},
+
+    classes = [],
+
+    featureName, // used in testing loop
+
+
+    // Inject element with style element and some CSS rules
+    injectElementWithStyles = function( rule, callback, nodes, testnames ) {
+
+      var style, ret, node,
+          div = document.createElement('div');
+
+      if ( parseInt(nodes, 10) ) {
+          // In order not to give false positives we create a node for each test
+          // This also allows the method to scale for unspecified uses
+          while ( nodes-- ) {
+              node = document.createElement('div');
+              node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
+              div.appendChild(node);
+          }
+      }
+
+      // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
+      // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
+      // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
+      // http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
+      style = ['&shy;', '<style>', rule, '</style>'].join('');
+      div.id = mod;
+      div.innerHTML += style;
+      docElement.appendChild(div);
+
+      ret = callback(div, rule);
+      div.parentNode.removeChild(div);
+
+      return !!ret;
+
+    },
+
+
+    // adapted from matchMedia polyfill
+    // by Scott Jehl and Paul Irish
+    // gist.github.com/786768
+    testMediaQuery = function( mq ) {
+
+      if ( window.matchMedia ) {
+        return matchMedia(mq).matches;
+      }
+
+      var bool;
+
+      injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
+        bool = (window.getComputedStyle ?
+                  getComputedStyle(node, null) :
+                  node.currentStyle)['position'] == 'absolute';
+      });
+
+      return bool;
+
+     },
+
+
+    /**
+      * isEventSupported determines if a given element supports the given event
+      * function from http://yura.thinkweb2.com/isEventSupported/
+      */
+    isEventSupported = (function() {
+
+      var TAGNAMES = {
+        'select': 'input', 'change': 'input',
+        'submit': 'form', 'reset': 'form',
+        'error': 'img', 'load': 'img', 'abort': 'img'
+      };
+
+      function isEventSupported( eventName, element ) {
+
+        element = element || document.createElement(TAGNAMES[eventName] || 'div');
+        eventName = 'on' + eventName;
+
+        // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
+        var isSupported = eventName in element;
+
+        if ( !isSupported ) {
+          // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
+          if ( !element.setAttribute ) {
+            element = document.createElement('div');
+          }
+          if ( element.setAttribute && element.removeAttribute ) {
+            element.setAttribute(eventName, '');
+            isSupported = is(element[eventName], 'function');
+
+            // If property was created, "remove it" (by setting value to `undefined`)
+            if ( !is(element[eventName], undefined) ) {
+              element[eventName] = undefined;
+            }
+            element.removeAttribute(eventName);
+          }
+        }
+
+        element = null;
+        return isSupported;
+      }
+      return isEventSupported;
+    })();
+
+    // hasOwnProperty shim by kangax needed for Safari 2.0 support
+    var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
+    if ( !is(_hasOwnProperty, undefined) && !is(_hasOwnProperty.call, undefined) ) {
+      hasOwnProperty = function (object, property) {
+        return _hasOwnProperty.call(object, property);
+      };
+    }
+    else {
+      hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
+        return ((property in object) && is(object.constructor.prototype[property], undefined));
+      };
+    }
+
+    /**
+     * setCss applies given styles to the Modernizr DOM node.
+     */
+    function setCss( str ) {
+        mStyle.cssText = str;
+    }
+
+    /**
+     * setCssAll extrapolates all vendor-specific css strings.
+     */
+    function setCssAll( str1, str2 ) {
+        return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
+    }
+
+    /**
+     * is returns a boolean for if typeof obj is exactly type.
+     */
+    function is( obj, type ) {
+        return typeof obj === type;
+    }
+
+    /**
+     * contains returns a boolean for if substr is found within str.
+     */
+    function contains( str, substr ) {
+        return !!~('' + str).indexOf(substr);
+    }
+
+    /**
+     * testProps is a generic CSS / DOM property test; if a browser supports
+     *   a certain property, it won't return undefined for it.
+     *   A supported CSS property returns empty string when its not yet set.
+     */
+    function testProps( props, prefixed ) {
+        for ( var i in props ) {
+            if ( mStyle[ props[i] ] !== undefined ) {
+                return prefixed == 'pfx' ? props[i] : true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * testPropsAll tests a list of DOM properties we want to check against.
+     *   We specify literally ALL possible (known and/or likely) properties on
+     *   the element including the non-vendor prefixed one, for forward-
+     *   compatibility.
+     */
+    function testPropsAll( prop, prefixed ) {
+
+        var ucProp  = prop.charAt(0).toUpperCase() + prop.substr(1),
+            props   = (prop + ' ' + domPrefixes.join(ucProp + ' ') + ucProp).split(' ');
+
+        return testProps(props, prefixed);
+    }
+
+    /**
+     * testBundle tests a list of CSS features that require element and style injection.
+     *   By bundling them together we can reduce the need to touch the DOM multiple times.
+     */
+    /*>>testBundle*/
+    var testBundle = (function( styles, tests ) {
+        var style = styles.join(''),
+            len = tests.length;
+
+        injectElementWithStyles(style, function( node, rule ) {
+            var style = document.styleSheets[document.styleSheets.length - 1],
+                // IE8 will bork if you create a custom build that excludes both fontface and generatedcontent tests.
+                // So we check for cssRules and that there is a rule available
+                // More here: https://github.com/Modernizr/Modernizr/issues/288 & https://github.com/Modernizr/Modernizr/issues/293
+                cssText = style.cssRules && style.cssRules[0] ? style.cssRules[0].cssText : style.cssText || "",
+                children = node.childNodes, hash = {};
+
+            while ( len-- ) {
+                hash[children[len].id] = children[len];
+            }
+
+            /*>>touch*/           Modernizr['touch'] = ('ontouchstart' in window) || hash['touch'].offsetTop === 9; /*>>touch*/
+            /*>>csstransforms3d*/ Modernizr['csstransforms3d'] = hash['csstransforms3d'].offsetLeft === 9;          /*>>csstransforms3d*/
+            /*>>generatedcontent*/Modernizr['generatedcontent'] = hash['generatedcontent'].offsetHeight >= 1;       /*>>generatedcontent*/
+            /*>>fontface*/        Modernizr['fontface'] = /src/i.test(cssText) &&
+                                                                  cssText.indexOf(rule.split(' ')[0]) === 0;        /*>>fontface*/
+        }, len, tests);
+
+    })([
+        // Pass in styles to be injected into document
+        /*>>fontface*/        '@font-face {font-family:"font";src:url("https://")}'         /*>>fontface*/
+        
+        /*>>touch*/           ,['@media (',prefixes.join('touch-enabled),('),mod,')',
+                                '{#touch{top:9px;position:absolute}}'].join('')           /*>>touch*/
+                                
+        /*>>csstransforms3d*/ ,['@media (',prefixes.join('transform-3d),('),mod,')',
+                                '{#csstransforms3d{left:9px;position:absolute}}'].join('')/*>>csstransforms3d*/
+                                
+        /*>>generatedcontent*/,['#generatedcontent:after{content:"',smile,'";visibility:hidden}'].join('')  /*>>generatedcontent*/
+    ],
+      [
+        /*>>fontface*/        'fontface'          /*>>fontface*/
+        /*>>touch*/           ,'touch'            /*>>touch*/
+        /*>>csstransforms3d*/ ,'csstransforms3d'  /*>>csstransforms3d*/
+        /*>>generatedcontent*/,'generatedcontent' /*>>generatedcontent*/
+        
+    ]);/*>>testBundle*/
+
+
+    /**
+     * Tests
+     * -----
+     */
+
+    tests['flexbox'] = function() {
+        /**
+         * setPrefixedValueCSS sets the property of a specified element
+         * adding vendor prefixes to the VALUE of the property.
+         * @param {Element} element
+         * @param {string} property The property name. This will not be prefixed.
+         * @param {string} value The value of the property. This WILL be prefixed.
+         * @param {string=} extra Additional CSS to append unmodified to the end of
+         * the CSS string.
+         */
+        function setPrefixedValueCSS( element, property, value, extra ) {
+            property += ':';
+            element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
+        }
+
+        /**
+         * setPrefixedPropertyCSS sets the property of a specified element
+         * adding vendor prefixes to the NAME of the property.
+         * @param {Element} element
+         * @param {string} property The property name. This WILL be prefixed.
+         * @param {string} value The value of the property. This will not be prefixed.
+         * @param {string=} extra Additional CSS to append unmodified to the end of
+         * the CSS string.
+         */
+        function setPrefixedPropertyCSS( element, property, value, extra ) {
+            element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
+        }
+
+        var c = document.createElement('div'),
+            elem = document.createElement('div');
+
+        setPrefixedValueCSS(c, 'display', 'box', 'width:42px;padding:0;');
+        setPrefixedPropertyCSS(elem, 'box-flex', '1', 'width:10px;');
+
+        c.appendChild(elem);
+        docElement.appendChild(c);
+
+        var ret = elem.offsetWidth === 42;
+
+        c.removeChild(elem);
+        docElement.removeChild(c);
+
+        return ret;
+    };
+
+    // On the S60 and BB Storm, getContext exists, but always returns undefined
+    // http://github.com/Modernizr/Modernizr/issues/issue/97/
+
+    tests['canvas'] = function() {
+        var elem = document.createElement('canvas');
+        return !!(elem.getContext && elem.getContext('2d'));
+    };
+
+    tests['canvastext'] = function() {
+        return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
+    };
+
+    // This WebGL test may false positive. 
+    // But really it's quite impossible to know whether webgl will succeed until after you create the context. 
+    // You might have hardware that can support a 100x100 webgl canvas, but will not support a 1000x1000 webgl 
+    // canvas. So this feature inference is weak, but intentionally so.
+    
+    // It is known to false positive in FF4 with certain hardware and the iPad 2.
+    
+    tests['webgl'] = function() {
+        return !!window.WebGLRenderingContext;
+    };
+
+    /*
+     * The Modernizr.touch test only indicates if the browser supports
+     *    touch events, which does not necessarily reflect a touchscreen
+     *    device, as evidenced by tablets running Windows 7 or, alas,
+     *    the Palm Pre / WebOS (touch) phones.
+     *
+     * Additionally, Chrome (desktop) used to lie about its support on this,
+     *    but that has since been rectified: http://crbug.com/36415
+     *
+     * We also test for Firefox 4 Multitouch Support.
+     *
+     * For more info, see: http://modernizr.github.com/Modernizr/touch.html
+     */
+
+    tests['touch'] = function() {
+        return Modernizr['touch'];
+    };
+
+    /**
+     * geolocation tests for the new Geolocation API specification.
+     *   This test is a standards compliant-only test; for more complete
+     *   testing, including a Google Gears fallback, please see:
+     *   http://code.google.com/p/geo-location-javascript/
+     * or view a fallback solution using google's geo API:
+     *   http://gist.github.com/366184
+     */
+    tests['geolocation'] = function() {
+        return !!navigator.geolocation;
+    };
+
+    // Per 1.6:
+    // This used to be Modernizr.crosswindowmessaging but the longer
+    // name has been deprecated in favor of a shorter and property-matching one.
+    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
+    // and in the first release thereafter disappear entirely.
+    tests['postmessage'] = function() {
+      return !!window.postMessage;
+    };
+
+    // Web SQL database detection is tricky:
+
+    // In chrome incognito mode, openDatabase is truthy, but using it will
+    //   throw an exception: http://crbug.com/42380
+    // We can create a dummy database, but there is no way to delete it afterwards.
+
+    // Meanwhile, Safari users can get prompted on any database creation.
+    //   If they do, any page with Modernizr will give them a prompt:
+    //   http://github.com/Modernizr/Modernizr/issues/closed#issue/113
+
+    // We have chosen to allow the Chrome incognito false positive, so that Modernizr
+    //   doesn't litter the web with these test databases. As a developer, you'll have
+    //   to account for this gotcha yourself.
+    tests['websqldatabase'] = function() {
+      var result = !!window.openDatabase;
+      /*  if (result){
+            try {
+              result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
+            } catch(e) {
+            }
+          }  */
+      return result;
+    };
+
+    // Vendors had inconsistent prefixing with the experimental Indexed DB:
+    // - Webkit's implementation is accessible through webkitIndexedDB
+    // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
+    // For speed, we don't test the legacy (and beta-only) indexedDB
+    tests['indexedDB'] = function() {
+      for ( var i = -1, len = domPrefixes.length; ++i < len; ){
+        if ( window[domPrefixes[i].toLowerCase() + 'IndexedDB'] ){
+          return true;
+        }
+      }
+      return !!window.indexedDB;
+    };
+
+    // documentMode logic from YUI to filter out IE8 Compat Mode
+    //   which false positives.
+    tests['hashchange'] = function() {
+      return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
+    };
+
+    // Per 1.6:
+    // This used to be Modernizr.historymanagement but the longer
+    // name has been deprecated in favor of a shorter and property-matching one.
+    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
+    // and in the first release thereafter disappear entirely.
+    tests['history'] = function() {
+      return !!(window.history && history.pushState);
+    };
+
+    tests['draganddrop'] = function() {
+        return isEventSupported('dragstart') && isEventSupported('drop');
+    };
+
+    // Mozilla is targeting to land MozWebSocket for FF6
+    // bugzil.la/659324
+    tests['websockets'] = function() {
+        for ( var i = -1, len = domPrefixes.length; ++i < len; ){
+          if ( window[domPrefixes[i] + 'WebSocket'] ){
+            return true;
+          }
+        }
+        return 'WebSocket' in window;
+    };
+
+
+    // http://css-tricks.com/rgba-browser-support/
+    tests['rgba'] = function() {
+        // Set an rgba() color and check the returned value
+
+        setCss('background-color:rgba(150,255,150,.5)');
+
+        return contains(mStyle.backgroundColor, 'rgba');
+    };
+
+    tests['hsla'] = function() {
+        // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
+        //   except IE9 who retains it as hsla
+
+        setCss('background-color:hsla(120,40%,100%,.5)');
+
+        return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
+    };
+
+    tests['multiplebgs'] = function() {
+        // Setting multiple images AND a color on the background shorthand property
+        //  and then querying the style.background property value for the number of
+        //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
+
+        setCss('background:url(https://),url(https://),red url(https://)');
+
+        // If the UA supports multiple backgrounds, there should be three occurrences
+        //   of the string "url(" in the return value for elemStyle.background
+
+        return /(url\s*\(.*?){3}/.test(mStyle.background);
+    };
+
+
+    // In testing support for a given CSS property, it's legit to test:
+    //    `elem.style[styleName] !== undefined`
+    // If the property is supported it will return an empty string,
+    // if unsupported it will return undefined.
+
+    // We'll take advantage of this quick test and skip setting a style
+    // on our modernizr element, but instead just testing undefined vs
+    // empty string.
+
+
+    tests['backgroundsize'] = function() {
+        return testPropsAll('backgroundSize');
+    };
+
+    tests['borderimage'] = function() {
+        return testPropsAll('borderImage');
+    };
+
+
+    // Super comprehensive table about all the unique implementations of
+    // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
+
+    tests['borderradius'] = function() {
+        return testPropsAll('borderRadius');
+    };
+
+    // WebOS unfortunately false positives on this test.
+    tests['boxshadow'] = function() {
+        return testPropsAll('boxShadow');
+    };
+
+    // FF3.0 will false positive on this test
+    tests['textshadow'] = function() {
+        return document.createElement('div').style.textShadow === '';
+    };
+
+
+    tests['opacity'] = function() {
+        // Browsers that actually have CSS Opacity implemented have done so
+        //  according to spec, which means their return values are within the
+        //  range of [0.0,1.0] - including the leading zero.
+
+        setCssAll('opacity:.55');
+
+        // The non-literal . in this regex is intentional:
+        //   German Chrome returns this value as 0,55
+        // https://github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
+        return /^0.55$/.test(mStyle.opacity);
+    };
+
+
+    tests['cssanimations'] = function() {
+        return testPropsAll('animationName');
+    };
+
+
+    tests['csscolumns'] = function() {
+        return testPropsAll('columnCount');
+    };
+
+
+    tests['cssgradients'] = function() {
+        /**
+         * For CSS Gradients syntax, please see:
+         * http://webkit.org/blog/175/introducing-css-gradients/
+         * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
+         * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
+         * http://dev.w3.org/csswg/css3-images/#gradients-
+         */
+
+        var str1 = 'background-image:',
+            str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
+            str3 = 'linear-gradient(left top,#9f9, white);';
+
+        setCss(
+            (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0, -str1.length)
+        );
+
+        return contains(mStyle.backgroundImage, 'gradient');
+    };
+
+
+    tests['cssreflections'] = function() {
+        return testPropsAll('boxReflect');
+    };
+
+
+    tests['csstransforms'] = function() {
+        return !!testProps(['transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform']);
+    };
+
+
+    tests['csstransforms3d'] = function() {
+
+        var ret = !!testProps(['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']);
+
+        // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
+        //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
+        //   some conditions. As a result, Webkit typically recognizes the syntax but
+        //   will sometimes throw a false positive, thus we must do a more thorough check:
+        if ( ret && 'webkitPerspective' in docElement.style ) {
+
+          // Webkit allows this media query to succeed only if the feature is enabled.
+          // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }`
+          ret = Modernizr['csstransforms3d'];
+        }
+        return ret;
+    };
+
+
+    tests['csstransitions'] = function() {
+        return testPropsAll('transitionProperty');
+    };
+
+
+    /*>>fontface*/
+    // @font-face detection routine by Diego Perini
+    // http://javascript.nwbox.com/CSSSupport/
+    tests['fontface'] = function() {
+        return Modernizr['fontface'];
+    };
+    /*>>fontface*/
+
+    // CSS generated content detection
+    tests['generatedcontent'] = function() {
+        return Modernizr['generatedcontent'];
+    };
+
+
+
+    // These tests evaluate support of the video/audio elements, as well as
+    // testing what types of content they support.
+    //
+    // We're using the Boolean constructor here, so that we can extend the value
+    // e.g.  Modernizr.video     // true
+    //       Modernizr.video.ogg // 'probably'
+    //
+    // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
+    //                     thx to NielsLeenheer and zcorpan
+
+    // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
+    //   Modernizr does not normalize for that.
+
+    tests['video'] = function() {
+        var elem = document.createElement('video'),
+            bool = false;
+            
+        // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
+        try {
+            if ( bool = !!elem.canPlayType ) {
+                bool      = new Boolean(bool);
+                bool.ogg  = elem.canPlayType('video/ogg; codecs="theora"');
+
+                // Workaround required for IE9, which doesn't report video support without audio codec specified.
+                //   bug 599718 @ msft connect
+                var h264 = 'video/mp4; codecs="avc1.42E01E';
+                bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
+
+                bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
+            }
+            
+        } catch(e) { }
+        
+        return bool;
+    };
+
+    tests['audio'] = function() {
+        var elem = document.createElement('audio'),
+            bool = false;
+
+        try { 
+            if ( bool = !!elem.canPlayType ) {
+                bool      = new Boolean(bool);
+                bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"');
+                bool.mp3  = elem.canPlayType('audio/mpeg;');
+
+                // Mimetypes accepted:
+                //   https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
+                //   http://bit.ly/iphoneoscodecs
+                bool.wav  = elem.canPlayType('audio/wav; codecs="1"');
+                bool.m4a  = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
+            }
+        } catch(e) { }
+        
+        return bool;
+    };
+
+
+    // Firefox has made these tests rather unfun.
+
+    // In FF4, if disabled, window.localStorage should === null.
+
+    // Normally, we could not test that directly and need to do a
+    //   `('localStorage' in window) && ` test first because otherwise Firefox will
+    //   throw http://bugzil.la/365772 if cookies are disabled
+
+    // However, in Firefox 4 betas, if dom.storage.enabled == false, just mentioning
+    //   the property will throw an exception. http://bugzil.la/599479
+    // This looks to be fixed for FF4 Final.
+
+    // Because we are forced to try/catch this, we'll go aggressive.
+
+    // FWIW: IE8 Compat mode supports these features completely:
+    //   http://www.quirksmode.org/dom/html5.html
+    // But IE8 doesn't support either with local files
+
+    tests['localstorage'] = function() {
+        try {
+            return !!localStorage.getItem;
+        } catch(e) {
+            return false;
+        }
+    };
+
+    tests['sessionstorage'] = function() {
+        try {
+            return !!sessionStorage.getItem;
+        } catch(e){
+            return false;
+        }
+    };
+
+
+    tests['webworkers'] = function() {
+        return !!window.Worker;
+    };
+
+
+    tests['applicationcache'] = function() {
+        return !!window.applicationCache;
+    };
+
+
+    // Thanks to Erik Dahlstrom
+    tests['svg'] = function() {
+        return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
+    };
+
+    // specifically for SVG inline in HTML, not within XHTML
+    // test page: paulirish.com/demo/inline-svg
+    tests['inlinesvg'] = function() {
+      var div = document.createElement('div');
+      div.innerHTML = '<svg/>';
+      return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
+    };
+
+    // Thanks to F1lt3r and lucideer, ticket #35
+    tests['smil'] = function() {
+        return !!document.createElementNS && /SVG/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
+    };
+
+    tests['svgclippaths'] = function() {
+        // Possibly returns a false positive in Safari 3.2?
+        return !!document.createElementNS && /SVG/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
+    };
+
+    // input features and input types go directly onto the ret object, bypassing the tests loop.
+    // Hold this guy to execute in a moment.
+    function webforms() {
+        // Run through HTML5's new input attributes to see if the UA understands any.
+        // We're using f which is the <input> element created early on
+        // Mike Taylr has created a comprehensive resource for testing these attributes
+        //   when applied to all input types:
+        //   http://miketaylr.com/code/input-type-attr.html
+        // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
+        
+        // Only input placeholder is tested while textarea's placeholder is not. 
+        // Currently Safari 4 and Opera 11 have support only for the input placeholder
+        // Both tests are available in feature-detects/forms-placeholder.js
+        Modernizr['input'] = (function( props ) {
+            for ( var i = 0, len = props.length; i < len; i++ ) {
+                attrs[ props[i] ] = !!(props[i] in inputElem);
+            }
+            return attrs;
+        })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
+
+        // Run through HTML5's new input types to see if the UA understands any.
+        //   This is put behind the tests runloop because it doesn't return a
+        //   true/false like all the other tests; instead, it returns an object
+        //   containing each input type with its corresponding true/false value
+
+        // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
+        Modernizr['inputtypes'] = (function(props) {
+
+            for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
+
+                inputElem.setAttribute('type', inputElemType = props[i]);
+                bool = inputElem.type !== 'text';
+
+                // We first check to see if the type we give it sticks..
+                // If the type does, we feed it a textual value, which shouldn't be valid.
+                // If the value doesn't stick, we know there's input sanitization which infers a custom UI
+                if ( bool ) {
+
+                    inputElem.value         = smile;
+                    inputElem.style.cssText = 'position:absolute;visibility:hidden;';
+
+                    if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
+
+                      docElement.appendChild(inputElem);
+                      defaultView = document.defaultView;
+
+                      // Safari 2-4 allows the smiley as a value, despite making a slider
+                      bool =  defaultView.getComputedStyle &&
+                              defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
+                              // Mobile android web browser has false positive, so must
+                              // check the height to see if the widget is actually there.
+                              (inputElem.offsetHeight !== 0);
+
+                      docElement.removeChild(inputElem);
+
+                    } else if ( /^(search|tel)$/.test(inputElemType) ){
+                      // Spec doesnt define any special parsing or detectable UI
+                      //   behaviors so we pass these through as true
+
+                      // Interestingly, opera fails the earlier test, so it doesn't
+                      //  even make it here.
+
+                    } else if ( /^(url|email)$/.test(inputElemType) ) {
+                      // Real url and email support comes with prebaked validation.
+                      bool = inputElem.checkValidity && inputElem.checkValidity() === false;
+
+                    } else if ( /^color$/.test(inputElemType) ) {
+                        // chuck into DOM and force reflow for Opera bug in 11.00
+                        // github.com/Modernizr/Modernizr/issues#issue/159
+                        docElement.appendChild(inputElem);
+                        docElement.offsetWidth;
+                        bool = inputElem.value != smile;
+                        docElement.removeChild(inputElem);
+
+                    } else {
+                      // If the upgraded input compontent rejects the :) text, we got a winner
+                      bool = inputElem.value != smile;
+                    }
+                }
+
+                inputs[ props[i] ] = !!bool;
+            }
+            return inputs;
+        })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
+    }
+
+
+    // End of test definitions
+    // -----------------------
+
+
+
+    // Run through all tests and detect their support in the current UA.
+    // todo: hypothetically we could be doing an array of tests and use a basic loop here.
+    for ( var feature in tests ) {
+        if ( hasOwnProperty(tests, feature) ) {
+            // run the test, throw the return value into the Modernizr,
+            //   then based on that boolean, define an appropriate className
+            //   and push it into an array of classes we'll join later.
+            featureName  = feature.toLowerCase();
+            Modernizr[featureName] = tests[feature]();
+
+            classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
+        }
+    }
+
+    // input tests need to run.
+    Modernizr.input || webforms();
+
+
+    /**
+     * addTest allows the user to define their own feature tests
+     * the result will be added onto the Modernizr object,
+     * as well as an appropriate className set on the html element
+     *
+     * @param feature - String naming the feature
+     * @param test - Function returning true if feature is supported, false if not
+     */
+     Modernizr.addTest = function ( feature, test ) {
+       if ( typeof feature == "object" ) {
+         for ( var key in feature ) {
+           if ( hasOwnProperty( feature, key ) ) { 
+             Modernizr.addTest( key, feature[ key ] );
+           }
+         }
+       } else {
+
+         feature = feature.toLowerCase();
+
+         if ( Modernizr[feature] !== undefined ) {
+           // we're going to quit if you're trying to overwrite an existing test
+           // if we were to allow it, we'd do this:
+           //   var re = new RegExp("\\b(no-)?" + feature + "\\b");  
+           //   docElement.className = docElement.className.replace( re, '' );
+           // but, no rly, stuff 'em.
+           return; 
+         }
+
+         test = typeof test == "boolean" ? test : !!test();
+
+         docElement.className += ' ' + (test ? '' : 'no-') + feature;
+         Modernizr[feature] = test;
+
+       }
+
+       return Modernizr; // allow chaining.
+     };
+    
+
+    // Reset modElem.cssText to nothing to reduce memory footprint.
+    setCss('');
+    modElem = inputElem = null;
+
+    //>>BEGIN IEPP
+    // Enable HTML 5 elements for styling (and printing) in IE.
+    if ( window.attachEvent && (function(){ var elem = document.createElement('div');
+                                            elem.innerHTML = '<elem></elem>';
+                                            return elem.childNodes.length !== 1; })() ) {
+                                              
+        // iepp v2 by @jon_neal & afarkas : github.com/aFarkas/iepp/
+        (function(win, doc) {
+          win.iepp = win.iepp || {};
+          var iepp = win.iepp,
+            elems = iepp.html5elements || 'abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video',
+            elemsArr = elems.split('|'),
+            elemsArrLen = elemsArr.length,
+            elemRegExp = new RegExp('(^|\\s)('+elems+')', 'gi'),
+            tagRegExp = new RegExp('<(\/*)('+elems+')', 'gi'),
+            filterReg = /^\s*[\{\}]\s*$/,
+            ruleRegExp = new RegExp('(^|[^\\n]*?\\s)('+elems+')([^\\n]*)({[\\n\\w\\W]*?})', 'gi'),
+            docFrag = doc.createDocumentFragment(),
+            html = doc.documentElement,
+            head = html.firstChild,
+            bodyElem = doc.createElement('body'),
+            styleElem = doc.createElement('style'),
+            printMedias = /print|all/,
+            body;
+          function shim(doc) {
+            var a = -1;
+            while (++a < elemsArrLen)
+              // Use createElement so IE allows HTML5-named elements in a document
+              doc.createElement(elemsArr[a]);
+          }
+
+          iepp.getCSS = function(styleSheetList, mediaType) {
+            if(styleSheetList+'' === undefined){return '';}
+            var a = -1,
+              len = styleSheetList.length,
+              styleSheet,
+              cssTextArr = [];
+            while (++a < len) {
+              styleSheet = styleSheetList[a];
+              //currently no test for disabled/alternate stylesheets
+              if(styleSheet.disabled){continue;}
+              mediaType = styleSheet.media || mediaType;
+              // Get css from all non-screen stylesheets and their imports
+              if (printMedias.test(mediaType)) cssTextArr.push(iepp.getCSS(styleSheet.imports, mediaType), styleSheet.cssText);
+              //reset mediaType to all with every new *not imported* stylesheet
+              mediaType = 'all';
+            }
+            return cssTextArr.join('');
+          };
+
+          iepp.parseCSS = function(cssText) {
+            var cssTextArr = [],
+              rule;
+            while ((rule = ruleRegExp.exec(cssText)) != null){
+              // Replace all html5 element references with iepp substitute classnames
+              cssTextArr.push(( (filterReg.exec(rule[1]) ? '\n' : rule[1]) +rule[2]+rule[3]).replace(elemRegExp, '$1.iepp_$2')+rule[4]);
+            }
+            return cssTextArr.join('\n');
+          };
+
+          iepp.writeHTML = function() {
+            var a = -1;
+            body = body || doc.body;
+            while (++a < elemsArrLen) {
+              var nodeList = doc.getElementsByTagName(elemsArr[a]),
+                nodeListLen = nodeList.length,
+                b = -1;
+              while (++b < nodeListLen)
+                if (nodeList[b].className.indexOf('iepp_') < 0)
+                  // Append iepp substitute classnames to all html5 elements
+                  nodeList[b].className += ' iepp_'+elemsArr[a];
+            }
+            docFrag.appendChild(body);
+            html.appendChild(bodyElem);
+            // Write iepp substitute print-safe document
+            bodyElem.className = body.className;
+            bodyElem.id = body.id;
+            // Replace HTML5 elements with <font> which is print-safe and shouldn't conflict since it isn't part of html5
+            bodyElem.innerHTML = body.innerHTML.replace(tagRegExp, '<$1font');
+          };
+
+
+          iepp._beforePrint = function() {
+            // Write iepp custom print CSS
+            styleElem.styleSheet.cssText = iepp.parseCSS(iepp.getCSS(doc.styleSheets, 'all'));
+            iepp.writeHTML();
+          };
+
+          iepp.restoreHTML = function(){
+            // Undo everything done in onbeforeprint
+            bodyElem.innerHTML = '';
+            html.removeChild(bodyElem);
+            html.appendChild(body);
+          };
+
+          iepp._afterPrint = function(){
+            // Undo everything done in onbeforeprint
+            iepp.restoreHTML();
+            styleElem.styleSheet.cssText = '';
+          };
+
+
+
+          // Shim the document and iepp fragment
+          shim(doc);
+          shim(docFrag);
+
+          //
+          if(iepp.disablePP){return;}
+
+          // Add iepp custom print style element
+          head.insertBefore(styleElem, head.firstChild);
+          styleElem.media = 'print';
+          styleElem.className = 'iepp-printshim';
+          win.attachEvent(
+            'onbeforeprint',
+            iepp._beforePrint
+          );
+          win.attachEvent(
+            'onafterprint',
+            iepp._afterPrint
+          );
+        })(window, document);
+    }
+    //>>END IEPP
+
+    // Assign private properties to the return object with prefix
+    Modernizr._version      = version;
+
+    // expose these for the plugin API. Look in the source for how to join() them against your input
+    Modernizr._prefixes     = prefixes;
+    Modernizr._domPrefixes  = domPrefixes;
+    
+    // Modernizr.mq tests a given media query, live against the current state of the window
+    // A few important notes:
+    //   * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
+    //   * A max-width or orientation query will be evaluated against the current state, which may change later.
+    //   * You must specify values. Eg. If you are testing support for the min-width media query use: 
+    //       Modernizr.mq('(min-width:0)')
+    // usage:
+    // Modernizr.mq('only screen and (max-width:768)')
+    Modernizr.mq            = testMediaQuery;   
+    
+    // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
+    // Modernizr.hasEvent('gesturestart', elem)
+    Modernizr.hasEvent      = isEventSupported; 
+
+    // Modernizr.testProp() investigates whether a given style property is recognized
+    // Note that the property names must be provided in the camelCase variant.
+    // Modernizr.testProp('pointerEvents')
+    Modernizr.testProp      = function(prop){
+        return testProps([prop]);
+    };        
+
+    // Modernizr.testAllProps() investigates whether a given style property,
+    //   or any of its vendor-prefixed variants, is recognized
+    // Note that the property names must be provided in the camelCase variant.
+    // Modernizr.testAllProps('boxSizing')    
+    Modernizr.testAllProps  = testPropsAll;     
+
+
+    
+    // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
+    // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
+    Modernizr.testStyles    = injectElementWithStyles; 
+
+
+    // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
+    // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
+    
+    // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
+    // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
+    //
+    //     str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
+    
+    // If you're trying to ascertain which transition end event to bind to, you might do something like...
+    // 
+    //     var transEndEventNames = {
+    //       'WebkitTransition' : 'webkitTransitionEnd',
+    //       'MozTransition'    : 'transitionend',
+    //       'OTransition'      : 'oTransitionEnd',
+    //       'msTransition'     : 'msTransitionEnd', // maybe?
+    //       'transition'       : 'transitionEnd'
+    //     },
+    //     transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
+    
+    Modernizr.prefixed      = function(prop){
+      return testPropsAll(prop, 'pfx');
+    };
+
+
+
+    // Remove "no-js" class from <html> element, if it exists:
+    docElement.className = docElement.className.replace(/\bno-js\b/, '')
+                            
+                            // Add the new classes to the <html> element.
+                            + (enableClasses ? ' js ' + classes.join(' ') : '');
+
+    return Modernizr;
+
+})(this, this.document);
diff --git a/cloudcms/static/cloudcms/js/servicesbar.js b/cloudcms/static/cloudcms/js/servicesbar.js
new file mode 100644 (file)
index 0000000..cadfd0e
--- /dev/null
@@ -0,0 +1,85 @@
+$(document).ready(function(){
+    
+    // jquery cookie plugin, code shared from
+    var cookie=function(key,value,options){if(arguments.length>1&&(!/Object/.test(Object.prototype.toString.call(value))||value===null||value===undefined)){options=$.extend({},options);if(value===null||value===undefined){options.expires=-1}if(typeof options.expires==='number'){var days=options.expires,t=options.expires=new Date();t.setDate(t.getDate()+days)}value=String(value);return(document.cookie=[encodeURIComponent(key),'=',options.raw?value:encodeURIComponent(value),options.expires?'; expires='+options.expires.toUTCString():'',options.path?'; path='+options.path:'',options.domain?'; domain='+options.domain:'',options.secure?'; secure':''].join(''))}options=value||{};var decode=options.raw?function(s){return s}:decodeURIComponent;var pairs=document.cookie.split('; ');for(var i=0,pair;pair=pairs[i]&&pairs[i].split('=');i++){if(decode(pair[0])===key)return decode(pair[1]||'')}return null};
+
+    var ACTIVE_MENU = window.TOPBAR_ACTIVE_SERVICE || 'cloud';
+    var USER_DATA = window.TOPBAR_USER_DATA || {'user': 'test@grnet.gr', 'logged_in': false};
+
+    var TOPBAR_LOC = "http://servicesbar.cloud.grnet.gr/";
+    
+    // load css
+    var css = $("<link />");
+    css.attr({rel:'stylesheet', type:'text/css', href:TOPBAR_LOC + 'servicesbar.css'});
+    $("head").append(css);
+
+    // load service specific css
+    var SKIP_ADDITIONAL_CSS = window.SKIP_ADDITIONAL_CSS == undefined ? false : window.SKIP_ADDITIONAL_CSS;
+
+    if (!SKIP_ADDITIONAL_CSS) {
+        var css = $("<link />");
+        css.attr({rel:'stylesheet', type:'text/css', href:TOPBAR_LOC + ACTIVE_MENU + '.css'});
+        $("head").append(css);
+    }
+
+    var root = $('body');
+    var bar = $('<div class="servicesbar"></div>');
+    var services = $('<div class="services"></div>');
+    var profile = $('<div class="profile"></div>');
+    
+    var SERVICES_LINKS = {
+        'cloud':   { url:'http://cloud.grnet.gr/', name:'grnet cloud', id:'cloud', icon:'home-icon.png' },
+        'okeanos': { url:'http://okeanos.cloud.grnet.gr', name:'~okeanos', id:'okeanos' },
+        'pithos':  { url:'http://pithos.cloud.grnet.gr', name:'pithos+', id:'pithos' },
+    };
+    
+    var PROFILE_URL = "https://accounts.cloud.grnet.gr";
+
+    var home_icon_data = "";
+    var PROFILE_LINKS = {
+        'login': { url: '/accounts/login', auth:false, name: "login..." },
+        'forgot_pass': { url: '/accounts/recover', auth:false, name: "recover your password..." },
+        'profile': { url: '/accounts/myprofile', auth:true, name: "my profile..." },
+        'change_pass': { url: '/accounts/changepassword', auth:true, name: "change your password..." },
+        'invitations': { url: '/accounts/invitations', auth:true, name: "invite some friends..." },
+    };
+
+    $.each(SERVICES_LINKS, function(i, el){
+        var slink = $("<a>");
+        if (el.icon) {
+            slink.append($('<img src="'+TOPBAR_LOC+el.icon+'"/>'));
+        } else {
+            slink.text(el.name);
+        }
+        slink.attr('href', el.url);
+        slink.attr('title', el.name);
+        services.append(slink);
+        if (el.id == ACTIVE_MENU) {
+            slink.addClass("active");
+        }
+    });
+    
+    // user profile menu
+    var USERNAME = USER_DATA.user;
+    var LOGGED_IN = USER_DATA.logged_in;
+
+    var user = $('<div class="user"></div>');
+    var username = $('<a href="#"></a>');
+    username.text(USERNAME);
+    var usermenu = $("<ul>");
+
+    $.each(PROFILE_LINKS, function(i,el) {
+        var li = $("<li />");
+        var link = $("<a />");
+        link.text(el.name);
+        link.attr({href:el.url});
+        li.append(link);
+        usermenu.append(li);
+    });
+    
+    user.append(username);
+    user.append(usermenu);
+    profile.append(user);
+    bar.append(services).append(profile);
+    root.prepend(bar);
+});
diff --git a/cloudcms/static/cloudcms/js/twitter/ba-linkify.js b/cloudcms/static/cloudcms/js/twitter/ba-linkify.js
new file mode 100644 (file)
index 0000000..81dae5f
--- /dev/null
@@ -0,0 +1,214 @@
+/*!
+ * JavaScript Linkify - v0.3 - 6/27/2009
+ * http://benalman.com/projects/javascript-linkify/
+ * 
+ * Copyright (c) 2009 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ * 
+ * Some regexps adapted from http://userscripts.org/scripts/review/7122
+ */
+
+// Script: JavaScript Linkify: Process links in text!
+//
+// *Version: 0.3, Last updated: 6/27/2009*
+// 
+// Project Home - http://benalman.com/projects/javascript-linkify/
+// GitHub       - http://github.com/cowboy/javascript-linkify/
+// Source       - http://github.com/cowboy/javascript-linkify/raw/master/ba-linkify.js
+// (Minified)   - http://github.com/cowboy/javascript-linkify/raw/master/ba-linkify.min.js (2.8kb)
+// 
+// About: License
+// 
+// Copyright (c) 2009 "Cowboy" Ben Alman,
+// Dual licensed under the MIT and GPL licenses.
+// http://benalman.com/about/license/
+// 
+// About: Examples
+// 
+// This working example, complete with fully commented code, illustrates one way
+// in which this code can be used.
+// 
+// Linkify - http://benalman.com/code/projects/javascript-linkify/examples/linkify/
+// 
+// About: Support and Testing
+// 
+// Information about what browsers this code has been tested in.
+// 
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome, Opera 9.6-10.
+// 
+// About: Release History
+// 
+// 0.3 - (6/27/2009) Initial release
+
+// Function: linkify
+// 
+// Turn text into linkified html.
+// 
+// Usage:
+// 
+//  > var html = linkify( text [, options ] );
+// 
+// Arguments:
+// 
+//  text - (String) Non-HTML text containing links to be parsed.
+//  options - (Object) An optional object containing linkify parse options.
+// 
+// Options:
+// 
+//  callback (Function) - If specified, this will be called once for each link-
+//    or non-link-chunk with two arguments, text and href. If the chunk is
+//    non-link, href will be omitted. If unspecified, the default linkification
+//    callback is used.
+//  punct_regexp (RegExp) - A RegExp that will be used to trim trailing
+//    punctuation from links, instead of the default. If set to null, trailing
+//    punctuation will not be trimmed.
+// 
+// Returns:
+// 
+//  (String) An HTML string containing links.
+
+window.linkify = (function(){
+  var
+    SCHEME = "[a-z\\d.-]+://",
+    IPV4 = "(?:(?:[0-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}(?:[0-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])",
+    HOSTNAME = "(?:(?:[^\\s!@#$%^&*()_=+[\\]{}\\\\|;:'\",.<>/?]+)\\.)+",
+    TLD = "(?:ac|ad|aero|ae|af|ag|ai|al|am|an|ao|aq|arpa|ar|asia|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|biz|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|cat|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|coop|com|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|info|int|in|io|iq|ir|is|it|je|jm|jobs|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mobi|mo|mp|mq|mr|ms|mt|museum|mu|mv|mw|mx|my|mz|name|na|nc|net|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pro|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm|tn|to|tp|travel|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|xn--0zwm56d|xn--11b5bs3a9aj6g|xn--80akhbyknj4f|xn--9t4b11yi5a|xn--deba0ad|xn--g6w251d|xn--hgbk6aj7f53bba|xn--hlcj6aya9esc7a|xn--jxalpdlp|xn--kgbechtv|xn--zckzah|ye|yt|yu|za|zm|zw)",
+    HOST_OR_IP = "(?:" + HOSTNAME + TLD + "|" + IPV4 + ")",
+    PATH = "(?:[;/][^#?<>\\s]*)?",
+    QUERY_FRAG = "(?:\\?[^#<>\\s]*)?(?:#[^<>\\s]*)?",
+    URI1 = "\\b" + SCHEME + "[^<>\\s]+",
+    URI2 = "\\b" + HOST_OR_IP + PATH + QUERY_FRAG + "(?!\\w)",
+    
+    MAILTO = "mailto:",
+    EMAIL = "(?:" + MAILTO + ")?[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@" + HOST_OR_IP + QUERY_FRAG + "(?!\\w)",
+    
+    URI_RE = new RegExp( "(?:" + URI1 + "|" + URI2 + "|" + EMAIL + ")", "ig" ),
+    SCHEME_RE = new RegExp( "^" + SCHEME, "i" ),
+    
+    quotes = {
+      "'": "`",
+      '>': '<',
+      ')': '(',
+      ']': '[',
+      '}': '{',
+      '»': '«',
+      '›': '‹'
+    },
+    
+    default_options = {
+      callback: function( text, href ) {
+        return href ? '<a href="' + href + '" title="' + href + '">' + text + '</a>' : text;
+      },
+      punct_regexp: /(?:[!?.,:;'"]|(?:&|&amp;)(?:lt|gt|quot|apos|raquo|laquo|rsaquo|lsaquo);)$/
+    };
+  
+  return function( txt, options ) {
+    options = options || {};
+    
+    // Temp variables.
+    var arr,
+      i,
+      link,
+      href,
+      
+      // Output HTML.
+      html = '',
+      
+      // Store text / link parts, in order, for re-combination.
+      parts = [],
+      
+      // Used for keeping track of indices in the text.
+      idx_prev,
+      idx_last,
+      idx,
+      link_last,
+      
+      // Used for trimming trailing punctuation and quotes from links.
+      matches_begin,
+      matches_end,
+      quote_begin,
+      quote_end;
+    
+    // Initialize options.
+    for ( i in default_options ) {
+      if ( options[ i ] === undefined ) {
+        options[ i ] = default_options[ i ];
+      }
+    }
+    
+    // Find links.
+    while ( arr = URI_RE.exec( txt ) ) {
+      
+      link = arr[0];
+      idx_last = URI_RE.lastIndex;
+      idx = idx_last - link.length;
+      
+      // Not a link if preceded by certain characters.
+      if ( /[\/:]/.test( txt.charAt( idx - 1 ) ) ) {
+        continue;
+      }
+      
+      // Trim trailing punctuation.
+      do {
+        // If no changes are made, we don't want to loop forever!
+        link_last = link;
+        
+        quote_end = link.substr( -1 )
+        quote_begin = quotes[ quote_end ];
+        
+        // Ending quote character?
+        if ( quote_begin ) {
+          matches_begin = link.match( new RegExp( '\\' + quote_begin + '(?!$)', 'g' ) );
+          matches_end = link.match( new RegExp( '\\' + quote_end, 'g' ) );
+          
+          // If quotes are unbalanced, remove trailing quote character.
+          if ( ( matches_begin ? matches_begin.length : 0 ) < ( matches_end ? matches_end.length : 0 ) ) {
+            link = link.substr( 0, link.length - 1 );
+            idx_last--;
+          }
+        }
+        
+        // Ending non-quote punctuation character?
+        if ( options.punct_regexp ) {
+          link = link.replace( options.punct_regexp, function(a){
+            idx_last -= a.length;
+            return '';
+          });
+        }
+      } while ( link.length && link !== link_last );
+      
+      href = link;
+      
+      // Add appropriate protocol to naked links.
+      if ( !SCHEME_RE.test( href ) ) {
+        href = ( href.indexOf( '@' ) !== -1 ? ( !href.indexOf( MAILTO ) ? '' : MAILTO )
+          : !href.indexOf( 'irc.' ) ? 'irc://'
+          : !href.indexOf( 'ftp.' ) ? 'ftp://'
+          : 'http://' )
+          + href;
+      }
+      
+      // Push preceding non-link text onto the array.
+      if ( idx_prev != idx ) {
+        parts.push([ txt.slice( idx_prev, idx ) ]);
+        idx_prev = idx_last;
+      }
+      
+      // Push massaged link onto the array
+      parts.push([ link, href ]);
+    };
+    
+    // Push remaining non-link text onto the array.
+    parts.push([ txt.substr( idx_prev ) ]);
+    
+    // Process the array items.
+    for ( i = 0; i < parts.length; i++ ) {
+      html += options.callback.apply( window, parts[i] );
+    }
+    
+    // In case of catastrophic failure, return the original text;
+    return html || txt;
+  };
+  
+})();
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/js/twitter/jquery.timeago.js b/cloudcms/static/cloudcms/js/twitter/jquery.timeago.js
new file mode 100644 (file)
index 0000000..24ac69c
--- /dev/null
@@ -0,0 +1,146 @@
+/**
+ * Timeago is a jQuery plugin that makes it easy to support automatically
+ * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
+ *
+ * @name timeago
+ * @version 0.10.0
+ * @requires jQuery v1.2.3+
+ * @author Ryan McGeary
+ * @license MIT License - http://www.opensource.org/licenses/mit-license.php
+ *
+ * For usage and examples, visit:
+ * http://timeago.yarp.com/
+ *
+ * Copyright (c) 2008-2011, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
+ */
+(function($) {
+  $.timeago = function(timestamp) {
+    if (timestamp instanceof Date) {
+      return inWords(timestamp);
+    } else if (typeof timestamp === "string") {
+      return inWords($.timeago.parse(timestamp));
+    } else {
+      return inWords($.timeago.datetime(timestamp));
+    }
+  };
+  var $t = $.timeago;
+
+  $.extend($.timeago, {
+    settings: {
+      refreshMillis: 60000,
+      allowFuture: false,
+      strings: {
+        prefixAgo: null,
+        prefixFromNow: null,
+        suffixAgo: "ago",
+        suffixFromNow: "from now",
+        seconds: "less than a minute",
+        minute: "about a minute",
+        minutes: "%d minutes",
+        hour: "about an hour",
+        hours: "about %d hours",
+        day: "a day",
+        days: "%d days",
+        month: "about a month",
+        months: "%d months",
+        year: "about a year",
+        years: "%d years",
+        numbers: []
+      }
+    },
+    inWords: function(distanceMillis) {
+      var $l = this.settings.strings;
+      var prefix = $l.prefixAgo;
+      var suffix = $l.suffixAgo;
+      if (this.settings.allowFuture) {
+        if (distanceMillis < 0) {
+          prefix = $l.prefixFromNow;
+          suffix = $l.suffixFromNow;
+        }
+      }
+
+      var seconds = Math.abs(distanceMillis) / 1000;
+      var minutes = seconds / 60;
+      var hours = minutes / 60;
+      var days = hours / 24;
+      var years = days / 365;
+
+      function substitute(stringOrFunction, number) {
+        var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
+        var value = ($l.numbers && $l.numbers[number]) || number;
+        return string.replace(/%d/i, value);
+      }
+
+      var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
+        seconds < 90 && substitute($l.minute, 1) ||
+        minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
+        minutes < 90 && substitute($l.hour, 1) ||
+        hours < 24 && substitute($l.hours, Math.round(hours)) ||
+        hours < 48 && substitute($l.day, 1) ||
+        days < 30 && substitute($l.days, Math.floor(days)) ||
+        days < 60 && substitute($l.month, 1) ||
+        days < 365 && substitute($l.months, Math.floor(days / 30)) ||
+        years < 2 && substitute($l.year, 1) ||
+        substitute($l.years, Math.floor(years));
+
+      return $.trim([prefix, words, suffix].join(" "));
+    },
+    parse: function(iso8601) {
+      var s = $.trim(iso8601);
+      s = s.replace(/\.\d\d\d+/,""); // remove milliseconds
+      s = s.replace(/-/,"/").replace(/-/,"/");
+      s = s.replace(/T/," ").replace(/Z/," UTC");
+      s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
+      return new Date(s);
+    },
+    datetime: function(elem) {
+      // jQuery's `is()` doesn't play well with HTML5 in IE
+      var isTime = $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
+      var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title");
+      return $t.parse(iso8601);
+    }
+  });
+
+  $.fn.timeago = function() {
+    var self = this;
+    self.each(refresh);
+
+    var $s = $t.settings;
+    if ($s.refreshMillis > 0) {
+      setInterval(function() { self.each(refresh); }, $s.refreshMillis);
+    }
+    return self;
+  };
+
+  function refresh() {
+    var data = prepareData(this);
+    if (!isNaN(data.datetime)) {
+      $(this).text(inWords(data.datetime));
+    }
+    return this;
+  }
+
+  function prepareData(element) {
+    element = $(element);
+    if (!element.data("timeago")) {
+      element.data("timeago", { datetime: $t.datetime(element) });
+      var text = $.trim(element.text());
+      if (text.length > 0) {
+        element.attr("title", text);
+      }
+    }
+    return element.data("timeago");
+  }
+
+  function inWords(date) {
+    return $t.inWords(distance(date));
+  }
+
+  function distance(date) {
+    return (new Date().getTime() - date.getTime());
+  }
+
+  // fix for IE6 suckage
+  document.createElement("abbr");
+  document.createElement("time");
+}(jQuery));
diff --git a/cloudcms/static/cloudcms/js/twitter/jquery.twitter.js b/cloudcms/static/cloudcms/js/twitter/jquery.twitter.js
new file mode 100644 (file)
index 0000000..cb61270
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Twitter Search Plugin jquery.twitter.js
+ * http://code.bocoup.com/jquery-twitter-plugin/
+ *
+ * Copyright (c) 2010 Bocoup, LLC
+ * Authors: Boaz Sender, Rick Waldron, Nick Cammarata
+ * Dual licensed under the MIT and GPL licenses.
+ * http://code.bocoup.com/license/
+ *
+ */
+var linkify = linkify || function() {};
+;(function($, linkify) {
+
+  var
+  mention = function( str ) {
+    return str.replace("/[@]+[A-Za-z0-9-_]+/ig", function( username ) {
+      return username.link("http://twitter.com/"+ username.replace("@","") );
+    });
+  },
+  hashtags = function( str ) {
+    return str.replace("/[#]+[A-Za-z0-9-_]+/ig", function( tag ) {
+      return tag.link("http://search.twitter.com/search?q="+tag.replace("#","%23"));
+    });
+  };
+
+  $.twitter = function (options, callback) {
+    // Fail if the options arg is not set
+    if ( !options ) {
+      return false;
+    }
+
+    // Set a temporary default query object
+    var query,
+        // Set up a string to be used later in the case that exclusions have been set
+        exclusionsStr = "",
+        // Set up a regex to be used later in the case that exclusions have been set
+        exclusionsExp = new RegExp(false);
+
+    // If options is a string use it as standalone query
+    if ( typeof options === "string" ) {
+      query = $.extend({}, $.twitter.opts, {
+        q: options
+      });
+    // Else prepare the options object to be serialized
+    } else {
+      // If a limit is set, add it to the query object
+      options.rpp = options.limit ? options.limit : options.rpp;
+
+      // If no limit is set, make the limit the rpp
+      options.limit = options.limit ? options.limit : options.rpp;
+
+      // If there are exlusions, turn them into a regex string
+      exclusionsStr = options.exclusions ? options.exclusions.replace(" ", "|") : false;
+
+      // If there are exlusions, turn the regex string we just made into a RegExp
+      exclusionsExp = exclusionsStr ? new RegExp( exclusionsStr ) : false;
+
+      // Make a new object that is a merger of the options passed in with the default $.twitter.opts object
+      // and assign it to the query variable
+      query = $.extend({}, $.twitter.opts, options);
+
+      // If there are exclusions, or replies or retweets are set to false, multiply the results to ask for from twitter by ten
+      // We need to do this so that we have some meat to work with if the exclusions are common
+      query.rpp = query.exclusions || !query.replies || !query.retweets  ? (query.rpp * 10) : query.rpp;
+
+    }
+
+
+    // Call Twitter JSONP
+    $.getJSON("http://search.twitter.com/search.json?callback=?", query, function(tweets){
+      callback(tweets, query, exclusionsExp);
+    });
+  };
+
+  $.fn.twitter = function( options ) {
+    // Fail gracefully if the options arg is not set
+    // return the jQuery obj so that chaining does not break
+    if ( !options ) {
+      return this;
+    }
+
+    // Begin to iterate over the jQuery collection that the method was called on
+    return this.each(function () {
+      // Cache `this`
+      var $this = $(this);
+
+      $.twitter(options, function( tweets, query, exclusionsExp ) {
+        //Create and cache a new UL
+        var $tweets = $("<ul>"),
+            // Create a counter variable to count up how many tweets we have rendered
+            // unfortunately we have to do this, because exclusions, retweet booleans and replies booleans
+            // are not supported by the Twitter Search API
+            limitInt = 0,
+            i;
+
+        // If there are results to work with
+        if ( tweets.results && tweets.results.length ) {
+
+          //  Iterate over returned tweets
+          for ( i in tweets.results ) {
+
+            // Cache tweet content
+            var tweet = tweets.results[i],
+                // Set a variable to determine weather replies are set to false, and if so, weather the tweet starts with a reply
+                allowReply = !query.replies && tweet.to_user_id ? false : true,
+                // Set a variable to determine weather retweets are set to false, and if so, weather the tweet starts with a retweet
+                allowRetweet = !query.retweets && tweet.text.slice(0,2) === "RT" ? false : true;
+
+            // Only proceed if allow reply is false
+            if ( !allowReply ) {
+              continue;
+            }
+
+            // Only proceed if allow retweet is false
+            if ( !allowRetweet ) {
+              continue;
+            }
+
+            // If exlusions set and none of the exlusions is found in the tweet then add it to the DOM
+            if ( exclusionsExp && exclusionsExp.test(tweet.text) ) {
+              continue;
+            }
+
+            // Create and cache new LI
+            var $tweet = $("<li/>", {
+              "class": "tweet"
+            });
+
+            // Make the avatar, and append it to the $tweet
+            if ( query.avatar === true ) {
+              $tweet.append($("<a/>", {
+                href: "http://twitter.com/" + tweet.from_user,
+                html: "<img src='" + tweet.profile_image_url + "'/>"
+              }));
+            }
+
+            // Make the tweet text, and append it to the $tweet, then to the parent
+            $tweet.append($("<span>", {
+              "class": "content",
+              html: "<a href='http://twitter.com/" + tweet.from_user + "'>@" + tweet.from_user + "</a>: " + mention(hashtags(linkify(tweet.text)))
+            }))
+            // Append tweet to the $tweets ul
+            .appendTo($tweets);
+
+            // Count up our counter variable
+            limitInt++;
+
+            // If the counter is equal to the limit, stop rendering tweets
+            if ( limitInt === query.limit ) {
+              break;
+            }
+          }
+
+          // Inject the $tweets into the DOM
+          $this.html($tweets);
+
+        // Else there are no results to work with
+        } else {
+          // Update the DOM to reflect that no results were found
+          $this.html($("<h3/>", {
+            "class": "twitter-notFound",
+            text: query.notFoundText
+          }));
+        }
+      });
+    });
+  };
+
+  $.twitter.opts = {
+    // Number of tweets to get
+    // not in twitter search api, maps to and supersedes rpp (results per page)
+    limit: 7,
+    // Space delimited list of strings to exclude  (eg: "_ s gr @b")
+    // not in twitter search api, done in plugin
+    exclusions: "",
+    // Text to display if no results are found
+    // not in twitter search api, done in plugin
+    notFoundText: "No results found on twitter",
+    // Include replies?
+    // not in twitter search api, done in plugin
+    replies: true,
+    // Include replies?
+    // not in twitter search api, done in plugin
+    retweets: true,
+    // All of these words
+    ands: "",
+    // This exact phrase
+    phrase: "",
+    // Any of these words
+    ors : "",
+    // None of these words
+    nots: "",
+    // This hashtag
+    tag : "",
+    // Written in language
+    lang: "",
+    // From this person
+    from: "",
+    // To this person
+    to: "",
+    // Referencing this person
+    ref: "",
+    // Near this place
+    near: "",
+    // Within this distance
+    within: "",
+    // Distance unit (miles or kilometers)
+    units: "",
+    // Since this date
+    since: "",
+    // Until this date
+    until: "",
+    // Attitude: "?" or :)" or ":)"
+    tude: "",
+    // Containing: "links"
+    filter: "",
+    // Include retweet?: "retweets"
+    include: "",
+    // Results per page
+    rpp: 5,
+    // Default query
+    q: "",
+    // Add an avatar image of the user
+    avatar: true
+  };
+}(jQuery, linkify));
diff --git a/cloudcms/static/cloudcms/less/bootstrap.less b/cloudcms/static/cloudcms/less/bootstrap.less
new file mode 100644 (file)
index 0000000..6e9bdf3
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+ * Bootstrap @VERSION
+ *
+ * Copyright 2011 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ * Date: @DATE
+ */
+
+// CSS Reset
+@import "reset.less";
+
+// Core variables and mixins
+@import "variables.less"; // Modify this for custom colors, font-sizes, etc
+@import "mixins.less";
+@import "xtra.less";
diff --git a/cloudcms/static/cloudcms/less/cloudbox.less b/cloudcms/static/cloudcms/less/cloudbox.less
new file mode 100644 (file)
index 0000000..33a02a4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+    ColorBox Core Style:
+    The following CSS is consistent between example themes and should not be altered.
+*/
+#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
+#cboxOverlay{position:fixed; width:100%; height:100%;}
+#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
+#cboxContent{position:relative;}
+#cboxLoadedContent{overflow:auto;}
+#cboxTitle{margin:0;}
+#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
+#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
+.cboxPhoto{float:left; margin:auto; border:0; display:block;}
+.cboxIframe{width:100%; height:100%; display:block; border:0;}
+
+/* 
+    User Style:
+    Change the following styles to modify the appearance of ColorBox.  They are
+    ordered & tabbed in a way that represents the nesting of the generated HTML.
+*/
+#cboxOverlay{background:#222;}
+#colorbox{}
+    #cboxTopLeft{width:25px; height:25px; background:url(../images/colorbox/border1.png) no-repeat 0 0;}
+    #cboxTopCenter{height:25px; background:url(../images/colorbox/border1.png) repeat-x 0 -50px;}
+    #cboxTopRight{width:25px; height:25px; background:url(../images/colorbox/border1.png) no-repeat -25px 0;}
+    #cboxBottomLeft{width:25px; height:25px; background:url(../images/colorbox/border1.png) no-repeat 0 -25px;}
+    #cboxBottomCenter{height:25px; background:url(../images/colorbox/border1.png) repeat-x 0 -75px;}
+    #cboxBottomRight{width:25px; height:25px; background:url(../images/colorbox/border1.png) no-repeat -25px -25px;}
+    #cboxMiddleLeft{width:25px; background:url(../images/colorbox/border2.png) repeat-y 0 0;}
+    #cboxMiddleRight{width:25px; background:url(../images/colorbox/border2.png) repeat-y -25px 0;}
+    #cboxContent{background:#fff; overflow:hidden;}
+        .cboxIframe{background:#fff;}
+        #cboxError{padding:50px; border:1px solid #ccc;}
+        #cboxLoadedContent{margin-bottom:20px;}
+        #cboxTitle{position:absolute; bottom:0px; left:0; text-align:center; width:100%; color:#999;}
+        #cboxCurrent{position:absolute; bottom:0px; left:100px; color:#999;}
+        #cboxSlideshow{position:absolute; bottom:0px; right:42px; color:#444;}
+        #cboxPrevious{position:absolute; bottom:0px; left:0; color:#444;}
+        #cboxNext{position:absolute; bottom:0px; left:63px; color:#444;}
+        #cboxLoadingOverlay{background:#fff url(../images/colorbox/loading.gif) no-repeat 5px 5px;}
+        #cboxClose{position:absolute; bottom:0; right:0; display:block; color:#444;}
+
+/*
+  The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
+  when an alpha filter (opacity change) is set on the element or ancestor element.  This style is not applied to or needed in IE9.
+  See: http://jacklmoore.com/notes/ie-transparency-problems/
+*/
+.cboxIE #cboxTopLeft,
+.cboxIE #cboxTopCenter,
+.cboxIE #cboxTopRight,
+.cboxIE #cboxBottomLeft,
+.cboxIE #cboxBottomCenter,
+.cboxIE #cboxBottomRight,
+.cboxIE #cboxMiddleLeft,
+.cboxIE #cboxMiddleRight {
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
+}
+
+/*
+  The following provides PNG transparency support for IE6
+  Feel free to remove this and the /ie6/ directory if you have dropped IE6 support.
+*/
+.cboxIE6 #cboxTopLeft{background:url(../images/colorbox/ie6/borderTopLeft.png);}
+.cboxIE6 #cboxTopCenter{background:url(../images/colorbox/ie6/borderTopCenter.png);}
+.cboxIE6 #cboxTopRight{background:url(../images/colorbox/ie6/borderTopRight.png);}
+.cboxIE6 #cboxBottomLeft{background:url(../images/colorbox/ie6/borderBottomLeft.png);}
+.cboxIE6 #cboxBottomCenter{background:url(../images/colorbox/ie6/borderBottomCenter.png);}
+.cboxIE6 #cboxBottomRight{background:url(../images/colorbox/ie6/borderBottomRight.png);}
+.cboxIE6 #cboxMiddleLeft{background:url(../images/colorbox/ie6/borderMiddleLeft.png);}
+.cboxIE6 #cboxMiddleRight{background:url(../images/colorbox/ie6/borderMiddleRight.png);}
+
+.cboxIE6 #cboxTopLeft,
+.cboxIE6 #cboxTopCenter,
+.cboxIE6 #cboxTopRight,
+.cboxIE6 #cboxBottomLeft,
+.cboxIE6 #cboxBottomCenter,
+.cboxIE6 #cboxBottomRight,
+.cboxIE6 #cboxMiddleLeft,
+.cboxIE6 #cboxMiddleRight {
+    _behavior: expression(this.src = this.src ? this.src : this.currentStyle.backgroundImage.split('"')[1], this.style.background = "none", this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.src + ", sizingMethod='scale')");
+}
diff --git a/cloudcms/static/cloudcms/less/django_forms.less b/cloudcms/static/cloudcms/less/django_forms.less
new file mode 100644 (file)
index 0000000..25b8ae3
--- /dev/null
@@ -0,0 +1,2 @@
+ /*addon to style django forms rendered with as_p filter*/
+
diff --git a/cloudcms/static/cloudcms/less/forms.less b/cloudcms/static/cloudcms/less/forms.less
new file mode 100644 (file)
index 0000000..87fcc3d
--- /dev/null
@@ -0,0 +1,479 @@
+/* Forms.less
+ * Base styles for various input types, form layouts, and states
+ * ------------------------------------------------------------- */
+
+
+// FORM STYLES
+// -----------
+
+form {
+  margin-bottom: @baseline;
+}
+
+// Groups of fields with labels on top (legends)
+fieldset {
+  margin-bottom: @baseline;
+  padding-top: @baseline;
+  legend {
+    display: block;
+    padding-left: 150px;
+    font-size: @basefont * 1.5;
+    line-height: 1;
+    color: @grayDark;
+    *padding: 0 0 5px 145px; /* IE6-7 */
+    *line-height: 1.5; /* IE6-7 */
+  }
+}
+
+// Parent element that clears floats and wraps labels and fields together
+form .clearfix {
+  margin-bottom: @baseline;
+  .clearfix()
+}
+
+// Set font for forms
+label,
+input,
+select,
+textarea {
+  #font > .sans-serif(normal,13px,normal);
+}
+
+// Float labels left
+label {
+  padding-top: 6px;
+  font-size: @basefont;
+  line-height: @baseline;
+  float: left;
+  width: 130px;
+  text-align: right;
+  color: @grayDark;
+}
+
+// Shift over the inside div to align all label's relevant content
+form .input {
+  margin-left: 150px;
+}
+
+// Checkboxs and radio buttons
+input[type=checkbox],
+input[type=radio] {
+  cursor: pointer;
+}
+
+// Inputs, Textareas, Selects
+input,
+textarea,
+select,
+.uneditable-input {
+  display: inline-block;
+  width: 210px;
+  height: @baseline;
+  padding: 4px;
+  font-size: @basefont;
+  line-height: @baseline;
+  color: @gray;
+  border: 1px solid #ccc;
+  .border-radius(3px);
+}
+
+// remove padding from select
+select {
+  padding: initial;
+}
+
+// mini reset for non-html5 file types
+input[type=checkbox],
+input[type=radio] {
+  width: auto;
+  height: auto;
+  padding: 0;
+  margin: 3px 0;
+  *margin-top: 0; /* IE6-7 */
+  line-height: normal;
+  border: none;
+}
+
+input[type=file] {
+  background-color: @white;
+  padding: initial;
+  border: initial;
+  line-height: initial;
+  .box-shadow(none);
+}
+
+input[type=button],
+input[type=reset],
+input[type=submit] {
+  width: auto;
+  height: auto;
+}
+
+select,
+input[type=file] {
+  height: @baseline * 1.5; // In IE7, the height of the select element cannot be changed by height, only font-size
+  *height: auto; // Reset for IE7
+  line-height: @baseline * 1.5;
+  *margin-top: 4px; /* For IE7, add top margin to align select with labels */
+}
+
+// Make multiple select elements height not fixed
+select[multiple] {
+  height: inherit;
+  background-color: @white; // Fixes Chromium bug of unreadable items
+}
+
+textarea {
+  height: auto;
+}
+
+// For text that needs to appear as an input but should not be an input
+.uneditable-input {
+  background-color: @white;
+  display: block;
+  border-color: #eee;
+  .box-shadow(inset 0 1px 2px rgba(0,0,0,.025));
+  cursor: not-allowed;
+}
+
+// Placeholder text gets special styles; can't be bundled together though for some reason
+:-moz-placeholder {
+  color: @grayLight;
+}
+::-webkit-input-placeholder {
+  color: @grayLight;
+}
+
+// Focus states
+input,
+textarea {
+  @transition: border linear .2s, box-shadow linear .2s;
+  .transition(@transition);
+  .box-shadow(inset 0 1px 3px rgba(0,0,0,.1));
+}
+input:focus,
+textarea:focus {
+  outline: 0;
+  border-color: rgba(82,168,236,.8);
+  @shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6);
+  .box-shadow(@shadow);
+}
+input[type=file]:focus,
+input[type=checkbox]:focus,
+select:focus {
+  .box-shadow(none); // override for file inputs
+  outline: 1px dotted #666; // Selet elements don't get box-shadow styles, so instead we do outline
+}
+
+
+// FORM FIELD FEEDBACK STATES
+// --------------------------
+
+// Mixin for form field states
+.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) {
+  // Set the text color
+  > label,
+  .help-block,
+  .help-inline {
+    color: @textColor;
+  }
+  // Style inputs accordingly
+  input,
+  textarea {
+    color: @textColor;
+    border-color: @borderColor;
+    &:focus {
+      border-color: darken(@borderColor, 10%);
+      .box-shadow(0 0 6px lighten(@borderColor, 20%));
+    }
+  }
+  // Give a small background color for input-prepend/-append
+  .input-prepend .add-on,
+  .input-append .add-on {
+    color: @textColor;
+    background-color: @backgroundColor;
+    border-color: @textColor;
+  }
+}
+// Error
+form .clearfix.error {
+  .formFieldState(#b94a48, #ee5f5b, lighten(#ee5f5b, 30%));
+}
+// Warning
+form .clearfix.warning {
+  .formFieldState(#c09853, #ccae64, lighten(#CCAE64, 5%));
+}
+// Success
+form .clearfix.success {
+  .formFieldState(#468847, #57a957, lighten(#57a957, 30%));
+}
+
+
+// Form element sizes
+// TODO v2: remove duplication here and just stick to .input-[size] in light of adding .spanN sizes
+.input-mini,
+input.mini,
+textarea.mini,
+select.mini {
+  width: 60px;
+}
+.input-small,
+input.small,
+textarea.small,
+select.small {
+  width: 90px;
+}
+.input-medium,
+input.medium,
+textarea.medium,
+select.medium {
+  width: 150px;
+}
+.input-large,
+input.large,
+textarea.large,
+select.large {
+  width: 210px;
+}
+.input-xlarge,
+input.xlarge,
+textarea.xlarge,
+select.xlarge {
+  width: 270px;
+}
+.input-xxlarge,
+input.xxlarge,
+textarea.xxlarge,
+select.xxlarge {
+  width: 530px;
+}
+textarea.xxlarge {
+  overflow-y: auto;
+}
+
+// Grid style input sizes
+// This is a duplication of the main grid .columns() mixin, but subtracts 10px to account for input padding and border
+.formColumns(@columnSpan: 1) {
+  display: inline-block;
+  float: none;
+  width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 10;
+  margin-left: 0;
+}
+input,
+textarea {
+  // Default columns
+  &.span1     { .formColumns(1); }
+  &.span2     { .formColumns(2); }
+  &.span3     { .formColumns(3); }
+  &.span4     { .formColumns(4); }
+  &.span5     { .formColumns(5); }
+  &.span6     { .formColumns(6); }
+  &.span7     { .formColumns(7); }
+  &.span8     { .formColumns(8); }
+  &.span9     { .formColumns(9); }
+  &.span10    { .formColumns(10); }
+  &.span11    { .formColumns(11); }
+  &.span12    { .formColumns(12); }
+  &.span13    { .formColumns(13); }
+  &.span14    { .formColumns(14); }
+  &.span15    { .formColumns(15); }
+  &.span16    { .formColumns(16); }
+}
+
+// Disabled and read-only inputs
+input[disabled],
+select[disabled],
+textarea[disabled],
+input[readonly],
+select[readonly],
+textarea[readonly] {
+  background-color: #f5f5f5;
+  border-color: #ddd;
+  cursor: not-allowed;
+}
+
+// Actions (the buttons)
+.actions {
+  background: #f5f5f5;
+  margin-top: @baseline;
+  margin-bottom: @baseline;
+  padding: (@baseline - 1) 20px @baseline 150px;
+  border-top: 1px solid #ddd;
+  .border-radius(0 0 3px 3px);
+  .secondary-action {
+    float: right;
+    a {
+      line-height: 30px;
+      &:hover {
+        text-decoration: underline;
+      }
+    }
+  }
+}
+
+// Help Text
+// TODO: Do we need to set basefont and baseline here?
+.help-inline,
+.help-block {
+  font-size: @basefont;
+  line-height: @baseline;
+  color: @grayLight;
+}
+.help-inline {
+  padding-left: 5px;
+  *position: relative; /* IE6-7 */
+  *top: -5px; /* IE6-7 */
+}
+
+// Big blocks of help text
+.help-block {
+  display: block;
+  max-width: 600px;
+}
+
+// Inline Fields (input fields that appear as inline objects
+.inline-inputs {
+  color: @gray;
+  span {
+    padding: 0 2px 0 1px;
+  }
+}
+
+// Allow us to put symbols and text within the input field for a cleaner look
+.input-prepend,
+.input-append {
+  input {
+    .border-radius(0 3px 3px 0);
+  }
+  .add-on {
+    position: relative;
+    background: #f5f5f5;
+    border: 1px solid #ccc;
+    z-index: 2;
+    float: left;
+    display: block;
+    width: auto;
+    min-width: 16px;
+    height: 18px;
+    padding: 4px 4px 4px 5px;
+    margin-right: -1px;
+    font-weight: normal;
+    line-height: 18px;
+    color: @grayLight;
+    text-align: center;
+    text-shadow: 0 1px 0 @white;
+    .border-radius(3px 0 0 3px);
+  }
+  .active {
+    background: lighten(@green, 30);
+    border-color: @green;
+  }
+}
+.input-prepend {
+  .add-on {
+    *margin-top: 1px; /* IE6-7 */
+  }
+}
+.input-append {
+  input {
+    float: left;
+    .border-radius(3px 0 0 3px);
+  }
+  .add-on {
+    .border-radius(0 3px 3px 0);
+    margin-right: 0;
+    margin-left: -1px;
+  }
+}
+
+// Stacked options for forms (radio buttons or checkboxes)
+.inputs-list {
+  margin: 0 0 5px;
+  width: 100%;
+  li {
+    display: block;
+    padding: 0;
+    width: 100%;
+  }
+  label {
+    display: block;
+    float: none;
+    width: auto;
+    padding: 0;
+    margin-left: 20px;
+    line-height: @baseline;
+    text-align: left;
+    white-space: normal;
+    strong {
+      color: @gray;
+    }
+    small {
+      font-size: @basefont - 2;
+      font-weight: normal;
+    }
+  }
+  .inputs-list {
+    margin-left: 25px;
+    margin-bottom: 10px;
+    padding-top: 0;
+  }
+  &:first-child {
+    padding-top: 6px;
+  }
+  li + li {
+    padding-top: 2px;
+  }
+  input[type=radio],
+  input[type=checkbox] {
+    margin-bottom: 0;
+    margin-left: -20px;
+    float: left;
+  }
+}
+
+// Stacked forms
+.form-stacked {
+  padding-left: 20px;
+  fieldset {
+    padding-top: @baseline / 2;
+  }
+  legend {
+    padding-left: 0;
+  }
+  label {
+    display: block;
+    float: none;
+    width: auto;
+    font-weight: bold;
+    text-align: left;
+    line-height: 20px;
+    padding-top: 0;
+  }
+  .clearfix {
+    margin-bottom: @baseline / 2;
+    div.input {
+      margin-left: 0;
+    }
+  }
+  .inputs-list {
+    margin-bottom: 0;
+    li {
+      padding-top: 0;
+      label {
+        font-weight: normal;
+        padding-top: 0;
+      }
+    }
+  }
+  div.clearfix.error {
+    padding-top: 10px;
+    padding-bottom: 10px;
+    padding-left: 10px;
+    margin-top: 0;
+    margin-left: -10px;
+  }
+  .actions {
+    margin-left: -20px;
+    padding-left: 20px;
+  }
+}
diff --git a/cloudcms/static/cloudcms/less/mixins.less b/cloudcms/static/cloudcms/less/mixins.less
new file mode 100644 (file)
index 0000000..1304eff
--- /dev/null
@@ -0,0 +1,222 @@
+/* Mixins.less
+ * Snippets of reusable CSS to develop faster and keep code readable
+ * ----------------------------------------------------------------- */
+
+
+// Clearfix for clearing floats like a boss h5bp.com/q
+.clearfix() {
+  zoom: 1;
+  &:before,
+  &:after {
+    display: table;
+    content: "";
+    zoom: 1;
+  }
+  &:after {
+    clear: both;
+  }
+}
+
+// Center-align a block level element
+.center-block() {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+// Sizing shortcuts
+.size(@height: 5px, @width: 5px) {
+  height: @height;
+  width: @width;
+}
+.square(@size: 5px) {
+  .size(@size, @size);
+}
+
+// Input placeholder text
+.placeholder(@color: @grayLight) {
+  :-moz-placeholder {
+    color: @color;
+  }
+  ::-webkit-input-placeholder {
+    color: @color;
+  }
+}
+
+// Font Stacks
+#font {
+  .shorthand(@weight: normal, @size: 14px, @lineHeight: 20px) {
+    font-size: @size;
+    font-weight: @weight;
+    line-height: @lineHeight;
+  }
+  .sans-serif(@weight: normal, @size: 14px, @lineHeight: 20px) {
+    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+    font-size: @size;
+    font-weight: @weight;
+    line-height: @lineHeight;
+  }
+  .serif(@weight: normal, @size: 14px, @lineHeight: 20px) {
+    font-family: "Georgia", Times New Roman, Times, serif;
+    font-size: @size;
+    font-weight: @weight;
+    line-height: @lineHeight;
+  }
+  .monospace(@weight: normal, @size: 12px, @lineHeight: 20px) {
+    font-family: "Monaco", Courier New, monospace;
+    font-size: @size;
+    font-weight: @weight;
+    line-height: @lineHeight;
+  }
+}
+
+// Grid System
+.fixed-container() {
+  width: @siteWidth;
+  margin-left: auto;
+  margin-right: auto;
+  .clearfix();
+}
+.columns(@columnSpan: 1) {
+  width: (@gridColumnWidth * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1));
+}
+.offset(@columnOffset: 1) {
+  margin-left: (@gridColumnWidth * @columnOffset) + (@gridGutterWidth * (@columnOffset - 1));
+}
+// Necessary grid styles for every column to make them appear next to each other horizontally
+.gridColumn() {
+  display: inline;
+  float: left;
+  margin-left: @gridGutterWidth;
+}
+// makeColumn can be used to mark any element (e.g., .content-primary) as a column without changing markup to .span something
+.makeColumn(@columnSpan: 1) {
+  .gridColumn();
+  .columns(@columnSpan);
+}
+
+// Border Radius
+.border-radius(@radius: 5px) {
+  -webkit-border-radius: @radius;
+     -moz-border-radius: @radius;
+          border-radius: @radius;
+}
+
+// Drop shadows
+.box-shadow(@shadow: 0 1px 3px rgba(0,0,0,.25)) {
+  -webkit-box-shadow: @shadow;
+     -moz-box-shadow: @shadow;
+          box-shadow: @shadow;
+}
+
+// Transitions
+.transition(@transition) {
+     -webkit-transition: @transition;
+        -moz-transition: @transition;
+         -ms-transition: @transition;
+          -o-transition: @transition;
+             transition: @transition;
+}
+
+// Background clipping
+.background-clip(@clip) {
+  -webkit-background-clip: @clip;
+     -moz-background-clip: @clip;
+          background-clip: @clip;
+}
+
+// CSS3 Content Columns
+.content-columns(@columnCount, @columnGap: 20px) {
+  -webkit-column-count: @columnCount;
+     -moz-column-count: @columnCount;
+          column-count: @columnCount;
+  -webkit-column-gap: @columnGap;
+     -moz-column-gap: @columnGap;
+          column-gap: @columnGap;
+}
+
+// Make any element resizable for prototyping
+.resizable(@direction: both) {
+  resize: @direction; // Options are horizontal, vertical, both
+  overflow: auto; // Safari fix
+}
+
+// Add an alphatransparency value to any background or border color (via Elyse Holladay)
+#translucent {
+  .background(@color: @white, @alpha: 1) {
+    background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
+  }
+  .border(@color: @white, @alpha: 1) {
+    border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
+    background-clip: padding-box;
+  }
+}
+
+// Gradient Bar Colors for buttons and allerts
+.gradientBar(@primaryColor, @secondaryColor) {
+  #gradient > .vertical(@primaryColor, @secondaryColor);
+  text-shadow: 0 -1px 0 rgba(0,0,0,.25);
+  border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%);
+  border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%);
+}
+
+// Gradients
+#gradient {
+  .horizontal (@startColor: #555, @endColor: #333) {
+    background-color: @endColor;
+    background-repeat: repeat-x;
+    background-image: -khtml-gradient(linear, left top, right top, from(@startColor), to(@endColor)); // Konqueror
+    background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+
+    background-image: -ms-linear-gradient(left, @startColor, @endColor); // IE10
+    background-image: -webkit-gradient(linear, left top, right top, color-stop(0%, @startColor), color-stop(100%, @endColor)); // Safari 4+, Chrome 2+
+    background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+
+    background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10
+    background-image: linear-gradient(left, @startColor, @endColor); // Le standard
+    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",@startColor,@endColor)); // IE9 and down
+  }
+  .vertical (@startColor: #555, @endColor: #333) {
+    background-color: @endColor;
+    background-repeat: repeat-x;
+    background-image: -khtml-gradient(linear, left top, left bottom, from(@startColor), to(@endColor)); // Konqueror
+    background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+
+    background-image: -ms-linear-gradient(top, @startColor, @endColor); // IE10
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, @startColor), color-stop(100%, @endColor)); // Safari 4+, Chrome 2+
+    background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+
+    background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10
+    background-image: linear-gradient(top, @startColor, @endColor); // The standard
+    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down
+  }
+  .directional (@startColor: #555, @endColor: #333, @deg: 45deg) {
+    background-color: @endColor;
+    background-repeat: repeat-x;
+    background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+
+    background-image: -ms-linear-gradient(@deg, @startColor, @endColor); // IE10
+    background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+
+    background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10
+    background-image: linear-gradient(@deg, @startColor, @endColor); // The standard
+  }
+  .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) {
+    background-color: @endColor;
+    background-repeat: no-repeat;
+    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor));
+    background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor);
+    background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor);
+    background-image: -ms-linear-gradient(@startColor, @midColor @colorStop, @endColor);
+    background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor);
+    background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor);
+    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down, gets no color-stop at all for proper fallback
+  }
+}
+
+// Reset filters for IE
+.reset-filter() {
+  filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
+}
+
+// Opacity
+.opacity(@opacity: 100) {
+  filter: e(%("alpha(opacity=%d)", @opacity));
+  -khtml-opacity: @opacity / 100;
+    -moz-opacity: @opacity / 100;
+         opacity: @opacity / 100;
+}
diff --git a/cloudcms/static/cloudcms/less/patterns.less b/cloudcms/static/cloudcms/less/patterns.less
new file mode 100644 (file)
index 0000000..5b72081
--- /dev/null
@@ -0,0 +1,1060 @@
+/* Patterns.less
+ * Repeatable UI elements outside the base styles provided from the scaffolding
+ * ---------------------------------------------------------------------------- */
+
+
+// TOPBAR
+// ------
+
+// Topbar for Branding and Nav
+.topbar {
+  height: 40px;
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 10000;
+  overflow: visible;
+
+  // Links get text shadow
+  a {
+    color: @grayLight;
+    text-shadow: 0 -1px 0 rgba(0,0,0,.25);
+  }
+
+  // Hover and active states
+  // h3 for backwards compatibility
+  h3 a:hover,
+  .brand:hover,
+  ul .active > a {
+    background-color: #333;
+    background-color: rgba(255,255,255,.05);
+    color: @white;
+    text-decoration: none;
+  }
+
+  // Website name
+  // h3 left for backwards compatibility
+  h3 {
+    position: relative;
+  }
+  h3 a,
+  .brand {
+    float: left;
+    display: block;
+    padding: 8px 20px 12px;
+    margin-left: -20px; // negative indent to left-align the text down the page
+    color: @white;
+    font-size: 20px;
+    font-weight: 200;
+    line-height: 1;
+  }
+
+  // Plain text in topbar
+  p {
+    margin: 0;
+    line-height: 40px;
+    a:hover {
+      background-color: transparent;
+      color: @white;
+    }
+  }
+
+  // Search Form
+  form {
+    float: left;
+    margin: 5px 0 0 0;
+    position: relative;
+    .opacity(100);
+  }
+  // Todo: remove from v2.0 when ready, added for legacy
+  form.pull-right {
+    float: right;
+  }
+  input {
+    background-color: #444;
+    background-color: rgba(255,255,255,.3);
+    #font > .sans-serif(13px, normal, 1);
+    padding: 4px 9px;
+    color: @white;
+    color: rgba(255,255,255,.75);
+    border: 1px solid #111;
+    .border-radius(4px);
+    @shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0px rgba(255,255,255,.25);
+    .box-shadow(@shadow);
+    .transition(none);
+
+    // Placeholder text gets special styles; can't be bundled together though for some reason
+    &:-moz-placeholder {
+      color: @grayLighter;
+    }
+    &::-webkit-input-placeholder {
+      color: @grayLighter;
+    }
+    // Hover states
+    &:hover {
+      background-color: @grayLight;
+      background-color: rgba(255,255,255,.5);
+      color: @white;
+    }
+    // Focus states (we use .focused since IE8 and down doesn't support :focus)
+    &:focus,
+    &.focused {
+      outline: 0;
+      background-color: @white;
+      color: @grayDark;
+      text-shadow: 0 1px 0 @white;
+      border: 0;
+      padding: 5px 10px;
+      .box-shadow(0 0 3px rgba(0,0,0,.15));
+    }
+  }
+}
+
+// gradient is applied to it's own element because overflow visible is not honored by ie when filter is present
+// For backwards compatibility, include .topbar .fill
+.topbar-inner,
+.topbar .fill {
+  background-color: #222;
+  #gradient > .vertical(#333, #222);
+  @shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);
+  .box-shadow(@shadow);
+}
+
+
+// NAVIGATION
+// ----------
+
+// Topbar Nav
+// ul.nav for all topbar based navigation to avoid inheritance issues and over-specificity
+// For backwards compatibility, leave in .topbar div > ul
+.topbar div > ul,
+.nav {
+  display: block;
+  float: left;
+  margin: 0 10px 0 0;
+  position: relative;
+  left: 0;
+  > li {
+    display: block;
+    float: left;
+  }
+  a {
+    display: block;
+    float: none;
+    padding: 10px 10px 11px;
+    line-height: 19px;
+    text-decoration: none;
+    &:hover {
+      color: @white;
+      text-decoration: none;
+    }
+  }
+  .active > a {
+    background-color: #222;
+    background-color: rgba(0,0,0,.5);
+  }
+
+  // Secondary (floated right) nav in topbar
+  &.secondary-nav {
+    float: right;
+    margin-left: 10px;
+    margin-right: 0;
+    // backwards compatibility
+    .menu-dropdown,
+    .dropdown-menu {
+      right: 0;
+      border: 0;
+    }
+  }
+  // Dropdowns within the .nav
+  // a.menu:hover and li.open .menu for backwards compatibility
+  a.menu:hover,
+  li.open .menu,
+  .dropdown-toggle:hover,
+  .dropdown.open .dropdown-toggle {
+    background: #444;
+    background: rgba(255,255,255,.05);
+  }
+  // .menu-dropdown for backwards compatibility
+  .menu-dropdown,
+  .dropdown-menu {
+    background-color: #333;
+    // a.menu for backwards compatibility
+    a.menu,
+    .dropdown-toggle {
+      color: @white;
+      &.open {
+        background: #444;
+        background: rgba(255,255,255,.05);
+      }
+    }
+    li a {
+      color: #999;
+      text-shadow: 0 1px 0 rgba(0,0,0,.5);
+      &:hover {
+        #gradient > .vertical(#292929,#191919);
+        color: @white;
+      }
+    }
+    .active a {
+      color: @white;
+    }
+    .divider {
+      background-color: #222;
+      border-color: #444;
+    }
+  }
+}
+
+// For backwards compatibility with new dropdowns, redeclare dropdown link padding
+.topbar ul .menu-dropdown li a,
+.topbar ul .dropdown-menu li a {
+  padding: 4px 15px;
+}
+
+// Dropdown Menus
+// Use the .menu class on any <li> element within the topbar or ul.tabs and you'll get some superfancy dropdowns
+// li.menu for backwards compatibility
+li.menu,
+.dropdown {
+  position: relative;
+}
+// The link that is clicked to toggle the dropdown
+// a.menu for backwards compatibility
+a.menu:after,
+.dropdown-toggle:after {
+  width: 0;
+  height: 0;
+  display: inline-block;
+  content: "&darr;";
+  text-indent: -99999px;
+  vertical-align: top;
+  margin-top: 8px;
+  margin-left: 4px;
+  border-left: 4px solid transparent;
+  border-right: 4px solid transparent;
+  border-top: 4px solid @white;
+  .opacity(50);
+}
+// The dropdown menu (ul)
+// .menu-dropdown for backwards compatibility
+.menu-dropdown,
+.dropdown-menu {
+  background-color: @white;
+  float: left;
+  display: none; // None by default, but block on "open" of the menu
+  position: absolute;
+  top: 40px;
+  z-index: 900;
+  min-width: 160px;
+  max-width: 220px;
+  _width: 160px;
+  margin-left: 0; // override default ul styles
+  margin-right: 0;
+  padding: 6px 0;
+  zoom: 1; // do we need this?
+  border-color: #999;
+  border-color: rgba(0,0,0,.2);
+  border-style: solid;
+  border-width: 0 1px 1px;
+  .border-radius(0 0 6px 6px);
+  .box-shadow(0 2px 4px rgba(0,0,0,.2));
+  .background-clip(padding-box);
+
+  // Unfloat any li's to make them stack
+  li {
+    float: none;
+    display: block;
+    background-color: none;
+  }
+  // Dividers (basically an hr) within the dropdown
+  .divider {
+    height: 1px;
+    margin: 5px 0;
+    overflow: hidden;
+    background-color: #eee;
+    border-bottom: 1px solid @white;
+  }
+}
+
+.topbar .dropdown-menu,
+.dropdown-menu {
+  // Links within the dropdown menu
+  a {
+    display: block;
+    padding: 4px 15px;
+    clear: both;
+    font-weight: normal;
+    line-height: 18px;
+    color: @gray;
+    text-shadow: 0 1px 0 @white;
+    // Hover state
+    &:hover,
+    &.hover {
+      #gradient > .vertical(#eeeeee, #dddddd);
+      color: @grayDark;
+      text-decoration: none;
+      @shadow: inset 0 1px 0 rgba(0,0,0,.025), inset 0 -1px rgba(0,0,0,.025);
+      .box-shadow(@shadow);
+    }
+  }
+}
+
+// Open state for the dropdown
+// .open for backwards compatibility
+.open,
+.dropdown.open {
+  // .menu for backwards compatibility
+  .menu,
+  .dropdown-toggle {
+    color: @white;
+    background: #ccc;
+    background: rgba(0,0,0,.3);
+  }
+  // .menu-dropdown for backwards compatibility
+  .menu-dropdown,
+  .dropdown-menu {
+    display: block;
+  }
+}
+
+
+// TABS AND PILLS
+// --------------
+
+// Common styles
+.tabs,
+.pills {
+  margin: 0 0 @baseline;
+  padding: 0;
+  list-style: none;
+  .clearfix();
+  > li {
+    float: left;
+    > a {
+      display: block;
+    }
+  }
+}
+
+// Tabs
+.tabs {
+  border-color: #ddd;
+  border-style: solid;
+  border-width: 0 0 1px;
+  > li {
+    position: relative; // For the dropdowns mostly
+    margin-bottom: -1px;
+    > a {
+      padding: 0 15px;
+      margin-right: 2px;
+      line-height: (@baseline * 2) - 2;
+      border: 1px solid transparent;
+      .border-radius(4px 4px 0 0);
+      &:hover {
+        text-decoration: none;
+        background-color: #eee;
+        border-color: #eee #eee #ddd;
+      }
+    }
+  }
+  // Active state, and it's :hover to override normal :hover
+  .active > a,
+  .active > a:hover {
+    color: @gray;
+    background-color: @white;
+    border: 1px solid #ddd;
+    border-bottom-color: transparent;
+    cursor: default;
+  }
+}
+
+// Dropdowns in tabs
+.tabs {
+  // first one for backwards compatibility
+  .menu-dropdown,
+  .dropdown-menu {
+    top: 35px;
+    border-width: 1px;
+    .border-radius(0 6px 6px 6px);
+  }
+  // first one for backwards compatibility
+  a.menu:after,
+  .dropdown-toggle:after {
+    border-top-color: #999;
+    margin-top: 15px;
+    margin-left: 5px;
+  }
+  // first one for backwards compatibility
+  li.open.menu .menu,
+  .open.dropdown .dropdown-toggle {
+    border-color: #999;
+  }
+  // first one for backwards compatibility
+  li.open a.menu:after,
+  .dropdown.open .dropdown-toggle:after {
+    border-top-color: #555;
+  }
+}
+
+// Pills
+.pills {
+  a {
+    margin: 5px 3px 5px 0;
+    padding: 0 15px;
+    line-height: 30px;
+    text-shadow: 0 1px 1px @white;
+    .border-radius(15px);
+    &:hover {
+      color: @white;
+      text-decoration: none;
+      text-shadow: 0 1px 1px rgba(0,0,0,.25);
+      background-color: @linkColorHover;
+    }
+  }
+  .active a {
+    color: @white;
+    text-shadow: 0 1px 1px rgba(0,0,0,.25);
+    background-color: @linkColor;
+  }
+}
+
+// Stacked pills
+.pills-vertical > li {
+  float: none;
+}
+
+// Tabbable areas
+.tab-content,
+.pill-content {
+}
+.tab-content > .tab-pane,
+.pill-content > .pill-pane,
+.tab-content > div,
+.pill-content > div {
+  display: none;
+}
+.tab-content > .active,
+.pill-content > .active {
+  display: block;
+}
+
+
+// BREADCRUMBS
+// -----------
+
+.breadcrumb {
+  padding: 7px 14px;
+  margin: 0 0 @baseline;
+  #gradient > .vertical(#ffffff, #f5f5f5);
+  border: 1px solid #ddd;
+  .border-radius(3px);
+  .box-shadow(inset 0 1px 0 @white);
+  li {
+    display: inline;
+    text-shadow: 0 1px 0 @white;
+  }
+  .divider {
+    padding: 0 5px;
+    color: @grayLight;
+  }
+  .active a {
+    color: @grayDark;
+  }
+}
+
+
+// PAGE HEADERS
+// ------------
+
+.hero-unit {
+  background-color: #f5f5f5;
+  margin-bottom: 30px;
+  padding: 60px;
+  .border-radius(6px);
+  h1 {
+    margin-bottom: 0;
+    font-size: 60px;
+    line-height: 1;
+    letter-spacing: -1px;
+  }
+  p {
+    font-size: 18px;
+    font-weight: 200;
+    line-height: @baseline * 1.5;
+  }
+}
+footer {
+  margin-top: @baseline - 1;
+  padding-top: @baseline - 1;
+  border-top: 1px solid #eee;
+}
+
+
+// PAGE HEADERS
+// ------------
+
+.page-header {
+  margin-bottom: @baseline - 1;
+  border-bottom: 1px solid #ddd;
+  .box-shadow(0 1px 0 rgba(255,255,255,.5));
+  h1 {
+    margin-bottom: (@baseline / 2) - 1px;
+  }
+}
+
+
+// BUTTON STYLES
+// -------------
+
+// Shared colors for buttons and alerts
+.btn,
+.alert-message {
+  // Set text color
+  &.danger,
+  &.danger:hover,
+  &.error,
+  &.error:hover,
+  &.success,
+  &.success:hover,
+  &.info,
+  &.info:hover {
+    color: @white
+  }
+  // Sets the close button to the middle of message
+  .close{
+    font-family: Arial, sans-serif;
+    line-height: 18px;
+  }
+  // Danger and error appear as red
+  &.danger,
+  &.error {
+    .gradientBar(#ee5f5b, #c43c35);
+  }
+  // Success appears as green
+  &.success {
+    .gradientBar(#62c462, #57a957);
+  }
+  // Info appears as a neutral blue
+  &.info {
+    .gradientBar(#5bc0de, #339bb9);
+  }
+}
+
+// Base .btn styles
+.btn {
+  // Button Base
+  cursor: pointer;
+  display: inline-block;
+  #gradient > .vertical-three-colors(#ffffff, #ffffff, 25%, darken(#ffffff, 10%)); // Don't use .gradientbar() here since it does a three-color gradient
+  padding: 5px 14px 6px;
+  text-shadow: 0 1px 1px rgba(255,255,255,.75);
+  color: #333;
+  font-size: @basefont;
+  line-height: normal;
+  border: 1px solid #ccc;
+  border-bottom-color: #bbb;
+  .border-radius(4px);
+  @shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
+  .box-shadow(@shadow);
+
+  &:hover {
+    background-position: 0 -15px;
+    color: #333;
+    text-decoration: none;
+  }
+
+  // Focus state for keyboard and accessibility
+  &:focus {
+    outline: 1px dotted #666;
+  }
+
+  // Primary Button Type
+  &.primary {
+    color: @white;
+    .gradientBar(@blue, @blueDark)
+  }
+
+   // Transitions
+  .transition(.1s linear all);
+
+  // Active and Disabled states
+  &.active,
+  &:active {
+    @shadow: inset 0 2px 4px rgba(0,0,0,.25), 0 1px 2px rgba(0,0,0,.05);
+    .box-shadow(@shadow);
+  }
+  &.disabled {
+    cursor: default;
+    background-image: none;
+    .reset-filter();
+    .opacity(65);
+    .box-shadow(none);
+  }
+  &[disabled] {
+    // disabled pseudo can't be included with .disabled
+    // def because IE8 and below will drop it ;_;
+    cursor: default;
+    background-image: none;
+    .reset-filter();
+    .opacity(65);
+    .box-shadow(none);
+  }
+
+  // Button Sizes
+  &.large {
+    font-size: @basefont + 2px;
+    line-height: normal;
+    padding: 9px 14px 9px;
+    .border-radius(6px);
+  }
+  &.small {
+    padding: 7px 9px 7px;
+    font-size: @basefont - 2px;
+  }
+}
+// Super jank hack for removing border-radius from IE9 so we can keep filter gradients on alerts and buttons
+:root .alert-message,
+:root .btn {
+  border-radius: 0 \0;
+}
+
+// Help Firefox not be a jerk about adding extra padding to buttons
+button.btn,
+input[type=submit].btn {
+  &::-moz-focus-inner {
+       padding: 0;
+       border: 0;
+  }
+}
+
+
+// CLOSE ICONS
+// -----------
+.close {
+  float: right;
+  color: @black;
+  font-size: 20px;
+  font-weight: bold;
+  line-height: @baseline * .75;
+  text-shadow: 0 1px 0 rgba(255,255,255,1);
+  .opacity(25);
+  &:hover {
+    color: @black;
+    text-decoration: none;
+    .opacity(40);
+  }
+}
+
+
+// ERROR STYLES
+// ------------
+
+// Base alert styles
+.alert-message {
+  position: relative;
+  padding: 7px 15px;
+  margin-bottom: @baseline;
+  color: @grayDark;
+  .gradientBar(#fceec1, #eedc94); // warning by default
+  text-shadow: 0 1px 0 rgba(255,255,255,.5);
+  border-width: 1px;
+  border-style: solid;
+  .border-radius(4px);
+  .box-shadow(inset 0 1px 0 rgba(255,255,255,.25));
+
+  // Adjust close icon
+  .close {
+    margin-top: 1px;
+    *margin-top: 0; // For IE7
+  }
+
+  // Make links same color as text and stand out more
+  a {
+    font-weight: bold;
+    color: @grayDark;
+  }
+  &.danger p a,
+  &.error p a,
+  &.success p a,
+  &.info p a {
+    color: @white;
+  }
+
+  // Remove extra margin from content
+  h5 {
+    line-height: @baseline;
+  }
+  p {
+    margin-bottom: 0;
+  }
+  div {
+    margin-top: 5px;
+    margin-bottom: 2px;
+    line-height: 28px;
+  }
+  .btn {
+    // Provide actions with buttons
+    .box-shadow(0 1px 0 rgba(255,255,255,.25));
+  }
+
+  &.block-message {
+    background-image: none;
+    background-color: lighten(#fceec1, 5%);
+    .reset-filter();
+    padding: 14px;
+    border-color: #fceec1;
+    .box-shadow(none);
+    ul, p {
+      margin-right: 30px;
+    }
+    ul {
+      margin-bottom: 0;
+    }
+    li {
+      color: @grayDark;
+    }
+    .alert-actions {
+      margin-top: 5px;
+    }
+    &.error,
+    &.success,
+    &.info {
+      color: @grayDark;
+      text-shadow: 0 1px 0 rgba(255,255,255,.5);
+    }
+    &.error {
+      background-color: lighten(#f56a66, 25%);
+      border-color: lighten(#f56a66, 20%);
+    }
+    &.success {
+      background-color: lighten(#62c462, 30%);
+      border-color: lighten(#62c462, 25%);
+    }
+    &.info {
+      background-color: lighten(#6bd0ee, 25%);
+      border-color: lighten(#6bd0ee, 20%);
+    }
+    // Change link color back
+    &.danger p a,
+    &.error p a,
+    &.success p a,
+    &.info p a {
+      color: @grayDark;
+    }
+
+  }
+}
+
+
+// PAGINATION
+// ----------
+
+.pagination {
+  height: @baseline * 2;
+  margin: @baseline 0;
+  ul {
+    float: left;
+    margin: 0;
+    border: 1px solid #ddd;
+    border: 1px solid rgba(0,0,0,.15);
+    .border-radius(3px);
+    .box-shadow(0 1px 2px rgba(0,0,0,.05));
+  }
+  li {
+    display: inline;
+  }
+  a {
+    float: left;
+    padding: 0 14px;
+    line-height: (@baseline * 2) - 2;
+    border-right: 1px solid;
+    border-right-color: #ddd;
+    border-right-color: rgba(0,0,0,.15);
+    *border-right-color: #ddd; /* IE6-7 */
+    text-decoration: none;
+  }
+  a:hover,
+  .active a {
+    background-color: lighten(@blue, 45%);
+  }
+  .disabled a,
+  .disabled a:hover {
+    background-color: transparent;
+    color: @grayLight;
+  }
+  .next a {
+    border: 0;
+  }
+}
+
+
+// WELLS
+// -----
+
+.well {
+  background-color: #f5f5f5;
+  margin-bottom: 20px;
+  padding: 19px;
+  min-height: 20px;
+  border: 1px solid #eee;
+  border: 1px solid rgba(0,0,0,.05);
+  .border-radius(4px);
+  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
+  blockquote {
+    border-color: #ddd;
+    border-color: rgba(0,0,0,.15);
+  }
+}
+
+
+// MODALS
+// ------
+
+.modal-backdrop {
+  background-color: @black;
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 10000;
+  // Fade for backdrop
+  &.fade { opacity: 0; }
+}
+
+.modal-backdrop,
+.modal-backdrop.fade.in {
+  .opacity(80);
+}
+
+.modal {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  z-index: 11000;
+  width: 560px;
+  margin: -250px 0 0 -280px;
+  background-color: @white;
+  border: 1px solid #999;
+  border: 1px solid rgba(0,0,0,.3);
+  *border: 1px solid #999; /* IE6-7 */
+  .border-radius(6px);
+  .box-shadow(0 3px 7px rgba(0,0,0,0.3));
+  .background-clip(padding-box);
+  .close { margin-top: 7px; }
+  &.fade {
+    .transition(e('opacity .3s linear, top .3s ease-out'));
+    top: -25%;
+  }
+  &.fade.in { top: 50%; }
+}
+.modal-header {
+  border-bottom: 1px solid #eee;
+  padding: 5px 15px;
+}
+.modal-body {
+  padding: 15px;
+}
+.modal-body form {
+  margin-bottom: 0;
+}
+.modal-footer {
+  background-color: #f5f5f5;
+  padding: 14px 15px 15px;
+  border-top: 1px solid #ddd;
+  .border-radius(0 0 6px 6px);
+  .box-shadow(inset 0 1px 0 @white);
+  .clearfix();
+  margin-bottom: 0;
+  .btn {
+    float: right;
+    margin-left: 5px;
+  }
+}
+
+// Fix the stacking of these components when in modals
+.modal .popover,
+.modal .twipsy {
+  z-index: 12000;
+}
+
+
+// POPOVER ARROWS
+// --------------
+
+#popoverArrow {
+  .above(@arrowWidth: 5px) {
+    bottom: 0;
+    left: 50%;
+    margin-left: -@arrowWidth;
+    border-left: @arrowWidth solid transparent;
+    border-right: @arrowWidth solid transparent;
+    border-top: @arrowWidth solid @black;
+  }
+  .left(@arrowWidth: 5px) {
+    top: 50%;
+    right: 0;
+    margin-top: -@arrowWidth;
+    border-top: @arrowWidth solid transparent;
+    border-bottom: @arrowWidth solid transparent;
+    border-left: @arrowWidth solid @black;
+  }
+  .below(@arrowWidth: 5px) {
+    top: 0;
+    left: 50%;
+    margin-left: -@arrowWidth;
+    border-left: @arrowWidth solid transparent;
+    border-right: @arrowWidth solid transparent;
+    border-bottom: @arrowWidth solid @black;
+  }
+  .right(@arrowWidth: 5px) {
+    top: 50%;
+    left: 0;
+    margin-top: -@arrowWidth;
+    border-top: @arrowWidth solid transparent;
+    border-bottom: @arrowWidth solid transparent;
+    border-right: @arrowWidth solid @black;
+  }
+}
+
+// TWIPSY
+// ------
+
+.twipsy {
+  display: block;
+  position: absolute;
+  visibility: visible;
+  padding: 5px;
+  font-size: 11px;
+  z-index: 1000;
+  .opacity(80);
+  &.fade.in {
+    .opacity(80);
+  }
+  &.above .twipsy-arrow   { #popoverArrow > .above(); }
+  &.left .twipsy-arrow    { #popoverArrow > .left(); }
+  &.below .twipsy-arrow   { #popoverArrow > .below(); }
+  &.right .twipsy-arrow   { #popoverArrow > .right(); }
+}
+.twipsy-inner {
+  padding: 3px 8px;
+  background-color: @black;
+  color: white;
+  text-align: center;
+  max-width: 200px;
+  text-decoration: none;
+  .border-radius(4px);
+}
+.twipsy-arrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+}
+
+
+// POPOVERS
+// --------
+
+.popover {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 1000;
+  padding: 5px;
+  display: none;
+  &.above .arrow { #popoverArrow > .above(); }
+  &.right .arrow { #popoverArrow > .right(); }
+  &.below .arrow { #popoverArrow > .below(); }
+  &.left .arrow  { #popoverArrow > .left(); }
+  .arrow {
+    position: absolute;
+    width: 0;
+    height: 0;
+  }
+  .inner {
+    background: @black;
+    background: rgba(0,0,0,.8);
+    padding: 3px;
+    overflow: hidden;
+    width: 280px;
+    .border-radius(6px);
+    .box-shadow(0 3px 7px rgba(0,0,0,0.3));
+  }
+  .title {
+    background-color: #f5f5f5;
+    padding: 9px 15px;
+    line-height: 1;
+    .border-radius(3px 3px 0 0);
+    border-bottom:1px solid #eee;
+  }
+  .content {
+    background-color: @white;
+    padding: 14px;
+    .border-radius(0 0 3px 3px);
+    .background-clip(padding-box);
+    p, ul, ol {
+      margin-bottom: 0;
+    }
+  }
+}
+
+
+// PATTERN ANIMATIONS
+// ------------------
+
+.fade {
+  .transition(opacity .15s linear);
+  opacity: 0;
+  &.in {
+    opacity: 1;
+  }
+}
+
+
+// LABELS
+// ------
+
+.label {
+  padding: 1px 3px 2px;
+  font-size: @basefont * .75;
+  font-weight: bold;
+  color: @white;
+  text-transform: uppercase;
+  white-space: nowrap;
+  background-color: @grayLight;
+  .border-radius(3px);
+  &.important { background-color: #c43c35; }
+  &.warning   { background-color: @orange; }
+  &.success   { background-color: @green; }
+  &.notice    { background-color: lighten(@blue, 25%); }
+}
+
+
+// MEDIA GRIDS
+// -----------
+
+.media-grid {
+  margin-left: -@gridGutterWidth;
+  margin-bottom: 0;
+  .clearfix();
+  li {
+    display: inline;
+  }
+  a {
+    float: left;
+    padding: 4px;
+    margin: 0 0 @baseline @gridGutterWidth;
+    border: 1px solid #ddd;
+    .border-radius(4px);
+    .box-shadow(0 1px 1px rgba(0,0,0,.075));
+    img {
+      display: block;
+    }
+    &:hover {
+      border-color: @linkColor;
+      .box-shadow(0 1px 4px rgba(0,105,214,.25));
+    }
+  }
+}
diff --git a/cloudcms/static/cloudcms/less/reset.less b/cloudcms/static/cloudcms/less/reset.less
new file mode 100644 (file)
index 0000000..6be76fd
--- /dev/null
@@ -0,0 +1,141 @@
+/* Reset.less
+ * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here      that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc).
+ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
+
+
+// ERIC MEYER RESET
+// --------------------------------------------------
+
+html, body { margin: 0; padding: 0; }
+h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, cite, code, del, dfn, em, img, q, s, samp, small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset, form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; font-weight: normal; font-style: normal; font-size: 100%; line-height: 1; font-family: inherit; }
+table { border-collapse: collapse; border-spacing: 0; }
+ol, ul { list-style: none; }
+q:before, q:after, blockquote:before, blockquote:after { content: ""; }
+
+
+// Normalize.css
+// Pulling in select resets form the normalize.css project
+// --------------------------------------------------
+
+// Display in IE6-9 and FF3
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+html {
+  overflow-y: scroll;
+  font-size: 100%;
+  -webkit-text-size-adjust: 100%;
+      -ms-text-size-adjust: 100%;
+}
+// Focus states
+a:focus {
+  outline: thin dotted;
+}
+// Hover & Active
+a:hover,
+a:active {
+  outline: 0;
+}
+
+// Display in IE6-9 and FF3
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section {
+  display: block;
+}
+
+// Display block in IE6-9 and FF3
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+audio,
+canvas,
+video {
+  display: inline-block;
+  *display: inline;
+  *zoom: 1;
+}
+
+// Prevents modern browsers from displaying 'audio' without controls
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+audio:not([controls]) {
+    display: none;
+}
+
+// Prevents sub and sup affecting line-height in all browsers
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup {
+  top: -0.5em;
+}
+sub {
+  bottom: -0.25em;
+}
+
+// Img border in a's and image quality
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+img {
+    border: 0;
+    -ms-interpolation-mode: bicubic;
+}
+
+// Forms
+// -------------------------
+// Source: http://github.com/necolas/normalize.css
+
+// Font size in all browsers, margin changes, misc consistency
+button,
+input,
+select,
+textarea {
+  font-size: 100%;
+  margin: 0;
+  vertical-align: baseline;
+  *vertical-align: middle;
+}
+button,
+input {
+  line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
+  *overflow: visible; // Inner spacing ie IE6/7
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
+  border: 0;
+  padding: 0;
+}
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  cursor: pointer; // Cursors on all buttons applied consistently
+  -webkit-appearance: button; // Style clicable inputs in iOS
+}
+input[type="search"] { // Appearance in Safari/Chrome
+  -webkit-appearance: textfield;
+  -webkit-box-sizing: content-box;
+     -moz-box-sizing: content-box;
+          box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
+}
+textarea {
+  overflow: auto; // Remove vertical scrollbar in IE6-9
+  vertical-align: top; // Readability and alignment cross-browser
+}
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/less/scaffolding.less b/cloudcms/static/cloudcms/less/scaffolding.less
new file mode 100644 (file)
index 0000000..e990462
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Scaffolding
+ * Basic and global styles for generating a grid system, structural layout, and page templates
+ * ------------------------------------------------------------------------------------------- */
+
+
+// STRUCTURAL LAYOUT
+// -----------------
+
+body {
+  background-color: @white;
+  margin: 0;
+  #font > .sans-serif(normal,@basefont,@baseline);
+  color: @grayDark;
+}
+
+// Container (centered, fixed-width layouts)
+.container {
+  .fixed-container();
+}
+
+// Fluid layouts (left aligned, with sidebar, min- & max-width content)
+.container-fluid {
+  position: relative;
+  min-width: 940px;
+  padding-left: 20px;
+  padding-right: 20px;
+  .clearfix();
+  > .sidebar {
+    position: absolute;
+    top: 0;
+    left: 20px;
+    width: 220px;
+  }
+  // TODO in v2: rename this and .popover .content to be more specific
+  > .content {
+    margin-left: 240px;
+  }
+}
+
+
+// BASE STYLES
+// -----------
+
+// Links
+a {
+  color: @linkColor;
+  text-decoration: none;
+  line-height: inherit;
+  font-weight: inherit;
+  &:hover {
+    color: @linkColorHover;
+    text-decoration: underline;
+  }
+}
+
+// Quick floats
+.pull-right {
+  float: right;
+}
+.pull-left {
+  float: left;
+}
+
+// Toggling content
+.hide {
+  display: none;
+}
+.show {
+  display: block;
+}
+
+
+// GRID SYSTEM
+// -----------
+// To customize the grid system, bring up the variables.less file and change the column count, size, and gutter there
+
+.row {
+  .clearfix();
+  margin-left: -@gridGutterWidth;
+}
+
+// Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7)
+// Credit to @dhg for the idea
+.row > [class*="span"] {
+  .gridColumn();
+}
+
+// Default columns
+.span1     { .columns(1); }
+.span2     { .columns(2); }
+.span3     { .columns(3); }
+.span4     { .columns(4); }
+.span5     { .columns(5); }
+.span6     { .columns(6); }
+.span7     { .columns(7); }
+.span8     { .columns(8); }
+.span9     { .columns(9); }
+.span10    { .columns(10); }
+.span11    { .columns(11); }
+.span12    { .columns(12); }
+.span13    { .columns(13); }
+.span14    { .columns(14); }
+.span15    { .columns(15); }
+.span16    { .columns(16); }
+
+// For optional 24-column grid
+.span17    { .columns(17); }
+.span18    { .columns(18); }
+.span19    { .columns(19); }
+.span20    { .columns(20); }
+.span21    { .columns(21); }
+.span22    { .columns(22); }
+.span23    { .columns(23); }
+.span24    { .columns(24); }
+
+// Offset column options
+.row {
+  > .offset1   { .offset(1); }
+  > .offset2   { .offset(2); }
+  > .offset3   { .offset(3); }
+  > .offset4   { .offset(4); }
+  > .offset5   { .offset(5); }
+  > .offset6   { .offset(6); }
+  > .offset7   { .offset(7); }
+  > .offset8   { .offset(8); }
+  > .offset9   { .offset(9); }
+  > .offset10  { .offset(10); }
+  > .offset11  { .offset(11); }
+  > .offset12  { .offset(12); }
+}
+
+// Unique column sizes for 16-column grid
+.span-one-third     { width: 300px; }
+.span-two-thirds    { width: 620px; }
+.row {
+  > .offset-one-third   { margin-left: 340px; }
+  > .offset-two-thirds  { margin-left: 660px; }
+}
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/less/servicesbar.less b/cloudcms/static/cloudcms/less/servicesbar.less
new file mode 100644 (file)
index 0000000..e4d03a7
--- /dev/null
@@ -0,0 +1,71 @@
+@import "../less/bootstrap.less";
+
+@toolbarBg: #222;
+@toolbarColor: darken(@white, 10%);
+@toolbarHeight: 30px;
+
+.servicesbar {
+    font-family: arial, sans-serif;
+    font-size: 11px;
+    letter-spacing: 0px;
+    .clearfix();
+    color: #ccc;
+    z-index: 1000;
+    border-bottom: 1px solid #444;
+
+    background-color: darken(@toolbarBg, 40%);
+
+    a {
+        color: @toolbarColor;    
+        text-decoration: none;
+        display: block;
+        float: left;
+        padding: 11px;
+        &:hover {
+            background-color: #444;
+        }
+        &.active {
+            font-weight: bold;
+            background-color: #333;
+        }
+    }
+
+    .services {
+        .clearfix();
+    }    
+
+    position: relative;
+
+    .profile {
+        margin-top: -34px;
+        .clearfix();
+        text-align: right;
+        min-width: 200px;
+        a {
+                    float: none;
+        }
+        ul {
+            display: none;    
+            li {
+                width: 100%;
+                border-bottom: 1px solid #444;
+                background-color: #333;
+                a {
+                    float: none;
+                    display: block;
+                }
+            }
+        }
+        &:hover {
+            background-color: #222;
+            ul {
+                display: block;    
+            }
+        }
+        background-color: @black;
+        .clearfix();
+        position: absolute;
+        right: 0;
+        float: right;    
+    }
+}
diff --git a/cloudcms/static/cloudcms/less/styles.less b/cloudcms/static/cloudcms/less/styles.less
new file mode 100644 (file)
index 0000000..3d0cbc8
--- /dev/null
@@ -0,0 +1,587 @@
+@import "../less/bootstrap.less";
+@import "../less/django_forms.less";
+@import "../less/tables.less";
+@import "../less/cloudbox.less";
+
+
+@gradCol: #ddd;
+body {
+    #font.main();
+}
+
+.topbar {
+    background-color: @shadowColor;
+    .head {
+        float: left;    
+            padding: @gridGutterWidth/2-5;
+    }
+    .links {
+        .clearfix();
+        a {
+            color: @black;
+            text-decoration: none;
+            display: block;
+            float: left;
+            margin-left: 10px;
+            padding: @gridGutterWidth/2+1;
+
+            &:hover {
+                background-color: lighten(@black, 10%);
+                color: @white;
+            }
+        }
+
+        float: right;    
+    }
+}
+
+// default link styles
+section a, p a, form a, .section a {
+    color: @black;
+    text-decoration: none;
+    border-bottom: 1px solid @linkColor;
+
+    &:hover {
+        color: @linkColor;
+    }
+
+    &.noborder {
+        border: none;   
+    }
+
+    em {
+        color: @blue;    
+    }
+}
+
+a.simple {
+    border: none;
+
+}
+a.action {
+    color: @linkColor;
+    border-bottom: none;
+}
+
+a img {
+    border-bottom: none;
+}
+
+// body borders
+.content-border {
+    border-right: 1px solid @mainBorderColor;
+    border-left: 1px solid @mainBorderColor;
+}
+
+.hidden {
+    display: none !important;
+}
+
+// container sizing
+.container, .topbar, .footer {
+    .fixed-container();
+    .content-border();
+    padding: 0 @siteWhiteSpace;
+}
+
+.container {
+    padding-bottom: @siteWhiteSpace;
+    background-color: @white;
+}
+
+.topbar {
+}
+
+
+div.header {
+    position: relative;
+    margin-top: 4*@gridGutterWidth;
+    margin-bottom: @gridGutterWidth;
+    h1 {
+        color: @shadowColor;
+        display: inline;
+        font-size: 2.3em;
+        border-bottom: 1px solid @shadowColor;
+        padding-bottom: 3px;
+    }
+}
+.mainlogo {
+    img {
+        margin-left: -10px;
+    }
+}
+
+.footer {
+    border-bottom: 1px solid @mainBorderColor;
+    border-top: 1px solid lighten(@mainBorderColor, 15%);
+    padding-top: @gridGutterWidth;
+    padding-bottom: @gridGutterWidth;
+}
+
+ul.inline {
+    .clearfix();
+    li {
+        display: block;    
+        float: left;
+        margin-right: 1em;
+    }
+}
+
+.mainnav.quicknav {
+    position: absolute;
+    right: 0;
+    top: -2.6*@gridGutterWidth;
+    margin:0;
+
+    li {
+        margin-right:0;
+        margin-left: 1em;
+    }
+}
+
+
+.mainnav {
+    font-size: 1.2em;
+    
+    &.subnav {
+        margin-bottom: -@gridGutterWidth;
+        li {
+            margin-top: 1.2em;
+        }
+    }
+
+    li {
+        margin-top: 3*@gridGutterWidth;
+    }
+
+    li.active {
+        a {
+            /*border-bottom: 1px solid @linkColor;*/
+            border-bottom: none;
+            color: @linkColor;
+        }
+    }
+    a {
+        color: @black;
+        text-decoration: none;
+
+        &:hover {
+            border-bottom: 1px solid @linkColor;
+        }
+
+        &.active, &:active {
+            border-bottom: 1px solid @linkColor;
+            color: @linkColor;
+        }
+    }
+}
+
+.page {
+    .makeRow();
+    margin-top: 6*@gridGutterWidth;
+    font-size: 1.1em;
+    .page-inner {
+        position: relative;    
+    }
+}
+
+// columnlayout
+.maincol {
+    .makeColumn(5);
+    
+    &.wide {
+        .makeColumn(6);    
+    }
+
+    &.full {
+        .makeRow();
+        margin-left: 0;
+        .makeColumn(10);
+    }
+}
+
+.appbar {
+    height: 30px;
+    background-color: @blue;
+}
+
+.rightcol {
+    .offset(6.5);
+    .columns(4);
+
+    &.narrow {
+        .offset(7.5);
+        .columns(3);    
+    }
+    input[type=text], input[type=password] {
+        width: 3*@gridColumnWidth + 4*@gridGutterWidth + 5;    
+    }
+}
+
+/* generic form styles */
+input, textarea {
+    background-color: @white;
+    color: @gray;
+    border-color: @black;
+}
+
+#forms {
+    .input, input {
+        #font.main();
+        border: 1px solid @gray;
+        margin-bottom: -1px;
+        padding: 0.8em;
+        padding-left: 1.5em;
+        z-index: 2;
+        &:focus {
+            position: relative;
+            border: 1px solid #000;
+            z-index: 100;
+
+            label {
+                z-index: 300;    
+            }
+        }
+    }
+}
+
+.altcol {
+    background-color: @altColor !important;
+
+    &:hover {
+        background-color: @linkColor !important;
+    }
+}
+
+.section {
+
+    &.positioned {
+        margin-bottom: 0;
+        .content {
+            .makeColumn(4);
+        }
+
+        img {
+        }
+
+        &.withimg {
+            .img {
+                .makeColumn(4);
+            }
+
+            img {
+                float: left;    
+            }
+        }
+        
+        h3 {
+            font-size: 1.2em;
+            margin-bottom: @gridGutterWidth;    
+        }
+
+        .text {
+            color: @black;    
+        }
+    }
+
+    margin-bottom: 3*@gridGutterWidth; 
+
+    .left, .right {
+        width: 50%;
+        float: left;
+    }
+
+    &.imagelist {
+        margin-top: 2em;
+        .clearfix();
+        img {
+            float: left;    
+            margin-right: 4em;
+            vertical-align: middle;
+        }    
+    }
+}
+
+input[readonly=true] {
+    background-color: #ddd;
+    color: darken(#ddd, 50%);
+}
+
+form.withlabels {
+    label {
+        width: 3*@gridColumnWidth + 2*@gridGutterWidth;
+        display: block;
+        float: left;
+        padding-top: 1em;
+    }
+
+    input[type=text], input[type=password], textarea {
+        width: 3*@gridColumnWidth + 2*@gridGutterWidth;
+
+        &.long {
+            width: 3*@gridColumnWidth + 2*@gridGutterWidth;
+        }
+    }
+}
+
+@errorColor: lighten(@red, 30%);
+// forms
+form {
+    
+    &.login {
+        margin-bottom: 3em; 
+    }
+
+    h2 {
+        color: @black;
+        margin-bottom: @gridGutterWidth;
+        font-size: 1.1em;
+
+        span {
+            padding-bottom: 3px;
+        }
+    }
+
+    .form-row {
+        position: relative;
+        &.submit {
+            margin-top: @gridGutterWidth;
+        }
+
+        .extra-link {
+            color: @gray;
+            text-decoration: none;
+            border: none;
+            font-size: 0.8em;
+            margin-top: 1.3em;
+            float: right;
+        }
+    }
+    
+    &.innerlabels label { 
+        position: absolute;
+        top:1em;
+        left:1.5em;
+        color: #aaa;
+    }
+
+    &.innerlabels p {
+        position: relative;    
+    }
+
+    textarea, input.text, input[type="text"], input[type="password"] {
+        #forms.input();
+    }
+
+    input.submit, input[type="submit"] {
+        .button();
+    }
+
+    
+    .with-errors {
+        input, textarea, select {
+            color: @red;
+        }
+        label {
+            color: @errorColor;
+        }
+    }
+}
+
+.form-error {
+    background-color: @red;
+    color: #fff;
+    font-size: 0.8em;
+    padding: 5px 5px;
+}
+
+.form-errors.all {
+    .form-error {
+        position: relative;
+        border-radius: 0;
+        margin-bottom: 1.3em;
+        padding: 0.5em;
+    }
+}
+
+div.form-stacked {
+    margin-bottom: 4em;
+}
+// content types
+.section {
+    h2 {
+        font-size: 1.1em;
+        margin-bottom: 1.5*@gridGutterWidth;    
+
+        a {
+            color: #4085A6;
+            border: none;
+            line-height: 1.3em;
+        }
+    }
+
+    p {
+        line-height: 1.7em;    
+    }
+}
+
+
+// page messages
+.messages {
+    .makeColumn(10);
+
+    margin-bottom: 2em;
+    background-color: #ddd;
+
+    li {
+        padding: 1em;    
+
+        &.success { background-color: @green; color: @white }
+        &.error { background-color: @red; color: @white }
+        &.warning { background-color: @yellow; color: @black }
+    }
+
+}
+
+// accounts specific styles
+.service-desc {
+    margin-top: 4em;    
+
+}
+
+
+// invitations table
+table {
+
+    td.consumed {
+        color: @red;
+    }
+
+    tr.consumed {
+        td.consumed {
+            color: @green;    
+        }
+    }
+}
+
+
+.row { .makeRow() }
+
+// footer
+.footer {
+    .makeRow()
+    
+    &:hover {
+        a {
+            color: @gray !important;
+            .transit();
+        }
+    }
+
+    a {
+        color: lighten(@gray, 20%);    
+        .transit();
+        text-decoration: none;
+
+        &:hover {
+            color: darken(@gray, 50%);    
+        }
+    }
+
+    li {
+        margin-bottom: @gridGutterWidth/2;
+
+        &.header {
+            margin-bottom: @gridGutterWidth;    
+        }
+    }
+
+    .col {
+        .makeColumn(4);
+        &:last-child, &.last {
+            width: 140px;
+            margin-right:0;
+        }
+    }
+
+    .bottom.row {
+        .col {
+            .makeColumn(2);    
+            &:last-child, &.last {
+                width: 140px;
+                margin-right:0;
+            }
+        }
+    }
+}
+
+
+/*pagination*/
+
+
+/*blog styles*/
+.blog-entries {
+
+}
+
+.blog-entry {
+
+    .section();
+    .clearfix();
+    margin-bottom: 2*@gridGutterWidth;    
+
+    .title {
+        margin-bottom: 1em;    
+        font-size: 1.1em;
+        line-height: 1.4em;
+    }    
+
+    .media {
+        img {
+            border: 1px solid @gray;    
+        }    
+    }
+    
+    .intro-content, .content {
+        margin-top: @gridGutterWidth;
+
+        object {
+            margin: @gridGutterWidth 0;    
+        }
+    }
+
+    .entry-info {
+        font-size: 0.7em;
+        margin-top: @gridGutterWidth;    
+    }
+
+    &.single {
+        .entry-info {
+            margin-top: 0;
+            margin-bottom: @gridGutterWidth;
+        }    
+    }
+}
+
+.section.twitter-feed {
+    
+    .tweet {
+        line-height: 1.3em;
+        font-size: 0.9em;
+        margin-bottom: @gridGutterWidth;
+        color: @gray;
+
+        .date {
+            display: block;
+            font-size: 0.7em;
+            a {
+                text-decoration: none !important;
+                border: none;
+            }
+        }
+    }
+}
+
+.pagination .page {
+    margin-left: 0;    
+}
diff --git a/cloudcms/static/cloudcms/less/tables.less b/cloudcms/static/cloudcms/less/tables.less
new file mode 100644 (file)
index 0000000..6145c94
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Tables.less
+ * Tables for, you guessed it, tabular data
+ * ---------------------------------------- */
+
+
+// BASELINE STYLES
+// ---------------
+
+table {
+  width: 100%;
+  margin-bottom: @baseline;
+  padding: 0;
+  font-size: @basefont;
+  border-collapse: collapse;
+  th,
+  td {
+    padding: 10px 10px 9px;
+    line-height: @baseline;
+    text-align: left;
+  }
+  th {
+    padding-top: 9px;
+    font-weight: bold;
+    vertical-align: middle;
+  }
+  td {
+    vertical-align: top;
+    border-top: 1px solid #ddd;
+  }
+  // When scoped to row, fix th in tbody
+  tbody th {
+    border-top: 1px solid #ddd;
+    vertical-align: top;
+  }
+}
+
+
+// CONDENSED VERSION
+// -----------------
+.condensed-table {
+  th,
+  td {
+    padding: 5px 5px 4px;
+  }
+}
+
+
+// BORDERED VERSION
+// ----------------
+
+.bordered-table {
+  border: 1px solid #ddd;
+  border-collapse: separate; // Done so we can round those corners!
+  *border-collapse: collapse; /* IE7, collapse table to remove spacing */
+  .border-radius(4px);
+  th + th,
+  td + td,
+  th + td {
+    border-left: 1px solid #ddd;
+  }
+  thead tr:first-child th:first-child,
+  tbody tr:first-child td:first-child {
+    .border-radius(4px 0 0 0);
+  }
+  thead tr:first-child th:last-child,
+  tbody tr:first-child td:last-child {
+    .border-radius(0 4px 0 0);
+  }
+  tbody tr:last-child td:first-child {
+    .border-radius(0 0 0 4px);
+  }
+  tbody tr:last-child td:last-child {
+    .border-radius(0 0 4px 0);
+  }
+}
+
+
+// TABLE CELL SIZES
+// ----------------
+
+// This is a duplication of the main grid .columns() mixin, but subtracts 20px to account for input padding and border
+.tableColumns(@columnSpan: 1) {
+  width: ((@gridColumnWidth - 20) * @columnSpan) + ((@gridColumnWidth - 20) * (@columnSpan - 1));
+}
+table {
+  // Default columns
+  .span1     { .tableColumns(1); }
+  .span2     { .tableColumns(2); }
+  .span3     { .tableColumns(3); }
+  .span4     { .tableColumns(4); }
+  .span5     { .tableColumns(5); }
+  .span6     { .tableColumns(6); }
+  .span7     { .tableColumns(7); }
+  .span8     { .tableColumns(8); }
+  .span9     { .tableColumns(9); }
+  .span10    { .tableColumns(10); }
+  .span11    { .tableColumns(11); }
+  .span12    { .tableColumns(12); }
+  .span13    { .tableColumns(13); }
+  .span14    { .tableColumns(14); }
+  .span15    { .tableColumns(15); }
+  .span16    { .tableColumns(16); }
+}
+
+
+// ZEBRA-STRIPING
+// --------------
+
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
+.zebra-striped {
+  tbody {
+    tr:nth-child(odd) td,
+    tr:nth-child(odd) th {
+      background-color: #f9f9f9;
+    }
+    tr:hover td,
+    tr:hover th {
+      background-color: #f5f5f5;
+    }
+  }
+}
+
+table {
+  // Tablesorting styles w/ jQuery plugin
+  .header {
+    cursor: pointer;
+    &:after {
+      content: "";
+      float: right;
+      margin-top: 7px;
+      border-width: 0 4px 4px;
+      border-style: solid;
+      border-color: #000 transparent;
+      visibility: hidden;
+    }
+  }
+  // Style the sorted column headers (THs)
+  .headerSortUp,
+  .headerSortDown {
+    background-color: rgba(141,192,219,.25);
+    text-shadow: 0 1px 1px rgba(255,255,255,.75);
+  }
+  // Style the ascending (reverse alphabetical) column header
+  .header:hover {
+    &:after {
+      visibility:visible;
+    }
+  }
+  // Style the descending (alphabetical) column header
+  .headerSortDown,
+  .headerSortDown:hover {
+    &:after {
+      visibility:visible;
+      .opacity(60);
+    }
+  }
+  // Style the ascending (reverse alphabetical) column header
+  .headerSortUp {
+    &:after {
+      border-bottom: none;
+      border-left: 4px solid transparent;
+      border-right: 4px solid transparent;
+      border-top: 4px solid #000;
+      visibility:visible;
+      .box-shadow(none); //can't add boxshadow to downward facing arrow :(
+      .opacity(60);
+    }
+  }
+  // Blue Table Headings
+  .blue {
+    color: @blue;
+    border-bottom-color: @blue;
+  }
+  .headerSortUp.blue,
+  .headerSortDown.blue {
+    background-color: lighten(@blue, 40%);
+  }
+  // Green Table Headings
+  .green {
+    color: @green;
+    border-bottom-color: @green;
+  }
+  .headerSortUp.green,
+  .headerSortDown.green {
+    background-color: lighten(@green, 40%);
+  }
+  // Red Table Headings
+  .red {
+    color: @red;
+    border-bottom-color: @red;
+  }
+  .headerSortUp.red,
+  .headerSortDown.red {
+    background-color: lighten(@red, 50%);
+  }
+  // Yellow Table Headings
+  .yellow {
+    color: @yellow;
+    border-bottom-color: @yellow;
+  }
+  .headerSortUp.yellow,
+  .headerSortDown.yellow {
+    background-color: lighten(@yellow, 40%);
+  }
+  // Orange Table Headings
+  .orange {
+    color: @orange;
+    border-bottom-color: @orange;
+  }
+  .headerSortUp.orange,
+  .headerSortDown.orange {
+    background-color: lighten(@orange, 40%);
+  }
+  // Purple Table Headings
+  .purple {
+    color: @purple;
+    border-bottom-color: @purple;
+  }
+  .headerSortUp.purple,
+  .headerSortDown.purple {
+    background-color: lighten(@purple, 40%);
+  }
+}
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/less/type.less b/cloudcms/static/cloudcms/less/type.less
new file mode 100644 (file)
index 0000000..077ae9d
--- /dev/null
@@ -0,0 +1,187 @@
+/* Typography.less
+ * Headings, body text, lists, code, and more for a versatile and durable typography system
+ * ---------------------------------------------------------------------------------------- */
+
+
+// BODY TEXT
+// ---------
+
+p {
+  #font > .shorthand(normal,@basefont,@baseline);
+  margin-bottom: @baseline / 2;
+  small {
+    font-size: @basefont - 2;
+    color: @grayLight;
+  }
+}
+
+
+// HEADINGS
+// --------
+
+h1, h2, h3, h4, h5, h6 {
+  font-weight: bold;
+  color: @grayDark;
+  small {
+    color: @grayLight;
+  }
+}
+h1 {
+  margin-bottom: @baseline;
+  font-size: 30px;
+  line-height: @baseline * 2;
+  small {
+    font-size: 18px;
+  }
+}
+h2 {
+  font-size: 24px;
+  line-height: @baseline * 2;
+  small {
+    font-size: 14px;
+  }
+}
+h3, h4, h5, h6 {
+  line-height: @baseline * 2;
+}
+h3 {
+  font-size: 18px;
+  small {
+    font-size: 14px;
+  }
+}
+h4 {
+  font-size: 16px;
+  small {
+    font-size: 12px;
+  }
+}
+h5 {
+  font-size: 14px;
+}
+h6 {
+  font-size: 13px;
+  color: @grayLight;
+  text-transform: uppercase;
+}
+
+
+// COLORS
+// ------
+
+// Unordered and Ordered lists
+ul, ol {
+  margin: 0 0 @baseline 25px;
+}
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+  margin-bottom: 0;
+}
+ul {
+  list-style: disc;
+}
+ol {
+  list-style: decimal;
+}
+li {
+  line-height: @baseline;
+  color: @gray;
+}
+ul.unstyled {
+  list-style: none;
+  margin-left: 0;
+}
+
+// Description Lists
+dl {
+  margin-bottom: @baseline;
+  dt, dd {
+    line-height: @baseline;
+  }
+  dt {
+    font-weight: bold;
+  }
+  dd {
+    margin-left: @baseline / 2;
+  }
+}
+
+// MISC
+// ----
+
+// Horizontal rules
+hr {
+  margin: 20px 0 19px;
+  border: 0;
+  border-bottom: 1px solid #eee;
+}
+
+// Emphasis
+strong {
+  font-style: inherit;
+  font-weight: bold;
+}
+em {
+  font-style: italic;
+  font-weight: inherit;
+  line-height: inherit;
+}
+.muted {
+  color: @grayLight;
+}
+
+// Blockquotes
+blockquote {
+  margin-bottom: @baseline;
+  border-left: 5px solid #eee;
+  padding-left: 15px;
+  p {
+    #font > .shorthand(300,14px,@baseline);
+    margin-bottom: 0;
+  }
+  small {
+    display: block;
+    #font > .shorthand(300,12px,@baseline);
+    color: @grayLight;
+    &:before {
+      content: '\2014 \00A0';
+    }
+  }
+}
+
+// Addresses
+address {
+  display: block;
+  line-height: @baseline;
+  margin-bottom: @baseline;
+}
+
+// Inline and block code styles
+code, pre {
+  padding: 0 3px 2px;
+  font-family: Monaco, Andale Mono, Courier New, monospace;
+  font-size: 12px;
+  .border-radius(3px);
+}
+code {
+  background-color: lighten(@orange, 40%);
+  color: rgba(0,0,0,.75);
+  padding: 1px 3px;
+}
+pre {
+  background-color: #f5f5f5;
+  display: block;
+  padding: (@baseline - 1) / 2;
+  margin: 0 0 @baseline;
+  line-height: @baseline;
+  font-size: 12px;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0,0,0,.15);
+  .border-radius(3px);
+  white-space: pre;
+  white-space: pre-wrap;
+  word-wrap: break-word;
+
+}
\ No newline at end of file
diff --git a/cloudcms/static/cloudcms/less/variables.less b/cloudcms/static/cloudcms/less/variables.less
new file mode 100644 (file)
index 0000000..aa31c8a
--- /dev/null
@@ -0,0 +1,62 @@
+/* Variables.less
+ * Variables to customize the look and feel of Bootstrap
+ * ----------------------------------------------------- */
+
+// Grays
+@black:             #000;
+@grayDark:          lighten(@black, 25%);
+@gray:              lighten(@black, 50%);
+@grayLight:         lighten(@black, 75%);
+@grayLighter:       lighten(@black, 90%);
+@white:             #fff;
+
+// Accent Colors
+@blue:              #3582AC;
+@blueDark:          darken(@blue, 25%);
+@green:             #46a546;
+@red:               #9d261d;
+@yellow:            #ffc40d;
+@orange:            #f89406;
+@pink:              #c3325f;
+@purple:            #7a43b6;
+@blueLight:         #80CFD1;
+@grayExtra:         #CFCDC7;
+@altColor:          #C3C3B9;
+
+// Semantic colors
+@linkColor:         #F89A1C;
+@linkColorHover:    darken(@linkColor, 15);
+@baseColor:         @blue;                  // Set a base color
+@extraColor:        @blueLight;
+@mainColor:         @black;
+@shadowColor:       @grayExtra;
+@menuLinkColor:     @linkColor;
+@mainBorderColor:   @gray;
+@buttonColor:       @white;
+@buttonBg:          @baseColor;
+
+// Baseline grid
+@basefont:          14px;
+@baseline:          22px;
+
+// Griditude
+// Modify the grid styles in mixins.less
+@gridColumns:       12;
+@gridColumnWidth:   60px;
+@gridGutterWidth:   22px;
+@extraSpace:        (@gridGutterWidth + @gridColumnWidth); // For our grid calculations
+@siteWhiteSpace:    (@gridGutterWidth + @gridColumnWidth);
+@siteWidth:         (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)) - 2 - 2*(@siteWhiteSpace);
+
+// Color Scheme
+// Use this to roll your own color schemes if you like (unused by Bootstrap by default)
+@complement:        spin(@baseColor, 180);  // Determine a complementary color
+@split1:            spin(@baseColor, 158);  // Split complements
+@split2:            spin(@baseColor, -158);
+@triad1:            spin(@baseColor, 135);  // Triads colors
+@triad2:            spin(@baseColor, -135);
+@tetra1:            spin(@baseColor, 90);   // Tetra colors
+@tetra2:            spin(@baseColor, -90);
+@analog1:           spin(@baseColor, 22);   // Analogs colors
+@analog2:           spin(@baseColor, -22);
+
diff --git a/cloudcms/static/cloudcms/less/xtra.less b/cloudcms/static/cloudcms/less/xtra.less
new file mode 100644 (file)
index 0000000..362ca38
--- /dev/null
@@ -0,0 +1,34 @@
+// row helper
+.makeRow { .clearfix(); margin-left: -@gridGutterWidth; }
+
+
+#font {
+  .main(@weight: normal, @size: 14px, @lineHeight: 22px) {
+    font-family: 'Antic', sans-serif;
+    font-size: @size;
+    font-weight: @weight;
+    line-height: @lineHeight;
+    letter-spacing: 1px;
+  }
+}
+
+
+.button {
+    #font.main();
+    background-color: @buttonBg;
+    color: @buttonColor;
+    border: none;
+    padding: 0.8em @gridGutterWidth;
+    font-size: 1em;
+
+    &:hover {
+        background-color: @linkColor;    
+    }
+}
+
+
+.transit(@type:color, @time:.15s, @easing:linear) {
+    -webkit-transition: @type @time @easing;
+    transition: @type @time @easing;
+}
+
diff --git a/cloudcms/templates/cms/base.html b/cloudcms/templates/cms/base.html
new file mode 100644 (file)
index 0000000..b77628f
--- /dev/null
@@ -0,0 +1,122 @@
+<!doctype html>
+{% load feincms_tags feincms_page_tags %}
+<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
+<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
+<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
+<!--[if (gte IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
+<head>
+  {% block starthead %}{% endblock starthead %}
+  <meta charset="{{ resource.meta.charset }}">
+  
+  <meta http-equiv="X-UA-Compatible" content="{{ resource.meta.compatibility }}">
+  
+  <title>
+      {% block page.title %}{% if feincms_page.page_title %}{{ feincms_page.page_title }}
+      {% else %}{{ feincms_page.title }} | {% endif %}{{ APP.title }}{% endblock %}
+  </title>
+  
+  <meta name="description" content="{{ resource.meta.description }}">
+  <meta name="author" content="{{ resource.meta.author }}">
+  <meta name="viewport" content="">
+    
+  {% block page.js %}
+  <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
+  <!--[if lt IE 9]>
+    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+  <![endif]-->
+  {% endblock %}
+  
+  {% block favicons %}
+  <link rel="shortcut icon" href="">
+  <link rel="apple-touch-icon" href="">
+  {% endblock favicons %}
+
+  {% block css %}
+      <link href='http://fonts.googleapis.com/css?family=Antic' rel='stylesheet' type='text/css'>
+      <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}cloudcms/css/styles.css">
+  {% endblock css %}
+
+  {% block headjs %}
+      <script src="{{ MEDIA_URL }}cloudcms/js/modernizr-2.0.6.js"></script>
+      <script src="{{ MEDIA_URL }}cloudcms/js/jquery-1.7.1.min.js"></script>
+      <script src="{{ MEDIA_URL }}cloudcms/js/jquery.infieldlabel.js"></script>
+      <script src="{{ MEDIA_URL }}cloudcms/js/jquery.cookie.js"></script>
+      <script src="{{ MEDIA_URL }}cloudcms/js/form-errors.js"></script>
+
+      <script src="{{ MEDIA_URL }}cloudcms/js/colorbox/jquery.colorbox.js"></script>
+  {% endblock headjs %}
+
+  {% block page.cms.media %}
+  {{ feincms_page.content.media }}
+  {% endblock %}
+
+
+  {% block page.scripts.cloudbar %}
+  {% if CLOUDBAR_BASE_URL %}
+  <script>
+        var CLOUDBAR_ACTIVE_SERVICE = '{{ CLOUDBAR_ACTIVE_SERVICE }}';
+        var CLOUDBAR_LOCATION = "{{ CLOUDBAR_BASE_URL }}";
+
+        $(document).ready(function(){
+            $.getScript(CLOUDBAR_LOCATION + 'cloudbar.js');
+        });
+  </script>
+  {% endif %}
+  {% endblock %}
+
+   <script type="text/javascript">
+      $(document).ready(function() {
+          $("form.innerlabels label").inFieldLabels();
+          $("form input").attr('autocomplete', 'off');
+          $("form .form-row").formErrors();
+      })
+   </script>
+  {% block endhead %}{% endblock endhead %}
+
+</head>
+
+<body class='cms-page-{{ feincms_page.slug }}'>
+    <div class='container'>
+        <div class='header'>
+            <div class="mainlogo">
+                    {% if APP.logo %}
+                        <a href="/" title="{{ APP.title }}">
+                            <img src="{{ APP.logo.get_absolute_url }}" alt="{{ APP.title }}" />
+                        </a>
+                    {% else %}
+                        <h1>{{ APP.title }}</h1>
+                    {% endif %}
+                </div>
+            <div class="navigation">
+                <ul class="mainnav inline">
+                    {% block page.nav %}
+                        {% feincms_navigation of feincms_page as sublevel level=2,depth=1 %}
+                        {% for p in sublevel %}
+                        <li class="{% if p|is_equal_or_parent_of:feincms_page %}active{% endif %}">
+                        <a href="{{ p.get_absolute_url }}">{{ p.title }}</a></li>
+                        {% endfor %}
+                    {% endblock %}
+                </ul>
+                <ul class="mainnav inline subnav">
+                    {% block page.subnav %}
+                        {% if feincms_page.override_url != "/" %}
+                        {% feincms_navigation of feincms_page as sublevel level=3,depth=1 %}
+                        {% for p in sublevel %}
+                        <li class="{% if p|is_equal_or_parent_of:feincms_page or p.url == request.path %}active{% endif %}">
+                        <a href="{{ p.get_absolute_url }}">{{ p.title }}</a></li>
+                        {% endfor %}
+                        {% endif %}
+                    {% endblock %}
+                </ul>
+            </div>
+        </div>
+        <div class="page">
+                {% block page.body %}
+                {% endblock %}
+        </div>
+    </div>
+    <div class="footer">
+        footer
+    </div>
+</body>
+</html>
diff --git a/cloudcms/templates/cms/pages/about.html b/cloudcms/templates/cms/pages/about.html
new file mode 100644 (file)
index 0000000..a8c7c2b
--- /dev/null
@@ -0,0 +1 @@
+{% extends "cms/pages/onecol.html" %}
diff --git a/cloudcms/templates/cms/pages/blog.html b/cloudcms/templates/cms/pages/blog.html
new file mode 100644 (file)
index 0000000..cdc9e11
--- /dev/null
@@ -0,0 +1,20 @@
+{% extends "cms/pages/twocolwide.html" %}
+{% load applicationcontent_tags feincms_page_tags %}
+
+
+{% block page.maincol %}
+    {% if request|has_fragment:"maincol" %}
+        {% get_fragment request "maincol" %}
+    {% else %}
+        {{ block.super }}
+    {% endif %}
+{% endblock %}
+
+{% block page.sidecol %}
+    {% if request|has_fragment:"sidecol" %}
+        {% get_fragment request "sidecol" %}
+    {% else %}
+        {{ block.super }}
+    {% endif %}
+{% endblock %}
+
diff --git a/cloudcms/templates/cms/pages/intro.html b/cloudcms/templates/cms/pages/intro.html
new file mode 100644 (file)
index 0000000..17803c6
--- /dev/null
@@ -0,0 +1,19 @@
+{% extends "cms/base.html" %}
+
+{% block page.body %}
+<section class="maincol {% block page.maincolclasses %}{% endblock %}">
+    {% block page.maincol %}
+        {% for content in feincms_page.content.main %}
+        {{ content.render }}
+        {% endfor %}
+        {% endblock %}
+</section>
+<section class="rightcol {% block page.sidecolclasses %}{% endblock %}">
+{% block page.sidecol %}
+        {% for content in feincms_page.content.sidebar %}
+            {{ content.render }}
+        {% endfor %}
+    {% endblock %}
+</section>
+{% endblock %}
+
diff --git a/cloudcms/templates/cms/pages/onecol.html b/cloudcms/templates/cms/pages/onecol.html
new file mode 100644 (file)
index 0000000..b1a7029
--- /dev/null
@@ -0,0 +1,10 @@
+{% extends "cms/base.html" %}
+
+{% block page.body %}
+<div class="maincol full">
+    {% for content in feincms_page.content.main %}
+        {{ content.render }}
+    {% endfor %}
+</div>
+{% endblock %}
+
diff --git a/cloudcms/templates/cms/pages/page.html b/cloudcms/templates/cms/pages/page.html
new file mode 100644 (file)
index 0000000..c2bd1b8
--- /dev/null
@@ -0,0 +1,2 @@
+{% extends "cms/pages/intro.html" %}
+
diff --git a/cloudcms/templates/cms/pages/twocolwide.html b/cloudcms/templates/cms/pages/twocolwide.html
new file mode 100644 (file)
index 0000000..e4cd76a
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "cms/pages/page.html" %}
+
+{% block page.maincolclasses %} wide {% endblock %}
+{% block page.sidecolclasses %} narrow {% endblock %}
+
diff --git a/cloudcms/templates/content/about_block.html b/cloudcms/templates/content/about_block.html
new file mode 100644 (file)
index 0000000..0a730e4
--- /dev/null
@@ -0,0 +1,40 @@
+<div class="
+    section positioned 
+    {% if content.image_position == "left" or content.image_position == "right" %}withimg{% endif %}" 
+    style="{% spaceless %}
+    {% if content.position_left %}left:{{ content.position_left }}px;{% endif %} 
+    {% if content.position_top %}top:{{ content.position_top }}px;{% endif %}
+    {% if content.size_width %}width:{{ content.size_width }}px;{% endif %}
+    {% if content.size_height %}height:{{ content.size_height }}px;{% endif %}
+    {% if content.color %}color:{{ content.color }};{% endif %}
+    {% if content.offset_left %}padding-left:{{ content.offset_left }}px;float:left;{% endif %}
+    {% if content.offset_top %}padding-top:{{ content.offset_top }}px;float:left;{% endif %}
+    {% endspaceless %}">
+
+    <div class="section-inner">
+    {% if content.image_position == "left" %}
+    <div class="img">
+        <img src="{{ content.image.get_absolute_url }}" alt="{{ content.title }}" />
+    </div>
+    {% endif %}
+    <div class="content">
+        {% if content.image_position == "top" %}
+        <div class="img">
+            <img src="{{ content.image.get_absolute_url }}" alt="{{ content.title }}" />
+        </div>
+        {% endif %}
+        <h3>{{ content.title }}</h3>
+        <div class="text">{{ content.content }}</div>
+        {% if content.image_position == "bottom" %}
+        <div class="img">
+            <img src="{{ content.image.get_absolute_url }}" alt="{{ content.title }}" />
+        </div>
+        {% endif %}
+    </div>
+    {% if content.image_position == "right" %}
+    <div class="img">
+        <img src="{{ content.image.get_absolute_url }}" alt="{{ content.title }}" />
+    </div>
+    {% endif %}
+    </div>
+</div>
diff --git a/cloudcms/templates/content/login_form.html b/cloudcms/templates/content/login_form.html
new file mode 100644 (file)
index 0000000..2d01bcc
--- /dev/null
@@ -0,0 +1,27 @@
+<div class="section login-section">
+<form class="login {{ content.extra_classes }} innerlabels" method="post"
+    action="{{ content.action_url }}login">
+    <h2 class="formheader"><span>{{ content.title }}</span></h2>
+    <div class="form-row">
+        <label for="username">username</label>
+        <input class="text" type="text" title="username" name="username"
+        id="username"/>
+    </div>
+    <div class="form-row">
+        <label for="password">password</label>
+        <input class="text" type="password" title="password" name="password"
+        id="password"/>
+    </div>
+    <div class="form-row submit">
+        <input type="submit" class="submit" value="SUBMIT" />
+        {% if content.display_forgot_password %}
+        <a class="extra-link" href="{{ content.action_url }}local/password_reset">
+            forgot your password ?
+        </a>
+        {% endif %}
+    </div>
+</form>
+</div>
+<div class="section">
+    <a href="{{ content.action_url }}"></a>
+</div>
diff --git a/cloudcms/templates/content/section/block.html b/cloudcms/templates/content/section/block.html
new file mode 100644 (file)
index 0000000..5297505
--- /dev/null
@@ -0,0 +1,11 @@
+<section class="section">
+{% if content.title %}
+<h2>{{ content.title }}</h2>
+{% endif %}
+{% if content.mediafile.type == "image" %}
+    <img src="{{ content.mediafile.get_absolute_url }}" />
+{% endif %}
+<p>
+{{ content.richtext|safe }}
+</p>
+</section>
diff --git a/cloudcms/templates/content/twitter_feed.html b/cloudcms/templates/content/twitter_feed.html
new file mode 100644 (file)
index 0000000..b9ac7bc
--- /dev/null
@@ -0,0 +1,34 @@
+<div class="section twitter-feed">
+    {% if content.title %}
+        <h2>{{ content.title|safe }}</h2>
+    {% endif %}
+    <div id="twitter_feeds_section_{{ content.pk }}">
+    </div>
+</div>
+
+<script id="feeds-template-{{ content.pk }}" type="text/x-jquery-tmpl">
+    <li><b>${Name}</b> (${ReleaseYear})</li>
+</script>
+<script>
+    $(document).ready(function(){
+        var el = $("#twitter_feeds_section_{{ content.pk }}");
+        $.twitter({{ content.js_conf|safe}}, function(tweets){
+            $.each(tweets.results, function(i,t){
+                console.log(t);
+                var tweet = $('<div class="tweet">');
+                var date = $('<span class="date">');
+                var text = $('<span class="text">');
+                
+                text.html(linkify(t.text));
+                date.html('<a href="http://twitter.com/#!/' + t.from_user + 
+                '">' + $.timeago(new Date(t.created_at)) + 
+                '</a>');
+
+                tweet.append(date);
+                tweet.append(text);
+                el.append(tweet);
+            })
+        })
+
+    })
+</script>
diff --git a/cloudcms/templates/content/videosection.html b/cloudcms/templates/content/videosection.html
new file mode 100644 (file)
index 0000000..9ddb2f7
--- /dev/null
@@ -0,0 +1,24 @@
+<div class="section videosection-{{ content.pk }}">
+    <h2>{{ content.section_title }}</h2>
+    <div class="content">
+        <a class="simple videolink"
+            href="{{ content.video_link }}">
+            <img class="mainimg" src="{{ content.image.get_absolute_url }}" />
+        </a>
+    </div>
+    <script>
+        $(document).ready(function(){
+            $(".videosection-{{ content.pk }}").find(".mainimg").hover(function(){
+                $(this).attr("src",
+                "{{ content.image_hover.get_absolute_url }}");
+            }, function(){
+                $(this).attr("src",
+                "{{ content.image.get_absolute_url }}");
+            })
+
+            $(".videosection-{{ content.pk }} a.videolink").colorbox({iframe:true,
+                innerWidth:{{ content.video_width }},
+                innerHeight: {{ content.video_height }}})
+        })
+    </script>
+</div>
diff --git a/cloudcms/templates/form_render.html b/cloudcms/templates/form_render.html
new file mode 100644 (file)
index 0000000..c77024e
--- /dev/null
@@ -0,0 +1,16 @@
+<div class="form-errors all">
+{% for key, err in form.errors.items %}
+{% if key == "__all__" %}
+<div class="form-error">{{ err }}</div>
+{% endif %}
+{% endfor %}
+</div>
+{% for field in form %}
+<div class="form-row {% if field.errors|length %}with-errors{% endif %}">
+        {{ field.errors }}
+     <p class="{% if field.blank %}required{% endif %}">
+        {{ field.label_tag }}
+        {{ field }}
+        </p>
+    </div>
+{% endfor %}
diff --git a/cloudcms/tests.py b/cloudcms/tests.py
new file mode 100644 (file)
index 0000000..501deb7
--- /dev/null
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)
diff --git a/cloudcms/urls.py b/cloudcms/urls.py
new file mode 100644 (file)
index 0000000..60570be
--- /dev/null
@@ -0,0 +1,17 @@
+from django.conf.urls.defaults import patterns, include, url
+from django.conf import settings
+from django.contrib import admin
+
+from feincms.module.page.sitemap import PageSitemap
+#from cloudcmsblog.sitemap import BlogSitemap
+
+admin.autodiscover()
+
+sitemaps = {'pages': PageSitemap }
+
+urlpatterns = patterns('',
+    url(r'^cmsmanage/', include(admin.site.urls)),
+    url(r'', include('feincms.urls')),
+    url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps }),
+)
+
diff --git a/cloudcms/views.py b/cloudcms/views.py
new file mode 100644 (file)
index 0000000..60f00ef
--- /dev/null
@@ -0,0 +1 @@
+# Create your views here.
diff --git a/cloudcmsblog/__init__.py b/cloudcmsblog/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcmsblog/admin.py b/cloudcmsblog/admin.py
new file mode 100644 (file)
index 0000000..9581956
--- /dev/null
@@ -0,0 +1,54 @@
+from django.contrib import admin
+from django.utils.translation import ugettext_lazy as _
+from cloudcmsblog.models import Entry, Category, CategoryTranslation
+from feincms.translations import admin_translationinline, short_language_code
+from feincms.admin import item_editor
+
+CategoryTranslationInline = admin_translationinline(CategoryTranslation,
+        prepopulated_fields={'slug': ('title',)})
+
+
+class EntryAdmin(item_editor.ItemEditor):
+    date_hierarchy = 'published_on'
+    filter_horizontal = ['categories']
+    list_display = ['title', 'is_active', 'published_on', 'author']
+    list_editable = ['is_active',]
+    list_filter = ['is_active', 'is_featured', 'categories', 'author']
+    raw_id_fields = ['image']
+    search_fields = ['title', 'slug']
+    prepopulated_fields = {
+        'slug': ('title',),
+        }
+
+    fieldsets = [
+        [None, {
+            'fields': [
+                ('is_active', 'is_featured', 'published_on'),
+                ('title', 'slug'),
+                'image',
+                'author',
+                'application',
+                'categories',
+                'intro_text',
+            ]
+        }],
+        item_editor.FEINCMS_CONTENT_FIELDSET,
+    ]
+
+
+class CategoryAdmin(admin.ModelAdmin):
+    inlines = [CategoryTranslationInline]
+    list_display = ['__unicode__', 'entries']
+    search_fields = ['translations__title']
+
+    def entries(self, obj):
+        if 'translations' in getattr(Entry, '_feincms_extensions', ()):
+            return Entry.objects.filter(categories=obj, language=short_language_code()).count()
+        return Entry.objects.filter(categories=obj)
+
+    entries.short_description = _('Blog entries in category')
+
+
+admin.site.register(Entry, EntryAdmin)
+admin.site.register(Category, CategoryAdmin)
+
diff --git a/cloudcmsblog/models.py b/cloudcmsblog/models.py
new file mode 100644 (file)
index 0000000..684f9d5
--- /dev/null
@@ -0,0 +1,141 @@
+from datetime import datetime
+
+from django.db import models
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy as _, ugettext, ungettext
+
+from feincms import translations
+from feincms.models import Base
+from feincms.content.richtext.models import RichTextContent
+from feincms.content.section.models import SectionContent
+from feincms.module.medialibrary.fields import MediaFileForeignKey
+from feincms.module.medialibrary.models import MediaFile
+from feincms.module.page.extensions.navigation import NavigationExtension
+from feincms.module.page.extensions.navigation import PagePretender
+
+from cloudcms.models import Application
+
+
+class Category(models.Model, translations.TranslatedObjectMixin):
+    """
+    Blog entry category. Each blog post may belong to multiple categories.
+    """
+
+    ordering = models.SmallIntegerField(_('ordering'), default=0)
+    display_on_menu = models.BooleanField(default=False)
+
+    class Meta:
+        verbose_name = _('category')
+        verbose_name_plural = _('categories')
+        ordering = ['-ordering',]
+
+    objects = translations.TranslatedObjectManager()
+
+    def __unicode__(self):
+        trans = translations.TranslatedObjectMixin.__unicode__(self)
+        return trans or _('Unnamed category')
+
+
+class CategoryTranslation(translations.Translation(Category)):
+    """
+    Category translation
+    """
+    title = models.CharField(_('category title'), max_length=100)
+    slug = models.SlugField(_('slug'), unique=True)
+    description = models.CharField(_('description'), max_length=250, blank=True)
+
+    class Meta:
+        verbose_name = _('category translation')
+        verbose_name_plural = _('category translations')
+        ordering = ['title']
+
+    def __unicode__(self):
+        return self.title
+
+    @models.permalink
+    def get_absolute_url(self):
+        return ('cloudcmsblog_entries_archive', (), {
+            'category': self.slug,
+            })
+
+    def save(self, *args, **kwargs):
+        if not self.slug:
+            self.slug = slugify(self.title)
+
+        super(CategoryTranslation, self).save(*args, **kwargs)
+
+
+class EntryManager(models.Manager):
+
+    def active(self):
+        return self.filter(is_active=True)
+
+class Entry(Base):
+    """
+    Blog post entry
+    """
+    is_active = models.BooleanField(_('is active'), default=True)
+    is_featured = models.BooleanField(_('is featured'), default=False)
+
+    title = models.CharField(_('title'), max_length=100)
+    slug = models.SlugField(_('slug'), max_length=100, unique_for_date='published_on')
+    author = models.ForeignKey(User, related_name='blogentries', verbose_name=_('author'))
+    language = models.CharField(max_length=255, choices=settings.LANGUAGES)
+
+    intro_text = models.TextField(max_length=255,
+            help_text="Displayed in list views", blank=True)
+    image = MediaFileForeignKey(MediaFile, null=True, blank=True)
+    application = models.ManyToManyField(Application,
+            related_name="blogentries",
+            verbose_name=_('application'))
+
+    published_on = models.DateTimeField(_('published on'), blank=True, null=True, default=datetime.now,
+        help_text=_('Will be filled in automatically when entry gets published.'))
+    last_changed = models.DateTimeField(_('last change'), auto_now=True, editable=False)
+
+    categories = models.ManyToManyField(Category, verbose_name=_('categories'),
+        related_name='blogentries', null=True, blank=True)
+
+    objects = EntryManager()
+
+    class Meta:
+        get_latest_by = 'published_on'
+        ordering = ['-published_on']
+        verbose_name = _('entry')
+        verbose_name_plural = _('entries')
+
+    def __unicode__(self):
+        return self.title
+
+    @models.permalink
+    def get_absolute_url(self):
+        return ('cloudcmsblog_entry_detail', (), {
+            'year': self.published_on.strftime('%Y'),
+            'month': self.published_on.strftime('%m'),
+            'day': self.published_on.strftime('%d'),
+            'slug': self.slug,
+            })
+
+
+# Feincms navigation extension
+class BlogCategoriesNavigationExtension(NavigationExtension):
+    """
+    Navigation extension for FeinCMS which lists all categories that user
+    wants to include in global site navigation.
+    """
+
+    name = _('blog categories')
+
+    def children(self, page, **kwargs):
+        for category in Category.objects.filter(display_on_menu=True):
+            url='%scategory/%s/' % (page.get_absolute_url(), category.translation.slug)
+            yield PagePretender(
+                title=category.translation.title,
+                tree_id=page.tree_id,
+                url=url,
+                lft=0,
+                rght=0,
+                slug=category.translation.slug,
+            )
+
diff --git a/cloudcmsblog/navigation_extensions.py b/cloudcmsblog/navigation_extensions.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cloudcmsblog/sitemap.py b/cloudcmsblog/sitemap.py
new file mode 100644 (file)
index 0000000..a5c8f28
--- /dev/null
@@ -0,0 +1,5 @@
+from django.db.models import Max
+from django.contrib.sitemaps import Sitemap
+from cloudcmsblog.models import Entry
+
+
diff --git a/cloudcmsblog/templates/cloudcmsblog/archive.html b/cloudcmsblog/templates/cloudcmsblog/archive.html
new file mode 100644 (file)
index 0000000..9a5d064
--- /dev/null
@@ -0,0 +1,38 @@
+{% load applicationcontent_tags pagination_tags i18n %}
+
+{% autopaginate entries ENTRIES_PER_PAGE %}
+{% fragment request "maincol" %}
+<div class="blog-entries">
+    {% for entry in entries %}
+    <div class="blog-entry">
+        <h3 class="title">
+            <a href="{{ entry.get_absolute_url }}">{{ entry.title|upper }}</a>
+        </h3>
+        {% if entry.image %}
+        <div class="media">
+        <img src="{{ entry.image.get_absolute_url }}" alt="{{ entry.title }}" />
+        </div>
+        {% endif %}
+        {% if entry.intro_text %}
+        <div class="intro-content">
+            {{ entry.intro_text|safe }}
+        </div>
+        {% endif %}
+        <div class="entry-info">
+            {% trans "posted by" %} 
+            <span class="author">{{ entry.author }}</span>
+            {% trans "on" %} <span class="date">{{ entry.published_on }}</span>,
+            {% trans "filed under" %}
+            {% for c in entry.categories.all %}
+            <a href="{{ c.get_absolute_url }}" title="{{ c|lower }} {% trans "posts" %}">
+                {{ c|lower }}
+            </a> {% if not forloop.last %},{% endif %}
+            {% endfor %}
+        </div>
+    </div>
+    {% endfor %}
+</div>
+<div class="pages">
+    {% paginate %}
+</div>
+{% endfragment %}
diff --git a/cloudcmsblog/templates/cloudcmsblog/detail.html b/cloudcmsblog/templates/cloudcmsblog/detail.html
new file mode 100644 (file)
index 0000000..b29c975
--- /dev/null
@@ -0,0 +1,36 @@
+{% load applicationcontent_tags i18n %}
+
+{% fragment request "maincol" %}
+<div class="blog-entry single">
+    <h2 class="title">{{ entry.title|upper }}</h2>
+    <div class="entry-info">
+        {% trans "posted by" %} 
+        <span class="author">{{ entry.author }}</span>
+        {% trans "on" %} <span class="date">{{ entry.published_on }}</span>,
+        {% trans "filed under" %}
+        {% for c in entry.categories.all %}
+        <a href="{{ c.get_absolute_url }}" title="{{ c|lower }} {% trans "posts" %}">
+            {{ c|lower }}
+        </a> {% if not forloop.last %},{% endif %}
+        {% endfor %}
+    </div>
+    {% if entry.image %}
+    <div class="media">
+    <img src="{{ entry.image.get_absolute_url }}" alt="{{ entry.title }}" />
+    </div>
+    {% endif %}
+    <div class="content"> 
+        {% for content in entry.content.main %}
+        {{ content.render }}
+        {% endfor %}
+    </div>
+</div>
+{% endfragment %}
+
+{% if entry.content.sidebar|length > 0 %}
+    {% fragment request "sidecol" %}
+    {% for content in entry.content.sidebar %}
+    {{ content.render }}
+    {% endfor %}
+    {% endfragment %}
+{% endif %}
diff --git a/cloudcmsblog/tests.py b/cloudcmsblog/tests.py
new file mode 100644 (file)
index 0000000..2247054
--- /dev/null
@@ -0,0 +1,23 @@
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
diff --git a/cloudcmsblog/urls.py b/cloudcmsblog/urls.py
new file mode 100644 (file)
index 0000000..9ec62ec
--- /dev/null
@@ -0,0 +1,13 @@
+from django.conf.urls.defaults import patterns, include, url
+from django.conf import settings
+from django.contrib import admin
+
+admin.autodiscover()
+
+urlpatterns = patterns('cloudcmsblog.views',
+    url(r'^$', 'index', name='cloudcmsblog_entries_archive'),
+    url(r'^category/(?P<category>\w+)/$', 'archive', name='cloudcmsblog_entries_archive'),
+    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$',
+        'detail', name='cloudcmsblog_entry_detail'),
+)
+
diff --git a/cloudcmsblog/views.py b/cloudcmsblog/views.py
new file mode 100644 (file)
index 0000000..fc270b3
--- /dev/null
@@ -0,0 +1,38 @@
+from django.conf import settings
+from django.views.generic.simple import direct_to_template
+from django.http import HttpResponseRedirect, Http404
+
+from cloudcms.models import Application
+from cloudcmsblog.models import Entry, Category, CategoryTranslation
+
+def index(request):
+    """
+    Redirecto to first category found entries archive
+    """
+    categories = Category.objects.filter(display_on_menu=True)
+    if categories.exists() == 0:
+        raise Http404
+
+    return HttpResponseRedirect(categories[0].get_absolute_url())
+
+def archive(request, category):
+    """
+    Display entries list
+    """
+    app = Application.current()
+    category = CategoryTranslation.objects.get(slug=category).parent
+    entries = category.blogentries.all()
+    return direct_to_template(request,
+            "cloudcmsblog/archive.html", {'entries': entries,
+                'ENTRIES_PER_PAGE': getattr(settings,
+                    'CLOUDCMSBLOG_ENTRIES_PER_PAGE', 2)})
+
+def detail(request, year, month, day, slug):
+    """
+    Display detailed blog entry.
+    """
+    entry = Entry.objects.get(published_on__year=year,
+            published_on__month=month, published_on__day=day,
+            slug=slug, is_active=True)
+    return direct_to_template(request,
+            "cloudcmsblog/detail.html", {'entry': entry})
diff --git a/fabfile.py b/fabfile.py
new file mode 100644 (file)
index 0000000..1b030b9
--- /dev/null
@@ -0,0 +1,17 @@
+from fabric.api import local
+
+def makestyles():
+    """
+    Build less styles. Requires `lessc <http://lesscss.org>`_ tool.
+    """
+    lessfile = "cloudcms/static/cloudcms/less/styles"
+    cssfile = "cloudcms/static/cloudcms/css/styles"
+    local("lessc %s.less > %s.css" % (lessfile, cssfile))
+
+def watchstyles():
+    """
+    Watch static directory for changes and trigger styles build on each event.
+    Requires the dnotify tool (apt-get install dnotify).
+    """
+    local("dnotify -M cloudcms/static/cloudcms/less/ -e "
+          "fab makestyles", capture=False)
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..6faf69e
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,20 @@
+from setuptools import setup, find_packages
+
+setup(
+    name = "snf-cloudcms",
+    version = "0.1",
+    packages = find_packages(),
+
+    entry_points = {
+     'synnefo': [
+         'default_settings = cloudcms.common_settings',
+         'web_apps = cloudcms.common_settings:CLOUDCMS_APPS',
+         'web_middleware = cloudcms.common_settings:CLOUDCMS_MIDDLEWARES',
+         'web_context_processors = cloudcms.common_settings:CLOUDCMS_CONTEXT_PROCESSORS',
+         'urls = cloudcms.urls:urlpatterns',
+         'web_static = cloudcms.common_settings:CLOUDCMS_STATICFILES'
+         ]
+    },
+
+)
+