Merge branch 'rh' into dev
authordavin baragiotta <davin.baragiotta@u-db.(none)>
Tue, 5 Apr 2011 13:21:33 +0000 (09:21 -0400)
committerDavin BARAGIOTTA <davin.baragiotta@auf.org>
Tue, 5 Apr 2011 13:21:33 +0000 (09:21 -0400)
116 files changed:
buildout.cfg
project/dae/forms.py
project/dae/migrations/0003_auto__del_postecomparatifexterne.py [new file with mode: 0644]
project/dae/models.py
project/dae/templates/dae/financement-full.html [new file with mode: 0644]
project/dae/templates/dae/financement.html [new file with mode: 0644]
project/dae/templates/dae/index.html
project/dae/templates/dae/poste.html
project/dae/urls.py
project/dae/views.py
project/dashboard.py [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png [new file with mode: 0644]
project/media/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_217bc0_256x240.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_2e83ff_256x240.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_469bdd_256x240.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_6da8d5_256x240.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_cd0a0a_256x240.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_d8e7f3_256x240.png [new file with mode: 0644]
project/media/css/redmond/images/ui-icons_f9bd01_256x240.png [new file with mode: 0644]
project/media/css/redmond/jquery-ui-1.8.11.custom.css [new file with mode: 0644]
project/media/django/css/base.css [new file with mode: 0644]
project/media/django/css/changelists.css [new file with mode: 0644]
project/media/django/css/dashboard.css [new file with mode: 0644]
project/media/django/css/forms.css [new file with mode: 0644]
project/media/django/css/ie.css [new file with mode: 0644]
project/media/django/css/login.css [new file with mode: 0644]
project/media/django/css/rtl.css [new file with mode: 0644]
project/media/django/css/widgets.css [new file with mode: 0644]
project/media/django/img/admin/arrow-down.gif [new file with mode: 0644]
project/media/django/img/admin/arrow-up.gif [new file with mode: 0644]
project/media/django/img/admin/changelist-bg.gif [new file with mode: 0644]
project/media/django/img/admin/changelist-bg_rtl.gif [new file with mode: 0644]
project/media/django/img/admin/chooser-bg.gif [new file with mode: 0644]
project/media/django/img/admin/chooser_stacked-bg.gif [new file with mode: 0644]
project/media/django/img/admin/default-bg-reverse.gif [new file with mode: 0644]
project/media/django/img/admin/default-bg.gif [new file with mode: 0644]
project/media/django/img/admin/deleted-overlay.gif [new file with mode: 0644]
project/media/django/img/admin/icon-no.gif [new file with mode: 0644]
project/media/django/img/admin/icon-unknown.gif [new file with mode: 0644]
project/media/django/img/admin/icon-yes.gif [new file with mode: 0644]
project/media/django/img/admin/icon_addlink.gif [new file with mode: 0644]
project/media/django/img/admin/icon_alert.gif [new file with mode: 0644]
project/media/django/img/admin/icon_calendar.gif [new file with mode: 0644]
project/media/django/img/admin/icon_changelink.gif [new file with mode: 0644]
project/media/django/img/admin/icon_clock.gif [new file with mode: 0644]
project/media/django/img/admin/icon_deletelink.gif [new file with mode: 0644]
project/media/django/img/admin/icon_error.gif [new file with mode: 0644]
project/media/django/img/admin/icon_searchbox.png [new file with mode: 0644]
project/media/django/img/admin/icon_success.gif [new file with mode: 0644]
project/media/django/img/admin/inline-delete-8bit.png [new file with mode: 0644]
project/media/django/img/admin/inline-delete.png [new file with mode: 0644]
project/media/django/img/admin/inline-restore-8bit.png [new file with mode: 0644]
project/media/django/img/admin/inline-restore.png [new file with mode: 0644]
project/media/django/img/admin/inline-splitter-bg.gif [new file with mode: 0644]
project/media/django/img/admin/nav-bg-grabber.gif [new file with mode: 0644]
project/media/django/img/admin/nav-bg-reverse.gif [new file with mode: 0644]
project/media/django/img/admin/nav-bg.gif [new file with mode: 0644]
project/media/django/img/admin/selector-add.gif [new file with mode: 0644]
project/media/django/img/admin/selector-addall.gif [new file with mode: 0644]
project/media/django/img/admin/selector-remove.gif [new file with mode: 0644]
project/media/django/img/admin/selector-removeall.gif [new file with mode: 0644]
project/media/django/img/admin/selector-search.gif [new file with mode: 0644]
project/media/django/img/admin/selector_stacked-add.gif [new file with mode: 0644]
project/media/django/img/admin/selector_stacked-remove.gif [new file with mode: 0644]
project/media/django/img/admin/tool-left.gif [new file with mode: 0644]
project/media/django/img/admin/tool-left_over.gif [new file with mode: 0644]
project/media/django/img/admin/tool-right.gif [new file with mode: 0644]
project/media/django/img/admin/tool-right_over.gif [new file with mode: 0644]
project/media/django/img/admin/tooltag-add.gif [new file with mode: 0644]
project/media/django/img/admin/tooltag-add_over.gif [new file with mode: 0644]
project/media/django/img/admin/tooltag-arrowright.gif [new file with mode: 0644]
project/media/django/img/admin/tooltag-arrowright_over.gif [new file with mode: 0644]
project/media/django/img/gis/move_vertex_off.png [new file with mode: 0644]
project/media/django/img/gis/move_vertex_on.png [new file with mode: 0644]
project/media/django/js/LICENSE-JQUERY.txt [new file with mode: 0644]
project/media/django/js/SelectBox.js [new file with mode: 0644]
project/media/django/js/SelectFilter2.js [new file with mode: 0644]
project/media/django/js/actions.js [new file with mode: 0644]
project/media/django/js/actions.min.js [new file with mode: 0644]
project/media/django/js/admin/DateTimeShortcuts.js [new file with mode: 0644]
project/media/django/js/admin/RelatedObjectLookups.js [new file with mode: 0644]
project/media/django/js/admin/ordering.js [new file with mode: 0644]
project/media/django/js/calendar.js [new file with mode: 0644]
project/media/django/js/collapse.js [new file with mode: 0644]
project/media/django/js/collapse.min.js [new file with mode: 0644]
project/media/django/js/compress.py [new file with mode: 0755]
project/media/django/js/core.js [new file with mode: 0644]
project/media/django/js/dateparse.js [new file with mode: 0644]
project/media/django/js/getElementsBySelector.js [new file with mode: 0644]
project/media/django/js/inlines.js [new file with mode: 0644]
project/media/django/js/inlines.min.js [new file with mode: 0644]
project/media/django/js/jquery.init.js [new file with mode: 0644]
project/media/django/js/jquery.js [new file with mode: 0644]
project/media/django/js/jquery.min.js [new file with mode: 0644]
project/media/django/js/prepopulate.js [new file with mode: 0644]
project/media/django/js/prepopulate.min.js [new file with mode: 0644]
project/media/django/js/timeparse.js [new file with mode: 0644]
project/media/django/js/urlify.js [new file with mode: 0644]
project/media/js/jquery-ui-1.8.11.custom.min.js [new file with mode: 0644]
project/media/skin/css/admin.css [new file with mode: 0644]
project/media/skin/css/auf.css [new file with mode: 0644]
project/media/skin/images/favicon.ico [new file with mode: 0644]
project/media/skin/images/logo_auf.gif [new file with mode: 0644]
project/media/skin/images/menu.png [new file with mode: 0644]
project/rh_v1/models.py
project/settings.py
project/templates/base.html [deleted file]
project/templates/menu.html [new file with mode: 0644]
project/urls.py

index 59504a1..e0d6adf 100644 (file)
@@ -1,10 +1,12 @@
 [buildout]
+newest = false
 parts = django
 versions = versions
 
 find-links = http://pypi.auf.org/simple/auf.recipe.django
     http://pypi.auf.org/simple/auf.django.skin
     http://pypi.auf.org/datamaster_modeles/
+    http://pypi.auf.org/simple/auf.django.auth
 
 eggs =
     django
@@ -12,10 +14,14 @@ eggs =
     django-admin-tools
     auf.django.skin
     datamaster_modeles
+    auf.django.auth
 
 [versions]
 django-admin-tools = 0.4.0
 django = 1.2.5
+south = 0.7
+auf.django.skin = 0.15dev
+auf.django.auth = 0.5.2dev
 
 [django] 
 recipe = auf.recipe.django
index b0f8c17..215c809 100644 (file)
@@ -58,3 +58,10 @@ class PosteForm(forms.ModelForm):
                sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies] +
                       [('rh-%s' % p.id, unicode(p)) for p in rhv1],
                       key=lambda t: t[1])
+
+
+class PosteFinancementForm(forms.ModelForm):
+    """ Formulaire des sources de financement pour un poste. """
+    class Meta:
+        model = dae.PosteFinancement
+        fields = ('type', 'montant', 'pourcentage', 'commentaire')
diff --git a/project/dae/migrations/0003_auto__del_postecomparatifexterne.py b/project/dae/migrations/0003_auto__del_postecomparatifexterne.py
new file mode 100644 (file)
index 0000000..36d064c
--- /dev/null
@@ -0,0 +1,360 @@
+# 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):
+        
+        # Deleting model 'PosteComparatifExterne'
+        db.delete_table('dae_postecomparatifexterne')
+
+
+    def backwards(self, orm):
+        
+        # Adding model 'PosteComparatifExterne'
+        db.create_table('dae_postecomparatifexterne', (
+            ('montant', self.gf('django.db.models.fields.DecimalField')(max_digits=12, decimal_places=2)),
+            ('devise', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['rh_v1.Devise'])),
+            ('type_org', self.gf('django.db.models.fields.CharField')(max_length=10)),
+            ('min_max', self.gf('django.db.models.fields.CharField')(max_length=10)),
+            ('poste', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dae.Poste'])),
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+        ))
+        db.send_create_signal('dae', ['PosteComparatifExterne'])
+
+
+    models = {
+        'dae.documentemploye': {
+            'Meta': {'object_name': 'DocumentEmploye'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'dae.documentposte': {
+            'Meta': {'object_name': 'DocumentPoste'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'dae.dossier': {
+            'Meta': {'object_name': 'Dossier'},
+            'classement': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Classement']"}),
+            'compte_compta': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'compte_courriel': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'contrat_date_debut': ('django.db.models.fields.DateField', [], {}),
+            'contrat_date_fin': ('django.db.models.fields.DateField', [], {}),
+            'contrat_nb_mois': ('django.db.models.fields.IntegerField', [], {}),
+            'devise': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Devise']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'mobilite_interne': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'organisme_bstg': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.OrganismeBstg']"}),
+            'poste': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dae.Poste']"}),
+            'regime_travail': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
+            'regime_travail_nb_heure_semaine': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
+            'remplacement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'salaire': ('django.db.models.fields.DecimalField', [], {'default': 'None', 'null': 'True', 'max_digits': '12', 'decimal_places': '2'}),
+            'statut': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Statut']"}),
+            'statut_anterieur': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Statut']"}),
+            'statut_residence': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'type_contrat': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.TypeContrat']"})
+        },
+        'dae.employe': {
+            'Meta': {'object_name': 'Employe'},
+            'genre': ('django.db.models.fields.CharField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'id_rh': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['rh_v1.Employe']"}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'prenom': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'dae.groupetyperemuneration': {
+            'Meta': {'object_name': 'GroupeTypeRemuneration'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'ordre': ('django.db.models.fields.IntegerField', [], {})
+        },
+        'dae.justificationemploye': {
+            'Meta': {'object_name': 'JustificationEmploye'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'dae.justificationposte': {
+            'Meta': {'object_name': 'JustificationPoste'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'dae.poste': {
+            'Meta': {'object_name': 'Poste'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'appel': ('django.db.models.fields.CharField', [], {'default': "'interne'", 'max_length': '10'}),
+            'autre_max': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
+            'autre_min': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
+            'classement_max': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Classement']"}),
+            'classement_min': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Classement']"}),
+            'comp_autre_max': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_autre_min': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_fonctionpub_max': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_fonctionpub_min': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_locale_max': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_locale_min': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_ong_max': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_ong_min': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_universite_max': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'comp_universite_min': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
+            'date_creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_debut': ('django.db.models.fields.DateField', [], {}),
+            'date_fin': ('django.db.models.fields.DateField', [], {'null': 'True'}),
+            'date_modification': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'devise_comparaison': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['rh_v1.Devise']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'id_rh': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['rh_v1.Poste']"}),
+            'implantation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Implantation']"}),
+            'indemn_max': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
+            'indemn_min': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
+            'mise_a_disposition': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'regime_travail': ('django.db.models.fields.DecimalField', [], {'default': '100', 'max_digits': '12', 'decimal_places': '2'}),
+            'regime_travail_nb_heure_semaine': ('django.db.models.fields.DecimalField', [], {'default': '40', 'max_digits': '12', 'decimal_places': '2'}),
+            'responsable': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Poste']"}),
+            'salaire_max': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
+            'salaire_min': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
+            'service': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.Service']"}),
+            'statut_residence': ('django.db.models.fields.CharField', [], {'default': "'MAD'", 'max_length': '10'}),
+            'type_poste': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['rh_v1.TypePoste']"}),
+            'valeur_point_max': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.ValeurPoint']"}),
+            'valeur_point_min': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['rh_v1.ValeurPoint']"})
+        },
+        'dae.postefinancement': {
+            'Meta': {'object_name': 'PosteFinancement'},
+            'commentaire': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'montant': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
+            'poste': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'financements'", 'to': "orm['dae.Poste']"}),
+            'pourcentage': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '1'})
+        },
+        'dae.remuneration': {
+            'Meta': {'object_name': 'Remuneration'},
+            'annule': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'date_annule': ('django.db.models.fields.DateField', [], {}),
+            'date_creation': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_desactivation': ('django.db.models.fields.DateField', [], {}),
+            'date_effective': ('django.db.models.fields.DateField', [], {}),
+            'desactivation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'devise': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to_field': "'code'", 'db_column': "'devise'", 'to': "orm['rh_v1.Devise']"}),
+            'dossier': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dae.Dossier']", 'db_column': "'dossier'"}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'montant': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
+            'pourcentage': ('django.db.models.fields.IntegerField', [], {}),
+            'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dae.TypeRemuneration']", 'db_column': "'type'"}),
+            'user_annule': ('django.db.models.fields.IntegerField', [], {}),
+            'user_creation': ('django.db.models.fields.IntegerField', [], {}),
+            'user_desactivation': ('django.db.models.fields.IntegerField', [], {})
+        },
+        'dae.typeremuneration': {
+            'Meta': {'object_name': 'TypeRemuneration'},
+            'groupe': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dae.GroupeTypeRemuneration']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordre': ('django.db.models.fields.IntegerField', [], {})
+        },
+        'dae.validation': {
+            'Meta': {'object_name': 'Validation'},
+            'date': ('django.db.models.fields.DateField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'dae.validationemploye': {
+            'Meta': {'object_name': 'ValidationEmploye'},
+            'employe': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dae.Employe']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'dae.validationposte': {
+            'Meta': {'object_name': 'ValidationPoste'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'poste': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dae.Poste']"})
+        },
+        'datamaster_modeles.bureau': {
+            'Meta': {'object_name': 'Bureau', 'db_table': "u'ref_bureau'"},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'implantation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Implantation']", 'db_column': "'implantation'"}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'nom_court': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'nom_long': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'region': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Region']", 'db_column': "'region'"})
+        },
+        'datamaster_modeles.implantation': {
+            'Meta': {'object_name': 'Implantation', 'db_table': "u'ref_implantation'"},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'adresse_physique_bureau': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'adresse_physique_code_postal': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'adresse_physique_code_postal_avant_ville': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+            'adresse_physique_no': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'adresse_physique_pays': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'impl_adresse_physique'", 'to_field': "'code'", 'db_column': "'adresse_physique_pays'", 'to': "orm['datamaster_modeles.Pays']"}),
+            'adresse_physique_precision': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'adresse_physique_precision_avant': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'adresse_physique_region': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'adresse_physique_rue': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'adresse_physique_ville': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'adresse_postale_boite_postale': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_bureau': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_code_postal': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_code_postal_avant_ville': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+            'adresse_postale_no': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_pays': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'impl_adresse_postale'", 'to_field': "'code'", 'db_column': "'adresse_postale_pays'", 'to': "orm['datamaster_modeles.Pays']"}),
+            'adresse_postale_precision': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_precision_avant': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_region': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_rue': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'adresse_postale_ville': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'bureau_rattachement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Implantation']", 'db_column': "'bureau_rattachement'"}),
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'code_meteo': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'commentaire': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'courriel': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'courriel_interne': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'date_extension': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_fermeture': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_inauguration': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_ouverture': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'fax': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'fax_interne': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'fuseau_horaire': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'hebergement_convention': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+            'hebergement_convention_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'hebergement_etablissement': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'modif_date': ('django.db.models.fields.DateField', [], {}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'nom_court': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'nom_long': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'region': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Region']", 'db_column': "'region'"}),
+            'remarque': ('django.db.models.fields.TextField', [], {}),
+            'responsable_implantation': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'statut': ('django.db.models.fields.IntegerField', [], {}),
+            'telephone': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'telephone_interne': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'})
+        },
+        'datamaster_modeles.pays': {
+            'Meta': {'object_name': 'Pays', 'db_table': "u'ref_pays'"},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '2'}),
+            'code_bureau': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Bureau']", 'to_field': "'code'", 'db_column': "'code_bureau'"}),
+            'code_iso3': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3', 'blank': 'True'}),
+            'developpement': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'monnaie': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'nord_sud': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'region': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Region']", 'db_column': "'region'"})
+        },
+        'datamaster_modeles.region': {
+            'Meta': {'object_name': 'Region', 'db_table': "u'ref_region'"},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'implantation_bureau': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'gere_region'", 'db_column': "'implantation_bureau'", 'to': "orm['datamaster_modeles.Implantation']"}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rh_v1.classement': {
+            'Meta': {'object_name': 'Classement'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'coefficient': ('django.db.models.fields.FloatField', [], {}),
+            'commentaire': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'date_modification': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'degre': ('django.db.models.fields.IntegerField', [], {}),
+            'echelon': ('django.db.models.fields.IntegerField', [], {}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        'rh_v1.devise': {
+            'Meta': {'object_name': 'Devise'},
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rh_v1.employe': {
+            'Meta': {'object_name': 'Employe'},
+            'adresse': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'code_postal': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'commentaire': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'date_creation': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_entree': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_maj': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'date_naissance': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'genre': ('django.db.models.fields.CharField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nationalite': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nationalite'", 'to_field': "'code'", 'db_column': "'nationalite'", 'to': "orm['datamaster_modeles.Pays']"}),
+            'no_rue': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'pays': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pays'", 'db_column': "'pays'", 'to_field': "'code'", 'to': "orm['datamaster_modeles.Pays']", 'blank': 'True', 'null': 'True'}),
+            'prenom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'province': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'situation_famille': ('django.db.models.fields.CharField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}),
+            'tel_cellulaire': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'tel_domicile': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'ville': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        'rh_v1.familleemploi': {
+            'Meta': {'object_name': 'FamilleEmploi'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rh_v1.organismebstg': {
+            'Meta': {'object_name': 'OrganismeBstg'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        'rh_v1.poste': {
+            'Meta': {'object_name': 'Poste'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'date_modification': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'implantation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'db_column': "'implantation'", 'to': "orm['datamaster_modeles.Implantation']"}),
+            'proportion': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'type_poste': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rh_v1.TypePoste']", 'db_column': "'type_poste'"})
+        },
+        'rh_v1.service': {
+            'Meta': {'object_name': 'Service'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rh_v1.statut': {
+            'Meta': {'object_name': 'Statut'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type_contrat_categorie': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        'rh_v1.typecontrat': {
+            'Meta': {'object_name': 'TypeContrat'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'categorie': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'nom_long': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rh_v1.typeposte': {
+            'Meta': {'object_name': 'TypePoste'},
+            'actif': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'date_modification': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'famille_emploi': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rh_v1.FamilleEmploi']", 'db_column': "'famille_emploi'"}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'is_responsable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'nom_feminin': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rh_v1.valeurpoint': {
+            'Meta': {'object_name': 'ValeurPoint'},
+            'annee': ('django.db.models.fields.IntegerField', [], {}),
+            'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
+            'implantation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['datamaster_modeles.Implantation']", 'db_column': "'implantation'"}),
+            'valeur': ('django.db.models.fields.FloatField', [], {})
+        }
+    }
+
+    complete_apps = ['dae']
index 49940ed..52e3db1 100644 (file)
@@ -21,6 +21,26 @@ POSTE_STATUT_CHOICES = (
 )
 
 
+
+class PosteManager(models.Manager):
+    """
+    Chargement de tous les objets FK existants sur chaque QuerySet.
+    """
+    def get_query_set(self):
+        fkeys = (
+            'id_rh',
+            'responsable',
+            'implantation',
+            'type_poste',
+            'service',
+            'classement_min',
+            'classement_max',
+            'valeur_point_min',
+            'valeur_point_max',
+        )
+        return super(PosteManager, self).get_query_set().select_related(*fkeys).all()
+
+
 class Poste(models.Model):
     # Modèle existant
     id_rh = models.ForeignKey(rh.Poste, null=True, related_name='+',
@@ -89,10 +109,13 @@ class Poste(models.Model):
     # Méta
     date_creation = models.DateTimeField(auto_now_add=True)
     date_modification = models.DateTimeField(auto_now=True)
-    date_debut = models.DateField()
-    date_fin = models.DateField(null=True)
+    date_debut = models.DateField(help_text="format: aaaa-mm-jj")
+    date_fin = models.DateField(null=True, help_text="format: aaaa-mm-jj")
     actif = models.BooleanField(default=True)
 
+    # Managers
+    objects = PosteManager()
+
     def __unicode__(self):
         return u'%s - %s (%s)' % (self.implantation, self.type_poste.nom,
                                   self.nom)
@@ -113,30 +136,6 @@ class Poste(models.Model):
         super(Subject, self).save(*args, **kwargs)
 
 
-MIN_MAX_CHOICES = (
-    ('min', 'minimum'),
-    ('max', 'maximum'),
-)
-
-
-TYPE_ORG_CHOICES = (
-    ('locale_ent', 'minimum'),
-    ('university', 'université'),
-    ('government', 'fonction publique'),
-    ('ong', 'ONG'),
-    ('autre', 'autre'),
-)
-
-
-class PosteComparatifExterne(models.Model):
-    poste = models.ForeignKey('Poste')
-    montant = models.DecimalField(max_digits=12, decimal_places=2)
-    # TODO default='EUR'
-    devise = models.ForeignKey(rh.Devise, related_name='+')
-    min_max = models.CharField(max_length=10, choices=MIN_MAX_CHOICES)
-    type_org = models.CharField(max_length=10, choices=TYPE_ORG_CHOICES)
-
-
 POSTE_FINANCEMENT_CHOICES = (
     ('A', 'A - Frais de personnel'),
     ('B', 'B - Projet(s)-Titre(s)'),
@@ -153,8 +152,8 @@ class PosteFinancement(models.Model):
 
 
 GENRE_CHOICES = (
-    ('m', 'Masculin'),
-    ('f', 'Féminin'),
+    ('M', 'Homme'),
+    ('F', 'Femme'),
 )
 
 
diff --git a/project/dae/templates/dae/financement-full.html b/project/dae/templates/dae/financement-full.html
new file mode 100644 (file)
index 0000000..132dc93
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends 'base.html' %}
+
+{% block title %}
+  Formulaire financement
+{% endblock %}
+
+{% block main %}
+  {% include 'dae/financement.html' %}
+{% endblock %}
diff --git a/project/dae/templates/dae/financement.html b/project/dae/templates/dae/financement.html
new file mode 100644 (file)
index 0000000..06d3ed7
--- /dev/null
@@ -0,0 +1,11 @@
+<h2>Financement</h2>
+
+<form action="{% url financement poste_key financement_id %}" method="post">
+  <table cellspacing="0" width="100%">
+    {{ form.as_table }}
+  </table>
+  <input type="submit" name="save" value="Sauvegarder" />
+  {% if not new %}
+    <input type="submit" name="delete" value="Supprimer" />
+  {% endif %}
+</form>
index fa953e3..d91941f 100644 (file)
@@ -1,7 +1,9 @@
 {% extends 'base.html' %}
+
 {% block title %}
   Autorisation d'embauche
 {% endblock %}
-{% block content %}
+
+{% block main %}
   <a href="{% url poste %}">Poste</a>
 {% endblock %}
index 06518d7..4784db9 100644 (file)
@@ -1,17 +1,87 @@
 {% extends 'base.html' %}
+
+{% block extrahead %}
+  <script src="{{ MEDIA_URL }}js/jquery-1.5.1.min.js"
+          type="text/javascript"></script>
+  <script src="{{ MEDIA_URL }}js/jquery-ui-1.8.11.custom.min.js"
+          type="text/javascript"></script>
+  <link href="{{ MEDIA_URL }}/css/redmond/jquery-ui-1.8.11.custom.css"
+        rel="stylesheet" />
+{% endblock %}
+
 {% block title %}
   Formulaire poste
 {% endblock %}
-{% block content %}
+
+{% block main %}
+  <h2>
+    {% if new %}
+      Nouveau poste
+    {% else %}
+      Poste
+    {% endif %}
+  </h2>
+
   <form action="" method="post">
     <table cellspacing="0">
       {{ form.as_table }}
     </table>
-    <input type="submit" name="submit" value="Sauvegarder" />
+    <input type="submit" name="save" value="Sauvegarder" />
   </form>
+
+  <h2>Financement</h2>
+
+  <table cellspacing="0" id="financing">
+    <tr>
+      <th>Type</th>
+      <th>Montant</th>
+      <th>Devise</th>
+      <th>Pourcentage</th>
+      <th>Commentaire</th>
+      <th></th>
+    </tr>
+    {% for fin in poste.financements.all %}
+      <tr>
+        <td>{{ fin.type }}</td>
+        <td>{{ fin.montant }}</td>
+        <td>{{ fin.devise }}</td>
+        <td>{{ fin.pourcentage }}</td>
+        <td>{{ fin.commentaire }}</td>
+        <td><a href="{% url financement poste_key fin.id %}">Modifier</a></td>
+      </tr>
+    {% empty %}
+      <tr>
+        <td colspan="5">
+          {% if new %}
+            Vous devez enregister ce nouveau poste avant de pouvoir spécifier
+            la ou les sources de financement.
+          {% else %}
+            Aucun financement au registre
+          {% endif %}
+        </td>
+      </tr>
+    {% endfor %}
+  </table>
+  {% if not new %}
+    <a href="{% url financement poste_key %}" class="new">
+      Ajouter une source de financement
+    </a>
+  {% endif %}
+
+  <div id="financing-form"></div>
+
   <script type="text/javascript">
     $('#id_poste').change(function() {
         window.location = '{% url poste %}/' + $(this).val();
     });
+    $('#financing a, a.new').click(function() {
+        $('#financing-form').load($(this).attr('href') + '?ajax=1')
+                            .dialog({
+                                modal: true,
+                                height: 460,
+                                width: 500
+                            });
+        return false;
+    });
   </script>
 {% endblock %}
index 900a5ee..25f2708 100644 (file)
@@ -4,6 +4,9 @@ from django.conf.urls.defaults import patterns, url
 urlpatterns = patterns(
     'project.dae.views',
     (r'^$', 'index'),
+    url(r'^poste/(?P<key>.*)/financement$', 'financement', name='financement'),
+    url(r'^poste/(?P<key>.*)/financement/(?P<id>\d*)$', 'financement',
+        name='financement'),
     url(r'^poste$', 'poste', name='poste'),
-    url(r'^poste/(?P<id>.*)$', 'poste', name='poste'),
+    url(r'^poste/(?P<key>.*)$', 'poste', name='poste'),
 )
index 3904725..fda10e9 100644 (file)
@@ -2,7 +2,7 @@
 from django.shortcuts import redirect, render_to_response, get_object_or_404
 from django.template import RequestContext
 
-from project.dae.forms import PosteForm
+from project.dae.forms import PosteForm, PosteFinancementForm
 from project.dae import models as dae
 from project.rh_v1 import models as rh
 
@@ -11,7 +11,7 @@ def index(request):
     return render_to_response('dae/index.html', {}, RequestContext(request))
 
 
-def poste(request, id=None):
+def poste(request, key=None):
     """ Formulaire pour un poste.
 
     Permet de créer ou modifier un poste. Si le poste n'existe que dans rh_v1
@@ -20,13 +20,10 @@ def poste(request, id=None):
     """
     poste, data, vars = None, dict(), dict()
 
-    if request.POST:
-        data.update(dict(request.POST.items()))
-
-    if id:
+    if key:
         # Poste existant
-        data['poste'] = id
-        type, id = id.split('-')
+        data['poste'] = key
+        type, id = key.split('-')
 
         if type == 'dae':
             poste = get_object_or_404(dae.Poste, pk=id)
@@ -36,17 +33,64 @@ def poste(request, id=None):
             poste = dae.Poste(id_rh=p, nom=p.type_poste.nom)
             for field in ('implantation', 'type_poste', 'actif'):
                 setattr(poste, field, getattr(p, field))
+    else:
+        # Nouveau poste
+        vars['new'] = True
 
     if request.POST:
+        data.update(dict(request.POST.items()))
         form = PosteForm(data, instance=poste)
-        if form.is_valid():
+        if 'save' in data and form.is_valid():
             poste = form.save()
-            return redirect('poste', id='dae-%s' % poste.id)
+            return redirect('poste', key='dae-%s' % poste.id)
     else:
         # 'initial' évite la validation prémature lors d'une copie de poste de
         # rh_v1 vers dae.
         form = PosteForm(initial=data, instance=poste)
 
-    vars['form'] = form
+    vars.update(dict(form=form, poste=poste, poste_key=key))
 
     return render_to_response('dae/poste.html', vars, RequestContext(request))
+
+
+def financement(request, key=None, id=None):
+    """ Formulaire pour une source de financement pour un poste. """
+    poste, financement, data, vars = None, None, dict(), dict()
+
+    if request.POST:
+        data.update(dict(request.POST.items()))
+
+    if key:
+        type, poste_id = key.split('-')
+        vars['poste_key'] = key
+        if type == 'dae':
+            poste = get_object_or_404(dae.Poste, pk=poste_id)
+            if id:
+                # Financement existant
+                financement = get_object_or_404(dae.PosteFinancement, pk=id)
+                vars['financement_id'] = id
+            else:
+                # Nouveau financement
+                financement = dae.PosteFinancement(poste_id=poste_id)
+                vars['new'] = True
+
+    if not financement:
+        return Http404
+
+    if request.POST:
+        form = PosteFinancementForm(data, instance=financement)
+        if 'delete' in data:
+            financement.delete()
+        elif 'save' in data and form.is_valid():
+            financement = form.save()
+        return redirect('poste', key='dae-%s' % poste.id)
+    else:
+        form = PosteFinancementForm(initial=data, instance=financement)
+
+    vars.update(dict(form=form, financement=financement))
+
+    if 'ajax' in request.GET:
+        template = 'dae/financement.html'
+    else:
+        template = 'dae/financement-full.html'
+    return render_to_response(template, vars, RequestContext(request))
diff --git a/project/dashboard.py b/project/dashboard.py
new file mode 100644 (file)
index 0000000..03ecf29
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- encoding: utf-8 -*
+
+"""
+This file was generated with the customdashboard management command, it
+contains the two classes for the main dashboard and app index dashboard.
+You can customize these classes as you want.
+
+To activate your index dashboard add the following to your settings.py::
+    ADMIN_TOOLS_INDEX_DASHBOARD = 'SIGMA.dashboard.CustomIndexDashboard'
+
+And to activate the app index dashboard::
+    ADMIN_TOOLS_APP_INDEX_DASHBOARD = 'SIGMA.dashboard.CustomAppIndexDashboard'
+"""
+
+from django.utils.translation import ugettext_lazy as _
+from django.core.urlresolvers import reverse
+
+from admin_tools.dashboard import modules, Dashboard, AppIndexDashboard
+from admin_tools.utils import get_admin_site_name
+
+
+class CustomIndexDashboard(Dashboard):
+    """
+    Custom index dashboard for SIGMA.
+    """
+    def init_with_context(self, context):
+        site_name = get_admin_site_name(context)
+
+        # append an app list module for "Applications"
+        self.children.append(modules.AppList(
+            _('Applications'),
+            exclude=('django.contrib.*',),
+        ))
+
+        # append an app list module for "Administration"
+        self.children.append(modules.AppList(
+            _('Administration'),
+            models=('django.contrib.*',),
+        ))
+
+        # append a recent actions module
+        self.children.append(modules.RecentActions(_('Recent Actions'), 5))
diff --git a/project/media/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png b/project/media/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644 (file)
index 0000000..5b5dab2
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/project/media/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png b/project/media/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png
new file mode 100644 (file)
index 0000000..47acaad
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png differ
diff --git a/project/media/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png b/project/media/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
new file mode 100644 (file)
index 0000000..9fb564f
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png differ
diff --git a/project/media/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png b/project/media/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png
new file mode 100644 (file)
index 0000000..0149515
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png differ
diff --git a/project/media/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png b/project/media/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644 (file)
index 0000000..4443fdc
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/project/media/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/project/media/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
new file mode 100644 (file)
index 0000000..81ecc36
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png differ
diff --git a/project/media/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png b/project/media/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
new file mode 100644 (file)
index 0000000..4f3faf8
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png differ
diff --git a/project/media/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/project/media/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
new file mode 100644 (file)
index 0000000..38c3833
Binary files /dev/null and b/project/media/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png differ
diff --git a/project/media/css/redmond/images/ui-icons_217bc0_256x240.png b/project/media/css/redmond/images/ui-icons_217bc0_256x240.png
new file mode 100644 (file)
index 0000000..6f4bd87
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_217bc0_256x240.png differ
diff --git a/project/media/css/redmond/images/ui-icons_2e83ff_256x240.png b/project/media/css/redmond/images/ui-icons_2e83ff_256x240.png
new file mode 100644 (file)
index 0000000..09d1cdc
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_2e83ff_256x240.png differ
diff --git a/project/media/css/redmond/images/ui-icons_469bdd_256x240.png b/project/media/css/redmond/images/ui-icons_469bdd_256x240.png
new file mode 100644 (file)
index 0000000..bd2cf07
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_469bdd_256x240.png differ
diff --git a/project/media/css/redmond/images/ui-icons_6da8d5_256x240.png b/project/media/css/redmond/images/ui-icons_6da8d5_256x240.png
new file mode 100644 (file)
index 0000000..9f3eafa
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_6da8d5_256x240.png differ
diff --git a/project/media/css/redmond/images/ui-icons_cd0a0a_256x240.png b/project/media/css/redmond/images/ui-icons_cd0a0a_256x240.png
new file mode 100644 (file)
index 0000000..2ab019b
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_cd0a0a_256x240.png differ
diff --git a/project/media/css/redmond/images/ui-icons_d8e7f3_256x240.png b/project/media/css/redmond/images/ui-icons_d8e7f3_256x240.png
new file mode 100644 (file)
index 0000000..ad2dc6f
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_d8e7f3_256x240.png differ
diff --git a/project/media/css/redmond/images/ui-icons_f9bd01_256x240.png b/project/media/css/redmond/images/ui-icons_f9bd01_256x240.png
new file mode 100644 (file)
index 0000000..7862502
Binary files /dev/null and b/project/media/css/redmond/images/ui-icons_f9bd01_256x240.png differ
diff --git a/project/media/css/redmond/jquery-ui-1.8.11.custom.css b/project/media/css/redmond/jquery-ui-1.8.11.custom.css
new file mode 100644 (file)
index 0000000..6b2a737
--- /dev/null
@@ -0,0 +1,573 @@
+/*
+ * jQuery UI CSS Framework 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; }
+.ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
+.ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-right {  -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
+.ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
+ * jQuery UI Resizable 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Selectable 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }
+/*
+ * jQuery UI Autocomplete 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }      
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.11
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+       list-style:none;
+       padding: 2px;
+       margin: 0;
+       display:block;
+       float: left;
+}
+.ui-menu .ui-menu {
+       margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+       margin:0;
+       padding: 0;
+       zoom: 1;
+       float: left;
+       clear: left;
+       width: 100%;
+}
+.ui-menu .ui-menu-item a {
+       text-decoration:none;
+       display:block;
+       padding:.2em .4em;
+       line-height:1.5;
+       zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+       font-weight: normal;
+       margin: -1px;
+}
+/*
+ * jQuery UI Button 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; } 
+button.ui-button-icons-only { width: 3.7em; } 
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4;  }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } 
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
+ * jQuery UI Tabs 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month, 
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+    display: none; /*sorry for IE5*/
+    display/**/: block; /*sorry for IE5*/
+    position: absolute; /*must have*/
+    z-index: -1; /*must have*/
+    filter: mask(); /*must have*/
+    top: -4px; /*must have*/
+    left: -4px; /*must have*/
+    width: 200px; /*must have*/
+    height: 200px; /*must have*/
+}/*
+ * jQuery UI Progressbar 1.8.11
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file
diff --git a/project/media/django/css/base.css b/project/media/django/css/base.css
new file mode 100644 (file)
index 0000000..29f7c83
--- /dev/null
@@ -0,0 +1,759 @@
+/*
+    DJANGO Admin styles
+*/
+
+body {
+    margin: 0;
+    padding: 0;
+    font-size: 12px;
+    font-family: "Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
+    color: #333;
+    background: #fff;
+}
+
+/* LINKS */
+
+a:link, a:visited {
+    color: #5b80b2;
+    text-decoration: none;
+}
+
+a:hover {
+    color: #036;
+}
+
+a img {
+    border: none;
+}
+
+a.section:link, a.section:visited {
+    color: white;
+    text-decoration: none;
+}
+
+/* GLOBAL DEFAULTS */
+
+p, ol, ul, dl {
+    margin: .2em 0 .8em 0;
+}
+
+p {
+    padding: 0;
+    line-height: 140%;
+}
+
+h1,h2,h3,h4,h5 {
+    font-weight: bold;
+}
+
+h1 {
+    font-size: 18px;
+    color: #666;
+    padding: 0 6px 0 0;
+    margin: 0 0 .2em 0;
+}
+
+h2 {
+    font-size: 16px;
+    margin: 1em 0 .5em 0;
+}
+
+h2.subhead {
+    font-weight: normal;
+    margin-top: 0;
+}
+
+h3 {
+    font-size: 14px;
+    margin: .8em 0 .3em 0;
+    color: #666;
+    font-weight: bold;
+}
+
+h4 {
+    font-size: 12px;
+    margin: 1em 0 .8em 0;
+    padding-bottom: 3px;
+}
+
+h5 {
+    font-size: 10px;
+    margin: 1.5em 0 .5em 0;
+    color: #666;
+    text-transform: uppercase;
+    letter-spacing: 1px;
+}
+
+ul li {
+    list-style-type: square;
+    padding: 1px 0;
+}
+
+ul.plainlist {
+    margin-left: 0 !important;
+}
+
+ul.plainlist li {
+    list-style-type: none;
+}
+
+li ul {
+    margin-bottom: 0;
+}
+
+li, dt, dd {
+    font-size: 11px;
+    line-height: 14px;
+}
+
+dt {
+    font-weight: bold;
+    margin-top: 4px;
+}
+
+dd {
+    margin-left: 0;
+}
+
+form {
+    margin: 0;
+    padding: 0;
+}
+
+fieldset {
+    margin: 0;
+    padding: 0;
+}
+
+blockquote {
+    font-size: 11px;
+    color: #777;
+    margin-left: 2px;
+    padding-left: 10px;
+    border-left: 5px solid #ddd;
+}
+
+code, pre {
+    font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
+    background: inherit;
+    color: #666;
+    font-size: 11px;
+}
+
+pre.literal-block {
+    margin: 10px;
+    background: #eee;
+    padding: 6px 8px;
+}
+
+code strong {
+    color: #930;
+}
+
+hr {
+    clear: both;
+    color: #eee;
+    background-color: #eee;
+    height: 1px;
+    border: none;
+    margin: 0;
+    padding: 0;
+    font-size: 1px;
+    line-height: 1px;
+}
+
+/* TEXT STYLES & MODIFIERS */
+
+.small {
+    font-size: 11px;
+}
+
+.tiny {
+    font-size: 10px;
+}
+
+p.tiny {
+    margin-top: -2px;
+}
+
+.mini {
+    font-size: 9px;
+}
+
+p.mini {
+    margin-top: -3px;
+}
+
+.help, p.help {
+    font-size: 10px !important;
+    color: #999;
+}
+
+p img, h1 img, h2 img, h3 img, h4 img, td img {
+    vertical-align: middle;
+}
+
+.quiet, a.quiet:link, a.quiet:visited {
+    color: #999 !important;
+    font-weight: normal !important;
+}
+
+.quiet strong {
+    font-weight: bold !important;
+}
+
+.float-right {
+    float: right;
+}
+
+.float-left {
+    float: left;
+}
+
+.clear {
+    clear: both;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-right {
+    text-align: right;
+}
+
+.example {
+    margin: 10px 0;
+    padding: 5px 10px;
+    background: #efefef;
+}
+
+.nowrap {
+    white-space: nowrap;
+}
+
+/* TABLES */
+
+table {
+    border-collapse: collapse;
+    border-color: #ccc;
+}
+
+td, th {
+    font-size: 11px;
+    line-height: 13px;
+    border-bottom: 1px solid #eee;
+    vertical-align: top;
+    padding: 5px;
+    font-family: "Lucida Grande", Verdana, Arial, sans-serif;
+}
+
+th {
+    text-align: left;
+    font-size: 12px;
+    font-weight: bold;
+}
+
+thead th,
+tfoot td {
+    color: #666;
+    padding: 2px 5px;
+    font-size: 11px;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
+    border-left: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+}
+
+tfoot td {
+    border-bottom: none;
+    border-top: 1px solid #ddd;
+}
+
+thead th:first-child,
+tfoot td:first-child {
+    border-left: none !important;
+}
+
+thead th.optional {
+    font-weight: normal !important;
+}
+
+fieldset table {
+    border-right: 1px solid #eee;
+}
+
+tr.row-label td {
+    font-size: 9px;
+    padding-top: 2px;
+    padding-bottom: 0;
+    border-bottom: none;
+    color: #666;
+    margin-top: -1px;
+}
+
+tr.alt {
+    background: #f6f6f6;
+}
+
+.row1 {
+    background: #EDF3FE;
+}
+
+.row2 {
+    background: white;
+}
+
+/* SORTABLE TABLES */
+
+thead th a:link, thead th a:visited {
+    color: #666;
+    display: block;
+}
+
+table thead th.sorted {
+    background-position: bottom left !important;
+}
+
+table thead th.sorted a {
+    padding-right: 13px;
+}
+
+table thead th.ascending a {
+    background: url(../img/admin/arrow-down.gif) right .4em no-repeat;
+}
+
+table thead th.descending a {
+    background: url(../img/admin/arrow-up.gif) right .4em no-repeat;
+}
+
+/* ORDERABLE TABLES */
+
+table.orderable tbody tr td:hover {
+    cursor: move;
+}
+
+table.orderable tbody tr td:first-child {
+    padding-left: 14px;
+    background-image: url(../img/admin/nav-bg-grabber.gif);
+    background-repeat: repeat-y;
+}
+
+table.orderable-initalized .order-cell, body>tr>td.order-cell {
+    display: none;
+}
+
+/* FORM DEFAULTS */
+
+input, textarea, select, .form-row p {
+    margin: 2px 0;
+    padding: 2px 3px;
+    vertical-align: middle;
+    font-family: "Lucida Grande", Verdana, Arial, sans-serif;
+    font-weight: normal;
+    font-size: 11px;
+}
+
+textarea {
+    vertical-align: top !important;
+}
+
+input[type=text], input[type=password], textarea, select, .vTextField {
+    border: 1px solid #ccc;
+}
+
+/* FORM BUTTONS */
+
+.button, input[type=submit], input[type=button], .submit-row input {
+    background: white url(../img/admin/nav-bg.gif) bottom repeat-x;
+    padding: 3px 5px;
+    color: black;
+    border: 1px solid #bbb;
+    border-color: #ddd #aaa #aaa #ddd;
+}
+
+.button:active, input[type=submit]:active, input[type=button]:active {
+    background-image: url(../img/admin/nav-bg-reverse.gif);
+    background-position: top;
+}
+
+.button.default, input[type=submit].default, .submit-row input.default {
+    border: 2px solid #5b80b2;
+    background: #7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x;
+    font-weight: bold;
+    color: white;
+    float: right;
+}
+
+.button.default:active, input[type=submit].default:active {
+    background-image: url(../img/admin/default-bg-reverse.gif);
+    background-position: top;
+}
+
+/* MODULES */
+
+.module {
+    border: 1px solid #ccc;
+    margin-bottom: 5px;
+    background: white;
+}
+
+.module p, .module ul, .module h3, .module h4, .module dl, .module pre {
+    padding-left: 10px;
+    padding-right: 10px;
+}
+
+.module blockquote {
+    margin-left: 12px;
+}
+
+.module ul, .module ol {
+    margin-left: 1.5em;
+}
+
+.module h3 {
+    margin-top: .6em;
+}
+
+.module h2, .module caption, .inline-group h2 {
+    margin: 0;
+    padding: 2px 5px 3px 5px;
+    font-size: 11px;
+    text-align: left;
+    font-weight: bold;
+    background: #7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x;
+    color: white;
+}
+
+.module table {
+    border-collapse: collapse;
+}
+
+/* MESSAGES & ERRORS */
+
+ul.messagelist {
+    padding: 0 0 5px 0;
+    margin: 0;
+}
+
+ul.messagelist li {
+    font-size: 12px;
+    display: block;
+    padding: 4px 5px 4px 25px;
+    margin: 0 0 3px 0;
+    border-bottom: 1px solid #ddd;
+    color: #666;
+    background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat;
+}
+
+ul.messagelist li.warning{
+    background-image: url(../img/admin/icon_alert.gif);
+}
+
+ul.messagelist li.error{
+    background-image: url(../img/admin/icon_error.gif);
+}
+
+.errornote {
+    font-size: 12px !important;
+    display: block;
+    padding: 4px 5px 4px 25px;
+    margin: 0 0 3px 0;
+    border: 1px solid red;
+    color: red;
+    background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat;
+}
+
+ul.errorlist {
+    margin: 0 !important;
+    padding: 0 !important;
+}
+
+.errorlist li {
+    font-size: 12px !important;
+    display: block;
+    padding: 4px 5px 4px 25px;
+    margin: 0 0 3px 0;
+    border: 1px solid red;
+    color: white;
+    background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat;
+}
+
+.errorlist li a {
+       color: white;
+    text-decoration: underline;
+}
+
+td ul.errorlist {
+    margin: 0 !important;
+    padding: 0 !important;
+}
+
+td ul.errorlist li {
+    margin: 0 !important;
+}
+
+.errors {
+    background: #ffc;
+}
+
+.errors input, .errors select, .errors textarea {
+    border: 1px solid red;
+}
+
+div.system-message {
+    background: #ffc;
+    margin: 10px;
+    padding: 6px 8px;
+    font-size: .8em;
+}
+
+div.system-message p.system-message-title {
+    padding: 4px 5px 4px 25px;
+    margin: 0;
+    color: red;
+    background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat;
+}
+
+.description {
+    font-size: 12px;
+    padding: 5px 0 0 12px;
+}
+
+/* BREADCRUMBS */
+
+div.breadcrumbs {
+    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
+    padding: 2px 8px 3px 8px;
+    font-size: 11px;
+    color: #999;
+    border-top: 1px solid white;
+    border-bottom: 1px solid #ccc;
+    text-align: left;
+}
+
+/* ACTION ICONS */
+
+.addlink {
+    padding-left: 12px;
+    background: url(../img/admin/icon_addlink.gif) 0 .2em no-repeat;
+}
+
+.changelink {
+    padding-left: 12px;
+    background: url(../img/admin/icon_changelink.gif) 0 .2em no-repeat;
+}
+
+.deletelink {
+    padding-left: 12px;
+    background: url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat;
+}
+
+a.deletelink:link, a.deletelink:visited {
+    color: #CC3434;
+}
+
+a.deletelink:hover {
+    color: #993333;
+}
+
+/* OBJECT TOOLS */
+
+.object-tools {
+    font-size: 10px;
+    font-weight: bold;
+    font-family: Arial,Helvetica,sans-serif;
+    padding-left: 0;
+    float: right;
+    position: relative;
+    margin-top: -2.4em;
+    margin-bottom: -2em;
+}
+
+.form-row .object-tools {
+    margin-top: 5px;
+    margin-bottom: 5px;
+    float: none;
+    height: 2em;
+    padding-left: 3.5em;
+}
+
+.object-tools li {
+    display: block;
+    float: left;
+    background: url(../img/admin/tool-left.gif) 0 0 no-repeat;
+    padding: 0 0 0 8px;
+    margin-left: 2px;
+    height: 16px;
+}
+
+.object-tools li:hover {
+    background: url(../img/admin/tool-left_over.gif) 0 0 no-repeat;
+}
+
+.object-tools a:link, .object-tools a:visited {
+    display: block;
+    float: left;
+    color: white;
+    padding: .1em 14px .1em 8px;
+    height: 14px;
+    background: #999 url(../img/admin/tool-right.gif) 100% 0 no-repeat;
+}
+
+.object-tools a:hover, .object-tools li:hover a {
+    background: #5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat;
+}
+
+.object-tools a.viewsitelink, .object-tools a.golink {
+    background: #999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat;
+    padding-right: 28px;
+}
+
+.object-tools a.viewsitelink:hover, .object-tools a.golink:hover {
+    background: #5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat;
+}
+
+.object-tools a.addlink {
+    background: #999 url(../img/admin/tooltag-add.gif) top right no-repeat;
+    padding-right: 28px;
+}
+
+.object-tools a.addlink:hover {
+    background: #5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat;
+}
+
+/* OBJECT HISTORY */
+
+table#change-history {
+    width: 100%;
+}
+
+table#change-history tbody th {
+    width: 16em;
+}
+
+/* PAGE STRUCTURE */
+
+#container {
+    position: relative;
+    width: 100%;
+    min-width: 760px;
+    padding: 0;
+}
+
+#content {
+    margin: 10px 15px;
+}
+
+#header {
+    width: 100%;
+}
+
+#content-main {
+    float: left;
+    width: 100%;
+}
+
+#content-related {
+    float: right;
+    width: 18em;
+    position: relative;
+    margin-right: -19em;
+}
+
+#footer {
+    clear: both;
+    padding: 10px;
+}
+
+/* COLUMN TYPES */
+
+.colMS {
+    margin-right: 20em !important;
+}
+
+.colSM {
+    margin-left: 20em !important;
+}
+
+.colSM #content-related {
+    float: left;
+    margin-right: 0;
+    margin-left: -19em;
+}
+
+.colSM #content-main {
+    float: right;
+}
+
+.popup .colM {
+    width: 95%;
+}
+
+.subcol {
+    float: left;
+    width: 46%;
+    margin-right: 15px;
+}
+
+.dashboard #content {
+    width: 500px;
+}
+
+/* HEADER */
+
+#header {
+    background: #417690;
+    color: #ffc;
+    overflow: hidden;
+}
+
+#header a:link, #header a:visited {
+    color: white;
+}
+
+#header a:hover {
+    text-decoration: underline;
+}
+
+#branding h1 {
+    padding: 0 10px;
+    font-size: 18px;
+    margin: 8px 0;
+    font-weight: normal;
+    color: #f4f379;
+}
+
+#branding h2 {
+    padding: 0 10px;
+    font-size: 14px;
+    margin: -8px 0 8px 0;
+    font-weight: normal;
+    color: #ffc;
+}
+
+#user-tools {
+    position: absolute;
+    top: 0;
+    right: 0;
+    padding: 1.2em 10px;
+    font-size: 11px;
+    text-align: right;
+}
+
+/* SIDEBAR */
+
+#content-related h3 {
+    font-size: 12px;
+    color: #666;
+    margin-bottom: 3px;
+}
+
+#content-related h4 {
+    font-size: 11px;
+}
+
+#content-related .module h2 {
+    background: #eee url(../img/admin/nav-bg.gif) bottom left repeat-x;
+    color: #666;
+}
+
diff --git a/project/media/django/css/changelists.css b/project/media/django/css/changelists.css
new file mode 100644 (file)
index 0000000..3aa969a
--- /dev/null
@@ -0,0 +1,286 @@
+/* CHANGELISTS */
+
+#changelist {
+    position: relative;
+    width: 100%;
+}
+
+#changelist table {
+    width: 100%;
+}
+
+.change-list .hiddenfields { display:none; }
+
+.change-list .filtered table {
+    border-right: 1px solid #ddd;
+}
+
+.change-list .filtered {
+    min-height: 400px;
+}
+
+.change-list .filtered {
+    background: white url(../img/admin/changelist-bg.gif) top right repeat-y !important;
+}
+
+.change-list .filtered table, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
+    margin-right: 160px !important;
+    width: auto !important;
+}
+
+.change-list .filtered table tbody th {
+    padding-right: 1em;
+}
+
+#changelist .toplinks {
+    border-bottom: 1px solid #ccc !important;
+}
+
+#changelist .paginator {
+    color: #666;
+    border-top: 1px solid #eee;
+    border-bottom: 1px solid #eee;
+    background: white url(../img/admin/nav-bg.gif) 0 180% repeat-x;
+    overflow: hidden;
+}
+
+.change-list .filtered .paginator {
+    border-right: 1px solid #ddd;
+}
+
+/* CHANGELIST TABLES */
+
+#changelist table thead th {
+    white-space: nowrap;
+    vertical-align: middle;
+}
+
+#changelist table thead th.action-checkbox-column {
+    width: 1.5em;
+    text-align: center;
+}
+
+#changelist table tbody td {
+    border-left: 1px solid #ddd;
+}
+
+#changelist table tbody td:first-child {
+    border-left: 0;
+    border-right: 1px solid #ddd;
+    text-align: center;
+}
+
+#changelist table tfoot {
+    color: #666;
+}
+
+/* TOOLBAR */
+
+#changelist #toolbar {
+    padding: 3px;
+    border-bottom: 1px solid #ddd;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
+    color: #666;
+}
+
+#changelist #toolbar form input {
+    font-size: 11px;
+    padding: 1px 2px;
+}
+
+#changelist #toolbar form #searchbar {
+    padding: 2px;
+}
+
+#changelist #changelist-search img {
+    vertical-align: middle;
+}
+
+/* FILTER COLUMN */
+
+#changelist-filter {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 1000;
+    width: 160px;
+    border-left: 1px solid #ddd;
+    background: #efefef;
+    margin: 0;
+}
+
+#changelist-filter h2 {
+    font-size: 11px;
+    padding: 2px 5px;
+    border-bottom: 1px solid #ddd;
+}
+
+#changelist-filter h3 {
+    font-size: 12px;
+    margin-bottom: 0;
+}
+
+#changelist-filter ul {
+    padding-left: 0;
+    margin-left: 10px;
+}
+
+#changelist-filter li {
+    list-style-type: none;
+    margin-left: 0;
+    padding-left: 0;
+}
+
+#changelist-filter a {
+    color: #999;
+}
+
+#changelist-filter a:hover {
+    color: #036;
+}
+
+#changelist-filter li.selected {
+    border-left: 5px solid #ccc;
+    padding-left: 5px;
+    margin-left: -10px;
+}
+
+#changelist-filter li.selected a {
+    color: #5b80b2 !important;
+}
+
+/* DATE DRILLDOWN */
+
+.change-list ul.toplinks {
+    display: block;
+    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
+    border-top: 1px solid white;
+    float: left;
+    padding: 0 !important;
+    margin: 0 !important;
+    width: 100%;
+}
+
+.change-list ul.toplinks li {
+    float: left;
+    width: 9em;
+    padding: 3px 6px;
+    font-weight: bold;
+    list-style-type: none;
+}
+
+.change-list ul.toplinks .date-back a {
+    color: #999;
+}
+
+.change-list ul.toplinks .date-back a:hover {
+    color: #036;
+}
+
+/* PAGINATOR */
+
+.paginator {
+    font-size: 11px;
+    padding-top: 10px;
+    padding-bottom: 10px;
+    line-height: 22px;
+    margin: 0;
+    border-top: 1px solid #ddd;
+}
+
+.paginator a:link, .paginator a:visited {
+    padding: 2px 6px;
+    border: solid 1px #ccc;
+    background: white;
+    text-decoration: none;
+}
+
+.paginator a.showall {
+    padding: 0 !important;
+    border: none !important;
+}
+
+.paginator a.showall:hover {
+    color: #036 !important;
+    background: transparent !important;
+}
+
+.paginator .end {
+    border-width: 2px !important;
+    margin-right: 6px;
+}
+
+.paginator .this-page {
+    padding: 2px 6px;
+    font-weight: bold;
+    font-size: 13px;
+    vertical-align: top;
+}
+
+.paginator a:hover {
+    color: white;
+    background: #5b80b2;
+    border-color: #036;
+}
+
+/* ACTIONS */
+
+.filtered .actions {
+    margin-right: 160px !important;
+    border-right: 1px solid #ddd;
+}
+
+#changelist table input {
+    margin: 0;
+}
+
+#changelist table tbody tr.selected {
+    background-color: #FFFFCC;
+}
+
+#changelist .actions {
+    color: #999;
+    padding: 3px;
+    border-top: 1px solid #fff;
+    border-bottom: 1px solid #ddd;
+    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
+}
+
+#changelist .actions.selected {
+    background: #fffccf;
+    border-top: 1px solid #fffee8;
+    border-bottom: 1px solid #edecd6;
+}
+
+#changelist .actions span.all,
+#changelist .actions span.action-counter,
+#changelist .actions span.clear,
+#changelist .actions span.question {
+    font-size: 11px;
+    margin: 0 0.5em;
+    display: none;
+}
+
+#changelist .actions:last-child {
+    border-bottom: none;
+}
+
+#changelist .actions select {
+    border: 1px solid #aaa;
+    margin-left: 0.5em;
+    padding: 1px 2px;
+}
+
+#changelist .actions label {
+    font-size: 11px;
+    margin-left: 0.5em;
+}
+
+#changelist #action-toggle {
+    display: none;
+}
+
+#changelist .actions .button {
+    font-size: 11px;
+    padding: 1px 2px;
+}
diff --git a/project/media/django/css/dashboard.css b/project/media/django/css/dashboard.css
new file mode 100644 (file)
index 0000000..88e3b1d
--- /dev/null
@@ -0,0 +1,24 @@
+/* DASHBOARD */
+
+.dashboard .module table th {
+    width: 100%;
+}
+
+.dashboard .module table td {
+    white-space: nowrap;
+}
+
+.dashboard .module table td a {
+    display: block;
+    padding-right: .6em;
+}
+
+/* RECENT ACTIONS MODULE */
+
+.module ul.actionlist {
+    margin-left: 0;
+}
+
+ul.actionlist li {
+    list-style-type: none;
+}
diff --git a/project/media/django/css/forms.css b/project/media/django/css/forms.css
new file mode 100644 (file)
index 0000000..35d0ed7
--- /dev/null
@@ -0,0 +1,354 @@
+@import url('widgets.css');
+
+/* FORM ROWS */
+
+.form-row {
+    overflow: hidden;
+    padding: 8px 12px;
+    font-size: 11px;
+    border-bottom: 1px solid #eee;
+}
+
+.form-row img, .form-row input {
+    vertical-align: middle;
+}
+
+form .form-row p {
+    padding-left: 0;
+    font-size: 11px;
+}
+
+/* FORM LABELS */
+
+form h4 {
+    margin: 0 !important;
+    padding: 0 !important;
+    border: none !important;
+}
+
+label {
+    font-weight: normal !important;
+    color: #666;
+    font-size: 12px;
+}
+
+.required label, label.required {
+    font-weight: bold !important;
+    color: #333 !important;
+}
+
+/* RADIO BUTTONS */
+
+form ul.radiolist li {
+    list-style-type: none;
+}
+
+form ul.radiolist label {
+    float: none;
+    display: inline;
+}
+
+form ul.inline {
+    margin-left: 0;
+    padding: 0;
+}
+
+form ul.inline li {
+    float: left;
+    padding-right: 7px;
+}
+
+/* ALIGNED FIELDSETS */
+
+.aligned label {
+    display: block;
+    padding: 3px 10px 0 0;
+    float: left;
+    width: 8em;
+}
+
+.aligned ul label {
+    display: inline;
+    float: none;
+    width: auto;
+}
+
+.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField {
+    width: 350px;
+}
+
+form .aligned p, form .aligned ul {
+    margin-left: 7em;
+    padding-left: 30px;
+}
+
+form .aligned table p {
+    margin-left: 0;
+    padding-left: 0;
+}
+
+form .aligned p.help {
+    padding-left: 38px;
+}
+
+.aligned .vCheckboxLabel {
+    float: none !important;
+    display: inline;
+    padding-left: 4px;
+}
+
+.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField {
+    width: 610px;
+}
+
+.checkbox-row p.help {
+    margin-left: 0;
+    padding-left: 0 !important;
+}
+
+fieldset .field-box {
+    float: left;
+    margin-right: 20px;
+}
+
+/* WIDE FIELDSETS */
+
+.wide label {
+    width: 15em !important;
+}
+
+form .wide p {
+    margin-left: 15em;
+}
+
+form .wide p.help {
+    padding-left: 38px;
+}
+
+.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField {
+    width: 450px;
+}
+
+/* COLLAPSED FIELDSETS */
+
+fieldset.collapsed * {
+    display: none;
+}
+
+fieldset.collapsed h2, fieldset.collapsed {
+    display: block !important;
+}
+
+fieldset.collapsed h2 {
+    background-image: url(../img/admin/nav-bg.gif);
+    background-position: bottom left;
+    color: #999;
+}
+
+fieldset.collapsed .collapse-toggle {
+    background: transparent;
+    display: inline !important;
+}
+
+/* MONOSPACE TEXTAREAS */
+
+fieldset.monospace textarea {
+    font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace;
+}
+
+/* SUBMIT ROW */
+
+.submit-row {
+    padding: 5px 7px;
+    text-align: right;
+    background: white url(../img/admin/nav-bg.gif) 0 100% repeat-x;
+    border: 1px solid #ccc;
+    margin: 5px 0;
+    overflow: hidden;
+}
+
+.submit-row input {
+    margin: 0 0 0 5px;
+}
+
+.submit-row p {
+    margin: 0.3em;
+}
+
+.submit-row p.deletelink-box {
+    float: left;
+}
+
+.submit-row .deletelink {
+    background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat;
+    padding-left: 14px;
+}
+
+/* CUSTOM FORM FIELDS */
+
+.vSelectMultipleField {
+    vertical-align: top !important;
+}
+
+.vCheckboxField {
+    border: none;
+}
+
+.vDateField, .vTimeField {
+    margin-right: 2px;
+}
+
+.vURLField {
+    width: 30em;
+}
+
+.vLargeTextField, .vXMLLargeTextField {
+    width: 48em;
+}
+
+.flatpages-flatpage #id_content {
+    height: 40.2em;
+}
+
+.module table .vPositiveSmallIntegerField {
+    width: 2.2em;
+}
+
+.vTextField {
+    width: 20em;
+}
+
+.vIntegerField {
+    width: 5em;
+}
+
+.vForeignKeyRawIdAdminField {
+    width: 5em;
+}
+
+/* INLINES */
+
+.inline-group {
+    padding: 0;
+    border: 1px solid #ccc;
+    margin: 10px 0;
+}
+
+.inline-group .aligned label {
+    width: 8em;
+}
+
+.inline-related {
+    position: relative;
+}
+
+.inline-related h3 {
+    margin: 0;
+    color: #666;
+    padding: 3px 5px;
+    font-size: 11px;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
+    border-bottom: 1px solid #ddd;
+}
+
+.inline-related h3 span.delete {
+    float: right;
+}
+
+.inline-related h3 span.delete label {
+    margin-left: 2px;
+    font-size: 11px;
+}
+
+.inline-related fieldset {
+    margin: 0;
+    background: #fff;
+    border: none;
+}
+
+.inline-related fieldset.module h3 {
+    margin: 0;
+    padding: 2px 5px 3px 5px;
+    font-size: 11px;
+    text-align: left;
+    font-weight: bold;
+    background: #bcd;
+    color: #fff;
+}
+
+.inline-group .tabular fieldset.module {
+    border: none;
+    border-bottom: 1px solid #ddd;
+}
+
+.inline-related.tabular fieldset.module table {
+    width: 100%;
+}
+
+.last-related fieldset {
+    border: none;
+}
+
+.inline-group .tabular tr.has_original td {
+    padding-top: 2em;
+}
+
+.inline-group .tabular tr td.original {
+    padding: 2px 0 0 0;
+    width: 0;
+    _position: relative;
+}
+
+.inline-group .tabular th.original {
+    width: 0px;
+    padding: 0;
+}
+
+.inline-group .tabular td.original p {
+    position: absolute;
+    left: 0;
+    height: 1.1em;
+    padding: 2px 7px;
+    overflow: hidden;
+    font-size: 9px;
+    font-weight: bold;
+    color: #666;
+    _width: 700px;
+}
+
+.inline-group ul.tools {
+    padding: 0;
+    margin: 0;
+    list-style: none;
+}
+
+.inline-group ul.tools li {
+    display: inline;
+    padding: 0 5px;
+}
+
+.inline-group div.add-row,
+.inline-group .tabular tr.add-row td {
+    color: #666;
+    padding: 3px 5px;
+    border-bottom: 1px solid #ddd;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
+}
+
+.inline-group .tabular tr.add-row td {
+    padding: 4px 5px 3px;
+    border-bottom: none;
+}
+
+.inline-group ul.tools a.add,
+.inline-group div.add-row a,
+.inline-group .tabular tr.add-row td a {
+    background: url(../img/admin/icon_addlink.gif) 0 50% no-repeat;
+    padding-left: 14px;
+    font-size: 11px;
+    outline: 0; /* Remove dotted border around link */
+}
+
+.empty-form {
+    display: none;
+}
diff --git a/project/media/django/css/ie.css b/project/media/django/css/ie.css
new file mode 100644 (file)
index 0000000..5fd1ce3
--- /dev/null
@@ -0,0 +1,57 @@
+/* IE 6 & 7 */
+
+/* Proper fixed width for dashboard in IE6 */
+
+.dashboard #content {
+    *width: 768px;
+}
+
+.dashboard #content-main {
+    *width: 535px;
+}
+
+/* IE 6 ONLY */
+
+/* Keep header from flowing off the page */
+
+#container {
+    _position: static;
+}
+
+/* Put the right sidebars back on the page */
+
+.colMS #content-related {
+    _margin-right: 0;
+    _margin-left: 10px;
+    _position: static;
+}
+
+/* Put the left sidebars back on the page */
+
+.colSM #content-related {
+    _margin-right: 10px;
+    _margin-left: -115px;
+    _position: static;
+}
+
+.form-row {
+    _height: 1%;
+}
+
+/* Fix right margin for changelist filters in IE6 */
+
+#changelist-filter ul {
+    _margin-right: -10px;
+}
+
+/* IE ignores min-height, but treats height as if it were min-height */
+
+.change-list .filtered {
+    _height: 400px;
+}
+
+/* IE doesn't know alpha transparency in PNGs */
+
+.inline-deletelink {
+    background: transparent url(../img/admin/inline-delete-8bit.png) no-repeat;
+}
\ No newline at end of file
diff --git a/project/media/django/css/login.css b/project/media/django/css/login.css
new file mode 100644 (file)
index 0000000..8d90d12
--- /dev/null
@@ -0,0 +1,54 @@
+/* LOGIN FORM */
+
+body.login {
+    background: #eee;
+}
+
+.login #container {
+    background: white;
+    border: 1px solid #ccc;
+    width: 28em;
+    min-width: 300px;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 100px;
+}
+
+.login #content-main {
+    width: 100%;
+}
+
+.login form {
+    margin-top: 1em;
+}
+
+.login .form-row {
+    padding: 4px 0;
+    float: left;
+    width: 100%;
+}
+
+.login .form-row label {
+    float: left;
+    width: 9em;
+    padding-right: 0.5em;
+    line-height: 2em;
+    text-align: right;
+    font-size: 1em;
+    color: #333;
+}
+
+.login .form-row #id_username, .login .form-row #id_password {
+    width: 14em;
+}
+
+.login span.help {
+    font-size: 10px;
+    display: block;
+}
+
+.login .submit-row {
+    clear: both;
+    padding: 1em 0 0 9.4em;
+}
+
diff --git a/project/media/django/css/rtl.css b/project/media/django/css/rtl.css
new file mode 100644 (file)
index 0000000..b05537a
--- /dev/null
@@ -0,0 +1,221 @@
+body {
+    direction: rtl;
+}
+
+/* LOGIN */
+
+.login .form-row {
+    float: right;
+}
+
+.login .form-row label {
+    float: right;
+    padding-left: 0.5em;
+    padding-right: 0;
+    text-align: left;
+}
+
+.login .submit-row {
+    clear: both;
+    padding: 1em 9.4em 0 0;
+}
+
+/* GLOBAL */
+
+th {
+    text-align: right;
+}
+
+.module h2, .module caption {
+    text-align: right;
+}
+
+.addlink, .changelink {
+    padding-left: 0px;
+    padding-right: 12px;
+    background-position: 100% 0.2em;
+}
+
+.deletelink {
+    padding-left: 0px;
+    padding-right: 12px;
+    background-position: 100% 0.25em;
+}
+
+.object-tools {
+    float: left;
+}
+
+/* LAYOUT */
+
+#user-tools {
+    right: auto;
+    left: 0;
+    text-align: left;
+}
+
+div.breadcrumbs {
+    text-align: right;
+}
+
+#content-main {
+    float: right;
+}
+
+#content-related {
+    float: left;
+    margin-left: -19em;
+    margin-right: auto;
+}
+
+.colMS {
+    margin-left: 20em !important;
+    margin-right: 10px !important;
+}
+
+/* dashboard styles */
+
+.dashboard .module table td a {
+    padding-left: .6em;
+    padding-right: 12px;
+}
+
+/* changelists styles */
+
+.change-list ul.toplinks li {
+    float: right;
+}
+
+.change-list .filtered {
+    background: white url(../img/admin/changelist-bg_rtl.gif) top left repeat-y !important;
+}
+
+.change-list .filtered table {
+    border-left: 1px solid #ddd;
+    border-right: 0px none;
+}
+
+#changelist-filter {
+    right: auto;
+    left: 0;
+    border-left: 0px none;
+    border-right: 1px solid #ddd;
+}
+
+.change-list .filtered table, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
+    margin-right: 0px !important;
+    margin-left: 160px !important;
+}
+
+#changelist-filter li.selected {
+    border-left: 0px none;
+    padding-left: 0px;
+    margin-left: 0;
+    border-right: 5px solid #ccc;
+    padding-right: 5px;
+    margin-right: -10px;
+}
+
+.filtered .actions {
+    border-left:1px solid #DDDDDD;
+    margin-left:160px !important;
+    border-right: 0 none;
+    margin-right:0 !important;
+}
+
+/* FORMS */
+
+.aligned label {
+    padding: 0 0 3px 1em;
+    float: right;
+}
+
+.submit-row {
+    text-align: left
+}
+
+.submit-row p.deletelink-box {
+    float: right;
+}
+
+.submit-row .deletelink {
+    background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat;
+    padding-right: 14px;
+}
+
+.vDateField, .vTimeField {
+    margin-left: 2px;
+}
+
+form ul.inline li {
+    float: right;
+    padding-right: 0;
+    padding-left: 7px;
+}
+
+input[type=submit].default, .submit-row input.default {
+    float: left;
+}
+
+fieldset .field-box {
+    float: right;
+    margin-left: 20px;
+}
+
+.errorlist li {
+    background-position: 100% .3em;
+    padding: 4px 25px 4px 5px;
+}
+
+.errornote {
+    background-position: 100% .3em;
+    padding: 4px 25px 4px 5px;
+}
+
+/* WIDGETS */
+
+.calendarnav-previous {
+    top: 0;
+    left: auto;
+    right: 0;
+}
+
+.calendarnav-next {
+    top: 0;
+    right: auto;
+    left: 0;
+}
+
+.calendar caption, .calendarbox h2 {
+    text-align: center;
+}
+
+.selector {
+    float: right;
+}
+
+.selector .selector-filter {
+    text-align: right;
+}
+
+.inline-deletelink {
+    float: left;
+}
+
+/* MISC */
+
+.inline-related h2, .inline-group h2 {
+    text-align: right
+}
+
+.inline-related h3 span.delete {
+    padding-right: 20px;
+    padding-left: inherit;
+    left: 10px;
+    right: inherit;
+}
+
+.inline-related h3 span.delete label {
+    margin-left: inherit;
+    margin-right: 2px;
+}
diff --git a/project/media/django/css/widgets.css b/project/media/django/css/widgets.css
new file mode 100644 (file)
index 0000000..c0911ff
--- /dev/null
@@ -0,0 +1,507 @@
+/* SELECTOR (FILTER INTERFACE) */
+
+.selector {
+    width: 580px;
+    float: left;
+}
+
+.selector select {
+    width: 270px;
+    height: 17.2em;
+}
+
+.selector-available, .selector-chosen {
+    float: left;
+    width: 270px;
+    text-align: center;
+    margin-bottom: 5px;
+}
+
+.selector-available h2, .selector-chosen h2 {
+    border: 1px solid #ccc;
+}
+
+.selector .selector-available h2 {
+    background: white url(../img/admin/nav-bg.gif) bottom left repeat-x;
+    color: #666;
+}
+
+.selector .selector-filter {
+    background: white;
+    border: 1px solid #ccc;
+    border-width: 0 1px;
+    padding: 3px;
+    color: #999;
+    font-size: 10px;
+    margin: 0;
+    text-align: left;
+}
+
+.selector .selector-chosen .selector-filter {
+    padding: 4px 5px;
+}
+
+.selector .selector-available input {
+    width: 230px;
+}
+
+.selector ul.selector-chooser {
+    float: left;
+    width: 22px;
+    height: 50px;
+    background: url(../img/admin/chooser-bg.gif) top center no-repeat;
+    margin: 8em 3px 0 3px;
+    padding: 0;
+}
+
+.selector-chooser li {
+    margin: 0;
+    padding: 3px;
+    list-style-type: none;
+}
+
+.selector select {
+    margin-bottom: 5px;
+    margin-top: 0;
+}
+
+.selector-add, .selector-remove {
+    width: 16px;
+    height: 16px;
+    display: block;
+    text-indent: -3000px;
+    overflow: hidden;
+}
+
+.selector-add {
+    background: url(../img/admin/selector-add.gif) top center no-repeat;
+    margin-bottom: 2px;
+}
+
+.selector-remove {
+    background: url(../img/admin/selector-remove.gif) top center no-repeat;
+}
+
+a.selector-chooseall, a.selector-clearall {
+    display: block;
+    width: 6em;
+    text-align: left;
+    margin-left: auto;
+    margin-right: auto;
+    font-weight: bold;
+    color: #666;
+    padding: 3px 0 3px 18px;
+}
+
+a.selector-chooseall:hover, a.selector-clearall:hover {
+    color: #036;
+}
+
+a.selector-chooseall {
+    width: 7em;
+    background: url(../img/admin/selector-addall.gif) left center no-repeat;
+}
+
+a.selector-clearall {
+    background: url(../img/admin/selector-removeall.gif) left center no-repeat;
+}
+
+
+/* STACKED SELECTORS */
+
+.stacked {
+    float: left;
+    width: 500px;
+}
+
+.stacked select {
+    width: 480px;
+    height: 10.1em;
+}
+
+.stacked .selector-available, .stacked .selector-chosen {
+    width: 480px;
+}
+
+.stacked .selector-available {
+    margin-bottom: 0;
+}
+
+.stacked .selector-available input {
+    width: 442px;
+}
+
+.stacked ul.selector-chooser {
+    height: 22px;
+    width: 50px;
+    margin: 0 0 3px 40%;
+    background: url(../img/admin/chooser_stacked-bg.gif) top center no-repeat;
+}
+
+.stacked .selector-chooser li {
+    float: left;
+    padding: 3px 3px 3px 5px;
+}
+
+.stacked .selector-chooseall, .stacked .selector-clearall {
+    display: none;
+}
+
+.stacked .selector-add {
+    background-image: url(../img/admin/selector_stacked-add.gif);
+}
+
+.stacked .selector-remove {
+    background-image: url(../img/admin/selector_stacked-remove.gif);
+}
+
+
+/* DATE AND TIME */
+
+p.datetime {
+    line-height: 20px;
+    margin: 0;
+    padding: 0;
+    color: #666;
+    font-size: 11px;
+    font-weight: bold;
+}
+
+.datetime span {
+    font-size: 11px;
+    color: #ccc;
+    font-weight: normal;
+    white-space: nowrap;
+}
+
+table p.datetime {
+    font-size: 10px;
+    margin-left: 0;
+    padding-left: 0;
+}
+
+/* FILE UPLOADS */
+
+p.file-upload {
+    line-height: 20px;
+    margin: 0;
+    padding: 0;
+    color: #666;
+    font-size: 11px;
+    font-weight: bold;
+}
+
+.file-upload a {
+    font-weight: normal;
+}
+
+.file-upload .deletelink {
+    margin-left: 5px;
+}
+
+/* CALENDARS & CLOCKS */
+
+.calendarbox, .clockbox {
+    margin: 5px auto;
+    font-size: 11px;
+    width: 16em;
+    text-align: center;
+    background: white;
+    position: relative;
+}
+
+.clockbox {
+    width: auto;
+}
+
+.calendar {
+    margin: 0;
+    padding: 0;
+}
+
+.calendar table {
+    margin: 0;
+    padding: 0;
+    border-collapse: collapse;
+    background: white;
+    width: 99%;
+}
+
+.calendar caption, .calendarbox h2 {
+    margin: 0;
+    font-size: 11px;
+    text-align: center;
+    border-top: none;
+}
+
+.calendar th {
+    font-size: 10px;
+    color: #666;
+    padding: 2px 3px;
+    text-align: center;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x;
+    border-bottom: 1px solid #ddd;
+}
+
+.calendar td {
+    font-size: 11px;
+    text-align: center;
+    padding: 0;
+    border-top: 1px solid #eee;
+    border-bottom: none;
+}
+
+.calendar td.selected a {
+    background: #C9DBED;
+}
+
+.calendar td.nonday {
+    background: #efefef;
+}
+
+.calendar td.today a {
+    background: #ffc;
+}
+
+.calendar td a, .timelist a {
+    display: block;
+    font-weight: bold;
+    padding: 4px;
+    text-decoration: none;
+    color: #444;
+}
+
+.calendar td a:hover, .timelist a:hover {
+    background: #5b80b2;
+    color: white;
+}
+
+.calendar td a:active, .timelist a:active {
+    background: #036;
+    color: white;
+}
+
+.calendarnav {
+    font-size: 10px;
+    text-align: center;
+    color: #ccc;
+    margin: 0;
+    padding: 1px 3px;
+}
+
+.calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover {
+    color: #999;
+}
+
+.calendar-shortcuts {
+    background: white;
+    font-size: 10px;
+    line-height: 11px;
+    border-top: 1px solid #eee;
+    padding: 3px 0 4px;
+    color: #ccc;
+}
+
+.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
+    display: block;
+    position: absolute;
+    font-weight: bold;
+    font-size: 12px;
+    background: #C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x;
+    padding: 1px 4px 2px 4px;
+    color: white;
+}
+
+.calendarnav-previous:hover, .calendarnav-next:hover {
+    background: #036;
+}
+
+.calendarnav-previous {
+    top: 0;
+    left: 0;
+}
+
+.calendarnav-next {
+    top: 0;
+    right: 0;
+}
+
+.calendar-cancel {
+    margin: 0 !important;
+    padding: 0;
+    font-size: 10px;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x;
+    border-top: 1px solid #ddd;
+}
+
+.calendar-cancel a {
+    padding: 2px;
+    color: #999;
+}
+
+ul.timelist, .timelist li {
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+}
+
+.timelist a {
+    padding: 2px;
+}
+
+/* INLINE ORDERER */
+
+ul.orderer {
+    position: relative;
+    padding: 0 !important;
+    margin: 0 !important;
+    list-style-type: none;
+}
+
+ul.orderer li {
+    list-style-type: none;
+    display: block;
+    padding: 0;
+    margin: 0;
+    border: 1px solid #bbb;
+    border-width: 0 1px 1px 0;
+    white-space: nowrap;
+    overflow: hidden;
+    background: #e2e2e2 url(../img/admin/nav-bg-grabber.gif) repeat-y;
+}
+
+ul.orderer li:hover {
+    cursor: move;
+    background-color: #ddd;
+}
+
+ul.orderer li a.selector {
+    margin-left: 12px;
+    overflow: hidden;
+    width: 83%;
+    font-size: 10px !important;
+    padding: 0.6em 0;
+}
+
+ul.orderer li a:link, ul.orderer li a:visited {
+    color: #333;
+}
+
+ul.orderer li .inline-deletelink {
+    position: absolute;
+    right: 4px;
+    margin-top: 0.6em;
+}
+
+ul.orderer li.selected {
+    background-color: #f8f8f8;
+    border-right-color: #f8f8f8;
+}
+
+ul.orderer li.deleted {
+    background: #bbb url(../img/admin/deleted-overlay.gif);
+}
+
+ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited {
+    color: #888;
+}
+
+ul.orderer li.deleted .inline-deletelink {
+    background-image: url(../img/admin/inline-restore.png);
+}
+
+ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover {
+    cursor: default;
+}
+
+/* EDIT INLINE */
+
+.inline-deletelink {
+    float: right;
+    text-indent: -9999px;
+    background: transparent url(../img/admin/inline-delete.png) no-repeat;
+    width: 15px;
+    height: 15px;
+    border: 0px none;
+    outline: 0; /* Remove dotted border around link */
+}
+
+.inline-deletelink:hover {
+    background-position: -15px 0;
+    cursor: pointer;
+}
+
+.editinline button.addlink {
+    border: 0px none;
+    color: #5b80b2;
+    font-size: 100%;
+    cursor: pointer;
+}
+
+.editinline button.addlink:hover {
+    color: #036;
+    cursor: pointer;
+}
+
+.editinline table .help {
+    text-align: right;
+    float: right;
+    padding-left: 2em;
+}
+
+.editinline tfoot .addlink {
+    white-space: nowrap;
+}
+
+.editinline table thead th:last-child {
+    border-left: none;
+}
+
+.editinline tr.deleted {
+    background: #ddd url(../img/admin/deleted-overlay.gif);
+}
+
+.editinline tr.deleted .inline-deletelink {
+    background-image: url(../img/admin/inline-restore.png);
+}
+
+.editinline tr.deleted td:hover {
+    cursor: default;
+}
+
+.editinline tr.deleted td:first-child {
+    background-image: none !important;
+}
+
+/* EDIT INLINE - STACKED */
+
+.editinline-stacked {
+    min-width: 758px;
+}
+
+.editinline-stacked .inline-object {
+    margin-left: 210px;
+    background: white;
+}
+
+.editinline-stacked .inline-source {
+    float: left;
+    width: 200px;
+    background: #f8f8f8;
+}
+
+.editinline-stacked .inline-splitter {
+    float: left;
+    width: 9px;
+    background: #f8f8f8 url(../img/admin/inline-splitter-bg.gif) 50% 50% no-repeat;
+    border-right: 1px solid #ccc;
+}
+
+.editinline-stacked .controls {
+    clear: both;
+    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
+    padding: 3px 4px;
+    font-size: 11px;
+    border-top: 1px solid #ddd;
+}
+
diff --git a/project/media/django/img/admin/arrow-down.gif b/project/media/django/img/admin/arrow-down.gif
new file mode 100644 (file)
index 0000000..a967b9f
Binary files /dev/null and b/project/media/django/img/admin/arrow-down.gif differ
diff --git a/project/media/django/img/admin/arrow-up.gif b/project/media/django/img/admin/arrow-up.gif
new file mode 100644 (file)
index 0000000..3fe4851
Binary files /dev/null and b/project/media/django/img/admin/arrow-up.gif differ
diff --git a/project/media/django/img/admin/changelist-bg.gif b/project/media/django/img/admin/changelist-bg.gif
new file mode 100644 (file)
index 0000000..7f46994
Binary files /dev/null and b/project/media/django/img/admin/changelist-bg.gif differ
diff --git a/project/media/django/img/admin/changelist-bg_rtl.gif b/project/media/django/img/admin/changelist-bg_rtl.gif
new file mode 100644 (file)
index 0000000..2379712
Binary files /dev/null and b/project/media/django/img/admin/changelist-bg_rtl.gif differ
diff --git a/project/media/django/img/admin/chooser-bg.gif b/project/media/django/img/admin/chooser-bg.gif
new file mode 100644 (file)
index 0000000..30e83c2
Binary files /dev/null and b/project/media/django/img/admin/chooser-bg.gif differ
diff --git a/project/media/django/img/admin/chooser_stacked-bg.gif b/project/media/django/img/admin/chooser_stacked-bg.gif
new file mode 100644 (file)
index 0000000..5d104b6
Binary files /dev/null and b/project/media/django/img/admin/chooser_stacked-bg.gif differ
diff --git a/project/media/django/img/admin/default-bg-reverse.gif b/project/media/django/img/admin/default-bg-reverse.gif
new file mode 100644 (file)
index 0000000..0873281
Binary files /dev/null and b/project/media/django/img/admin/default-bg-reverse.gif differ
diff --git a/project/media/django/img/admin/default-bg.gif b/project/media/django/img/admin/default-bg.gif
new file mode 100644 (file)
index 0000000..003aeca
Binary files /dev/null and b/project/media/django/img/admin/default-bg.gif differ
diff --git a/project/media/django/img/admin/deleted-overlay.gif b/project/media/django/img/admin/deleted-overlay.gif
new file mode 100644 (file)
index 0000000..dc3828f
Binary files /dev/null and b/project/media/django/img/admin/deleted-overlay.gif differ
diff --git a/project/media/django/img/admin/icon-no.gif b/project/media/django/img/admin/icon-no.gif
new file mode 100644 (file)
index 0000000..1b4ee58
Binary files /dev/null and b/project/media/django/img/admin/icon-no.gif differ
diff --git a/project/media/django/img/admin/icon-unknown.gif b/project/media/django/img/admin/icon-unknown.gif
new file mode 100644 (file)
index 0000000..cfd2b02
Binary files /dev/null and b/project/media/django/img/admin/icon-unknown.gif differ
diff --git a/project/media/django/img/admin/icon-yes.gif b/project/media/django/img/admin/icon-yes.gif
new file mode 100644 (file)
index 0000000..7399282
Binary files /dev/null and b/project/media/django/img/admin/icon-yes.gif differ
diff --git a/project/media/django/img/admin/icon_addlink.gif b/project/media/django/img/admin/icon_addlink.gif
new file mode 100644 (file)
index 0000000..ee70e1a
Binary files /dev/null and b/project/media/django/img/admin/icon_addlink.gif differ
diff --git a/project/media/django/img/admin/icon_alert.gif b/project/media/django/img/admin/icon_alert.gif
new file mode 100644 (file)
index 0000000..a1dde26
Binary files /dev/null and b/project/media/django/img/admin/icon_alert.gif differ
diff --git a/project/media/django/img/admin/icon_calendar.gif b/project/media/django/img/admin/icon_calendar.gif
new file mode 100644 (file)
index 0000000..7587b30
Binary files /dev/null and b/project/media/django/img/admin/icon_calendar.gif differ
diff --git a/project/media/django/img/admin/icon_changelink.gif b/project/media/django/img/admin/icon_changelink.gif
new file mode 100644 (file)
index 0000000..e1b9afd
Binary files /dev/null and b/project/media/django/img/admin/icon_changelink.gif differ
diff --git a/project/media/django/img/admin/icon_clock.gif b/project/media/django/img/admin/icon_clock.gif
new file mode 100644 (file)
index 0000000..ff2d57e
Binary files /dev/null and b/project/media/django/img/admin/icon_clock.gif differ
diff --git a/project/media/django/img/admin/icon_deletelink.gif b/project/media/django/img/admin/icon_deletelink.gif
new file mode 100644 (file)
index 0000000..72523e3
Binary files /dev/null and b/project/media/django/img/admin/icon_deletelink.gif differ
diff --git a/project/media/django/img/admin/icon_error.gif b/project/media/django/img/admin/icon_error.gif
new file mode 100644 (file)
index 0000000..3730a00
Binary files /dev/null and b/project/media/django/img/admin/icon_error.gif differ
diff --git a/project/media/django/img/admin/icon_searchbox.png b/project/media/django/img/admin/icon_searchbox.png
new file mode 100644 (file)
index 0000000..8ab579e
Binary files /dev/null and b/project/media/django/img/admin/icon_searchbox.png differ
diff --git a/project/media/django/img/admin/icon_success.gif b/project/media/django/img/admin/icon_success.gif
new file mode 100644 (file)
index 0000000..5cf90a1
Binary files /dev/null and b/project/media/django/img/admin/icon_success.gif differ
diff --git a/project/media/django/img/admin/inline-delete-8bit.png b/project/media/django/img/admin/inline-delete-8bit.png
new file mode 100644 (file)
index 0000000..95caf59
Binary files /dev/null and b/project/media/django/img/admin/inline-delete-8bit.png differ
diff --git a/project/media/django/img/admin/inline-delete.png b/project/media/django/img/admin/inline-delete.png
new file mode 100644 (file)
index 0000000..d59bcd2
Binary files /dev/null and b/project/media/django/img/admin/inline-delete.png differ
diff --git a/project/media/django/img/admin/inline-restore-8bit.png b/project/media/django/img/admin/inline-restore-8bit.png
new file mode 100644 (file)
index 0000000..e087c8e
Binary files /dev/null and b/project/media/django/img/admin/inline-restore-8bit.png differ
diff --git a/project/media/django/img/admin/inline-restore.png b/project/media/django/img/admin/inline-restore.png
new file mode 100644 (file)
index 0000000..efdd92a
Binary files /dev/null and b/project/media/django/img/admin/inline-restore.png differ
diff --git a/project/media/django/img/admin/inline-splitter-bg.gif b/project/media/django/img/admin/inline-splitter-bg.gif
new file mode 100644 (file)
index 0000000..32ac5b3
Binary files /dev/null and b/project/media/django/img/admin/inline-splitter-bg.gif differ
diff --git a/project/media/django/img/admin/nav-bg-grabber.gif b/project/media/django/img/admin/nav-bg-grabber.gif
new file mode 100644 (file)
index 0000000..0a784fa
Binary files /dev/null and b/project/media/django/img/admin/nav-bg-grabber.gif differ
diff --git a/project/media/django/img/admin/nav-bg-reverse.gif b/project/media/django/img/admin/nav-bg-reverse.gif
new file mode 100644 (file)
index 0000000..f11029f
Binary files /dev/null and b/project/media/django/img/admin/nav-bg-reverse.gif differ
diff --git a/project/media/django/img/admin/nav-bg.gif b/project/media/django/img/admin/nav-bg.gif
new file mode 100644 (file)
index 0000000..f8402b8
Binary files /dev/null and b/project/media/django/img/admin/nav-bg.gif differ
diff --git a/project/media/django/img/admin/selector-add.gif b/project/media/django/img/admin/selector-add.gif
new file mode 100644 (file)
index 0000000..50132d1
Binary files /dev/null and b/project/media/django/img/admin/selector-add.gif differ
diff --git a/project/media/django/img/admin/selector-addall.gif b/project/media/django/img/admin/selector-addall.gif
new file mode 100644 (file)
index 0000000..d6e7c63
Binary files /dev/null and b/project/media/django/img/admin/selector-addall.gif differ
diff --git a/project/media/django/img/admin/selector-remove.gif b/project/media/django/img/admin/selector-remove.gif
new file mode 100644 (file)
index 0000000..2b9b0a2
Binary files /dev/null and b/project/media/django/img/admin/selector-remove.gif differ
diff --git a/project/media/django/img/admin/selector-removeall.gif b/project/media/django/img/admin/selector-removeall.gif
new file mode 100644 (file)
index 0000000..5a44219
Binary files /dev/null and b/project/media/django/img/admin/selector-removeall.gif differ
diff --git a/project/media/django/img/admin/selector-search.gif b/project/media/django/img/admin/selector-search.gif
new file mode 100644 (file)
index 0000000..6d5f4c7
Binary files /dev/null and b/project/media/django/img/admin/selector-search.gif differ
diff --git a/project/media/django/img/admin/selector_stacked-add.gif b/project/media/django/img/admin/selector_stacked-add.gif
new file mode 100644 (file)
index 0000000..7426169
Binary files /dev/null and b/project/media/django/img/admin/selector_stacked-add.gif differ
diff --git a/project/media/django/img/admin/selector_stacked-remove.gif b/project/media/django/img/admin/selector_stacked-remove.gif
new file mode 100644 (file)
index 0000000..60412ce
Binary files /dev/null and b/project/media/django/img/admin/selector_stacked-remove.gif differ
diff --git a/project/media/django/img/admin/tool-left.gif b/project/media/django/img/admin/tool-left.gif
new file mode 100644 (file)
index 0000000..011490f
Binary files /dev/null and b/project/media/django/img/admin/tool-left.gif differ
diff --git a/project/media/django/img/admin/tool-left_over.gif b/project/media/django/img/admin/tool-left_over.gif
new file mode 100644 (file)
index 0000000..937e07b
Binary files /dev/null and b/project/media/django/img/admin/tool-left_over.gif differ
diff --git a/project/media/django/img/admin/tool-right.gif b/project/media/django/img/admin/tool-right.gif
new file mode 100644 (file)
index 0000000..cdc140c
Binary files /dev/null and b/project/media/django/img/admin/tool-right.gif differ
diff --git a/project/media/django/img/admin/tool-right_over.gif b/project/media/django/img/admin/tool-right_over.gif
new file mode 100644 (file)
index 0000000..4db977e
Binary files /dev/null and b/project/media/django/img/admin/tool-right_over.gif differ
diff --git a/project/media/django/img/admin/tooltag-add.gif b/project/media/django/img/admin/tooltag-add.gif
new file mode 100644 (file)
index 0000000..8b53d49
Binary files /dev/null and b/project/media/django/img/admin/tooltag-add.gif differ
diff --git a/project/media/django/img/admin/tooltag-add_over.gif b/project/media/django/img/admin/tooltag-add_over.gif
new file mode 100644 (file)
index 0000000..bfc52f1
Binary files /dev/null and b/project/media/django/img/admin/tooltag-add_over.gif differ
diff --git a/project/media/django/img/admin/tooltag-arrowright.gif b/project/media/django/img/admin/tooltag-arrowright.gif
new file mode 100644 (file)
index 0000000..cdaaae7
Binary files /dev/null and b/project/media/django/img/admin/tooltag-arrowright.gif differ
diff --git a/project/media/django/img/admin/tooltag-arrowright_over.gif b/project/media/django/img/admin/tooltag-arrowright_over.gif
new file mode 100644 (file)
index 0000000..7163189
Binary files /dev/null and b/project/media/django/img/admin/tooltag-arrowright_over.gif differ
diff --git a/project/media/django/img/gis/move_vertex_off.png b/project/media/django/img/gis/move_vertex_off.png
new file mode 100644 (file)
index 0000000..296b2e2
Binary files /dev/null and b/project/media/django/img/gis/move_vertex_off.png differ
diff --git a/project/media/django/img/gis/move_vertex_on.png b/project/media/django/img/gis/move_vertex_on.png
new file mode 100644 (file)
index 0000000..21f4758
Binary files /dev/null and b/project/media/django/img/gis/move_vertex_on.png differ
diff --git a/project/media/django/js/LICENSE-JQUERY.txt b/project/media/django/js/LICENSE-JQUERY.txt
new file mode 100644 (file)
index 0000000..a4c5bd7
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2010 John Resig, http://jquery.com/
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/project/media/django/js/SelectBox.js b/project/media/django/js/SelectBox.js
new file mode 100644 (file)
index 0000000..f28c861
--- /dev/null
@@ -0,0 +1,111 @@
+var SelectBox = {
+    cache: new Object(),
+    init: function(id) {
+        var box = document.getElementById(id);
+        var node;
+        SelectBox.cache[id] = new Array();
+        var cache = SelectBox.cache[id];
+        for (var i = 0; (node = box.options[i]); i++) {
+            cache.push({value: node.value, text: node.text, displayed: 1});
+        }
+    },
+    redisplay: function(id) {
+        // Repopulate HTML select box from cache
+        var box = document.getElementById(id);
+        box.options.length = 0; // clear all options
+        for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) {
+            var node = SelectBox.cache[id][i];
+            if (node.displayed) {
+                box.options[box.options.length] = new Option(node.text, node.value, false, false);
+            }
+        }
+    },
+    filter: function(id, text) {
+        // Redisplay the HTML select box, displaying only the choices containing ALL
+        // the words in text. (It's an AND search.)
+        var tokens = text.toLowerCase().split(/\s+/);
+        var node, token;
+        for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
+            node.displayed = 1;
+            for (var j = 0; (token = tokens[j]); j++) {
+                if (node.text.toLowerCase().indexOf(token) == -1) {
+                    node.displayed = 0;
+                }
+            }
+        }
+        SelectBox.redisplay(id);
+    },
+    delete_from_cache: function(id, value) {
+        var node, delete_index = null;
+        for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
+            if (node.value == value) {
+                delete_index = i;
+                break;
+            }
+        }
+        var j = SelectBox.cache[id].length - 1;
+        for (var i = delete_index; i < j; i++) {
+            SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
+        }
+        SelectBox.cache[id].length--;
+    },
+    add_to_cache: function(id, option) {
+        SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});
+    },
+    cache_contains: function(id, value) {
+        // Check if an item is contained in the cache
+        var node;
+        for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
+            if (node.value == value) {
+                return true;
+            }
+        }
+        return false;
+    },
+    move: function(from, to) {
+        var from_box = document.getElementById(from);
+        var to_box = document.getElementById(to);
+        var option;
+        for (var i = 0; (option = from_box.options[i]); i++) {
+            if (option.selected && SelectBox.cache_contains(from, option.value)) {
+                SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1});
+                SelectBox.delete_from_cache(from, option.value);
+            }
+        }
+        SelectBox.redisplay(from);
+        SelectBox.redisplay(to);
+    },
+    move_all: function(from, to) {
+        var from_box = document.getElementById(from);
+        var to_box = document.getElementById(to);
+        var option;
+        for (var i = 0; (option = from_box.options[i]); i++) {
+            if (SelectBox.cache_contains(from, option.value)) {
+                SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1});
+                SelectBox.delete_from_cache(from, option.value);
+            }
+        }
+        SelectBox.redisplay(from);
+        SelectBox.redisplay(to);
+    },
+    sort: function(id) {
+        SelectBox.cache[id].sort( function(a, b) {
+            a = a.text.toLowerCase();
+            b = b.text.toLowerCase();
+            try {
+                if (a > b) return 1;
+                if (a < b) return -1;
+            }
+            catch (e) {
+                // silently fail on IE 'unknown' exception
+            }
+            return 0;
+        } );
+    },
+    select_all: function(id) {
+        var box = document.getElementById(id);
+        for (var i = 0; i < box.options.length; i++) {
+            box.options[i].selected = 'selected';
+        }
+    }
+}
diff --git a/project/media/django/js/SelectFilter2.js b/project/media/django/js/SelectFilter2.js
new file mode 100644 (file)
index 0000000..5a03447
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+SelectFilter2 - Turns a multiple-select box into a filter interface.
+
+Different than SelectFilter because this is coupled to the admin framework.
+
+Requires core.js, SelectBox.js and addevent.js.
+*/
+
+function findForm(node) {
+    // returns the node of the form containing the given node
+    if (node.tagName.toLowerCase() != 'form') {
+        return findForm(node.parentNode);
+    }
+    return node;
+}
+
+var SelectFilter = {
+    init: function(field_id, field_name, is_stacked, admin_media_prefix) {
+        if (field_id.match(/__prefix__/)){
+            // Don't intialize on empty forms.
+            return;
+        }
+        var from_box = document.getElementById(field_id);
+        from_box.id += '_from'; // change its ID
+        from_box.className = 'filtered';
+
+        // Remove <p class="info">, because it just gets in the way.
+        var ps = from_box.parentNode.getElementsByTagName('p');
+        for (var i=0; i<ps.length; i++) {
+            from_box.parentNode.removeChild(ps[i]);
+        }
+
+        // <div class="selector"> or <div class="selector stacked">
+        var selector_div = quickElement('div', from_box.parentNode);
+        selector_div.className = is_stacked ? 'selector stacked' : 'selector';
+
+        // <div class="selector-available">
+        var selector_available = quickElement('div', selector_div, '');
+        selector_available.className = 'selector-available';
+        quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name]));
+        var filter_p = quickElement('p', selector_available, '');
+        filter_p.className = 'selector-filter';
+        quickElement('img', filter_p, '', 'src', admin_media_prefix + 'img/admin/selector-search.gif');
+        filter_p.appendChild(document.createTextNode(' '));
+        var filter_input = quickElement('input', filter_p, '', 'type', 'text');
+        filter_input.id = field_id + '_input';
+        selector_available.appendChild(from_box);
+        var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
+        choose_all.className = 'selector-chooseall';
+
+        // <ul class="selector-chooser">
+        var selector_chooser = quickElement('ul', selector_div, '');
+        selector_chooser.className = 'selector-chooser';
+        var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
+        add_link.className = 'selector-add';
+        var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
+        remove_link.className = 'selector-remove';
+
+        // <div class="selector-chosen">
+        var selector_chosen = quickElement('div', selector_div, '');
+        selector_chosen.className = 'selector-chosen';
+        quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
+        var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
+        selector_filter.className = 'selector-filter';
+        quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add');
+        var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
+        to_box.className = 'filtered';
+        var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
+        clear_all.className = 'selector-clearall';
+
+        from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
+
+        // Set up the JavaScript event handlers for the select box filter interface
+        addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
+        addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
+        addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
+        addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
+        addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
+        SelectBox.init(field_id + '_from');
+        SelectBox.init(field_id + '_to');
+        // Move selected from_box options to to_box
+        SelectBox.move(field_id + '_from', field_id + '_to');
+    },
+    filter_key_up: function(event, field_id) {
+        from = document.getElementById(field_id + '_from');
+        // don't submit form if user pressed Enter
+        if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
+            from.selectedIndex = 0;
+            SelectBox.move(field_id + '_from', field_id + '_to');
+            from.selectedIndex = 0;
+            return false;
+        }
+        var temp = from.selectedIndex;
+        SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
+        from.selectedIndex = temp;
+        return true;
+    },
+    filter_key_down: function(event, field_id) {
+        from = document.getElementById(field_id + '_from');
+        // right arrow -- move across
+        if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
+            var old_index = from.selectedIndex;
+            SelectBox.move(field_id + '_from', field_id + '_to');
+            from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index;
+            return false;
+        }
+        // down arrow -- wrap around
+        if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) {
+            from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
+        }
+        // up arrow -- wrap around
+        if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) {
+            from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1;
+        }
+        return true;
+    }
+}
diff --git a/project/media/django/js/actions.js b/project/media/django/js/actions.js
new file mode 100644 (file)
index 0000000..94aa6db
--- /dev/null
@@ -0,0 +1,139 @@
+(function($) {
+       $.fn.actions = function(opts) {
+               var options = $.extend({}, $.fn.actions.defaults, opts);
+               var actionCheckboxes = $(this);
+               var list_editable_changed = false;
+               checker = function(checked) {
+                       if (checked) {
+                               showQuestion();
+                       } else {
+                               reset();
+                       }
+                       $(actionCheckboxes).attr("checked", checked)
+                               .parent().parent().toggleClass(options.selectedClass, checked);
+               }
+               updateCounter = function() {
+                       var sel = $(actionCheckboxes).filter(":checked").length;
+                       $(options.counterContainer).html(interpolate(
+                       ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
+                               sel: sel,
+                               cnt: _actions_icnt
+                       }, true));
+                       $(options.allToggle).attr("checked", function() {
+                               if (sel == actionCheckboxes.length) {
+                                       value = true;
+                                       showQuestion();
+                               } else {
+                                       value = false;
+                                       clearAcross();
+                               }
+                               return value;
+                       });
+               }
+               showQuestion = function() {
+                       $(options.acrossClears).hide();
+                       $(options.acrossQuestions).show();
+                       $(options.allContainer).hide();
+               }
+               showClear = function() {
+                       $(options.acrossClears).show();
+                       $(options.acrossQuestions).hide();
+                       $(options.actionContainer).toggleClass(options.selectedClass);
+                       $(options.allContainer).show();
+                       $(options.counterContainer).hide();
+               }
+               reset = function() {
+                       $(options.acrossClears).hide();
+                       $(options.acrossQuestions).hide();
+                       $(options.allContainer).hide();
+                       $(options.counterContainer).show();
+               }
+               clearAcross = function() {
+                       reset();
+                       $(options.acrossInput).val(0);
+                       $(options.actionContainer).removeClass(options.selectedClass);
+               }
+               // Show counter by default
+               $(options.counterContainer).show();
+               // Check state of checkboxes and reinit state if needed
+               $(this).filter(":checked").each(function(i) {
+                       $(this).parent().parent().toggleClass(options.selectedClass);
+                       updateCounter();
+                       if ($(options.acrossInput).val() == 1) {
+                               showClear();
+                       }
+               });
+               $(options.allToggle).show().click(function() {
+                       checker($(this).attr("checked"));
+                       updateCounter();
+               });
+               $("div.actions span.question a").click(function(event) {
+                       event.preventDefault();
+                       $(options.acrossInput).val(1);
+                       showClear();
+               });
+               $("div.actions span.clear a").click(function(event) {
+                       event.preventDefault();
+                       $(options.allToggle).attr("checked", false);
+                       clearAcross();
+                       checker(0);
+                       updateCounter();
+               });
+               lastChecked = null;
+               $(actionCheckboxes).click(function(event) {
+                       if (!event) { var event = window.event; }
+                       var target = event.target ? event.target : event.srcElement;
+                       if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey == true) {
+                               var inrange = false;
+                               $(lastChecked).attr("checked", target.checked)
+                                       .parent().parent().toggleClass(options.selectedClass, target.checked);
+                               $(actionCheckboxes).each(function() {
+                                       if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) {
+                                               inrange = (inrange) ? false : true;
+                                       }
+                                       if (inrange) {
+                                               $(this).attr("checked", target.checked)
+                                                       .parent().parent().toggleClass(options.selectedClass, target.checked);
+                                       }
+                               });
+                       }
+                       $(target).parent().parent().toggleClass(options.selectedClass, target.checked);
+                       lastChecked = target;
+                       updateCounter();
+               });
+               $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
+                       list_editable_changed = true;
+               });
+               $('form#changelist-form button[name="index"]').click(function(event) {
+                       if (list_editable_changed) {
+                               return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
+                       }
+               });
+               $('form#changelist-form input[name="_save"]').click(function(event) {
+                       var action_changed = false;
+                       $('div.actions select option:selected').each(function() {
+                               if ($(this).val()) {
+                                       action_changed = true;
+                               }
+                       });
+                       if (action_changed) {
+                               if (list_editable_changed) {
+                                       return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
+                               } else {
+                                       return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
+                               }
+                       }
+               });
+       }
+       /* Setup plugin defaults */
+       $.fn.actions.defaults = {
+               actionContainer: "div.actions",
+               counterContainer: "span.action-counter",
+               allContainer: "div.actions span.all",
+               acrossInput: "div.actions input.select-across",
+               acrossQuestions: "div.actions span.question",
+               acrossClears: "div.actions span.clear",
+               allToggle: "#action-toggle",
+               selectedClass: "selected"
+       }
+})(django.jQuery);
diff --git a/project/media/django/js/actions.min.js b/project/media/django/js/actions.min.js
new file mode 100644 (file)
index 0000000..21f00cd
--- /dev/null
@@ -0,0 +1,7 @@
+(function(a){a.fn.actions=function(h){var b=a.extend({},a.fn.actions.defaults,h),e=a(this),f=false;checker=function(c){c?showQuestion():reset();a(e).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(e).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},true));a(b.allToggle).attr("checked",function(){if(c==e.length){value=true;showQuestion()}else{value=
+false;clearAcross()}return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};
+a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();a(b.acrossInput).val()==1&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",false);clearAcross();checker(0);
+updateCounter()});lastChecked=null;a(e).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&c.shiftKey==true){var g=false;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(e).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))g=g?false:true;g&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,
+d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){f=true});a('form#changelist-form button[name="index"]').click(function(){if(f)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var c=false;a("div.actions select option:selected").each(function(){if(a(this).val())c=
+true});if(c)return f?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",
+acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
diff --git a/project/media/django/js/admin/DateTimeShortcuts.js b/project/media/django/js/admin/DateTimeShortcuts.js
new file mode 100644 (file)
index 0000000..a4293b3
--- /dev/null
@@ -0,0 +1,274 @@
+// Inserts shortcut buttons after all of the following:
+//     <input type="text" class="vDateField">
+//     <input type="text" class="vTimeField">
+
+var DateTimeShortcuts = {
+    calendars: [],
+    calendarInputs: [],
+    clockInputs: [],
+    calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
+    calendarDivName2: 'calendarin',  // name of <div> that contains calendar
+    calendarLinkName: 'calendarlink',// name of the link that is used to toggle
+    clockDivName: 'clockbox',        // name of clock <div> that gets toggled
+    clockLinkName: 'clocklink',      // name of the link that is used to toggle
+    shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
+    admin_media_prefix: '',
+    init: function() {
+        // Get admin_media_prefix by grabbing it off the window object. It's
+        // set in the admin/base.html template, so if it's not there, someone's
+        // overridden the template. In that case, we'll set a clearly-invalid
+        // value in the hopes that someone will examine HTTP requests and see it.
+        if (window.__admin_media_prefix__ != undefined) {
+            DateTimeShortcuts.admin_media_prefix = window.__admin_media_prefix__;
+        } else {
+            DateTimeShortcuts.admin_media_prefix = '/missing-admin-media-prefix/';
+        }
+
+        var inputs = document.getElementsByTagName('input');
+        for (i=0; i<inputs.length; i++) {
+            var inp = inputs[i];
+            if (inp.getAttribute('type') == 'text' && inp.className.match(/vTimeField/)) {
+                DateTimeShortcuts.addClock(inp);
+            }
+            else if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) {
+                DateTimeShortcuts.addCalendar(inp);
+            }
+        }
+    },
+    // Add clock widget to a given field
+    addClock: function(inp) {
+        var num = DateTimeShortcuts.clockInputs.length;
+        DateTimeShortcuts.clockInputs[num] = inp;
+
+        // Shortcut links (clock icon and "Now" link)
+        var shortcuts_span = document.createElement('span');
+        shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
+        inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
+        var now_link = document.createElement('a');
+        now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + get_format('TIME_INPUT_FORMATS')[0] + "'));");
+        now_link.appendChild(document.createTextNode(gettext('Now')));
+        var clock_link = document.createElement('a');
+        clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
+        clock_link.id = DateTimeShortcuts.clockLinkName + num;
+        quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_clock.gif', 'alt', gettext('Clock'));
+        shortcuts_span.appendChild(document.createTextNode('\240'));
+        shortcuts_span.appendChild(now_link);
+        shortcuts_span.appendChild(document.createTextNode('\240|\240'));
+        shortcuts_span.appendChild(clock_link);
+
+        // Create clock link div
+        //
+        // Markup looks like:
+        // <div id="clockbox1" class="clockbox module">
+        //     <h2>Choose a time</h2>
+        //     <ul class="timelist">
+        //         <li><a href="#">Now</a></li>
+        //         <li><a href="#">Midnight</a></li>
+        //         <li><a href="#">6 a.m.</a></li>
+        //         <li><a href="#">Noon</a></li>
+        //     </ul>
+        //     <p class="calendar-cancel"><a href="#">Cancel</a></p>
+        // </div>
+
+        var clock_box = document.createElement('div');
+        clock_box.style.display = 'none';
+        clock_box.style.position = 'absolute';
+        clock_box.className = 'clockbox module';
+        clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);
+        document.body.appendChild(clock_box);
+        addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation);
+
+        quickElement('h2', clock_box, gettext('Choose a time'));
+        time_list = quickElement('ul', clock_box, '');
+        time_list.className = 'timelist';
+        time_format = get_format('TIME_INPUT_FORMATS')[0];
+        quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));");
+        quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));");
+        quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));");
+        quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));");
+
+        cancel_p = quickElement('p', clock_box, '');
+        cancel_p.className = 'calendar-cancel';
+        quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
+    },
+    openClock: function(num) {
+        var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num)
+        var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num)
+
+        // Recalculate the clockbox position
+        // is it left-to-right or right-to-left layout ?
+        if (getStyle(document.body,'direction')!='rtl') {
+            clock_box.style.left = findPosX(clock_link) + 17 + 'px';
+        }
+        else {
+            // since style's width is in em, it'd be tough to calculate
+            // px value of it. let's use an estimated px for now
+            // TODO: IE returns wrong value for findPosX when in rtl mode
+            //       (it returns as it was left aligned), needs to be fixed.
+            clock_box.style.left = findPosX(clock_link) - 110 + 'px';
+        }
+        clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px';
+
+        // Show the clock box
+        clock_box.style.display = 'block';
+        addEvent(window.document, 'click', function() { DateTimeShortcuts.dismissClock(num); return true; });
+    },
+    dismissClock: function(num) {
+       document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
+       window.document.onclick = null;
+    },
+    handleClockQuicklink: function(num, val) {
+       DateTimeShortcuts.clockInputs[num].value = val;
+       DateTimeShortcuts.clockInputs[num].focus();
+       DateTimeShortcuts.dismissClock(num);
+    },
+    // Add calendar widget to a given field.
+    addCalendar: function(inp) {
+        var num = DateTimeShortcuts.calendars.length;
+
+        DateTimeShortcuts.calendarInputs[num] = inp;
+
+        // Shortcut links (calendar icon and "Today" link)
+        var shortcuts_span = document.createElement('span');
+        shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
+        inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
+        var today_link = document.createElement('a');
+        today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
+        today_link.appendChild(document.createTextNode(gettext('Today')));
+        var cal_link = document.createElement('a');
+        cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');');
+        cal_link.id = DateTimeShortcuts.calendarLinkName + num;
+        quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_calendar.gif', 'alt', gettext('Calendar'));
+        shortcuts_span.appendChild(document.createTextNode('\240'));
+        shortcuts_span.appendChild(today_link);
+        shortcuts_span.appendChild(document.createTextNode('\240|\240'));
+        shortcuts_span.appendChild(cal_link);
+
+        // Create calendarbox div.
+        //
+        // Markup looks like:
+        //
+        // <div id="calendarbox3" class="calendarbox module">
+        //     <h2>
+        //           <a href="#" class="link-previous">&lsaquo;</a>
+        //           <a href="#" class="link-next">&rsaquo;</a> February 2003
+        //     </h2>
+        //     <div class="calendar" id="calendarin3">
+        //         <!-- (cal) -->
+        //     </div>
+        //     <div class="calendar-shortcuts">
+        //          <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
+        //     </div>
+        //     <p class="calendar-cancel"><a href="#">Cancel</a></p>
+        // </div>
+        var cal_box = document.createElement('div');
+        cal_box.style.display = 'none';
+        cal_box.style.position = 'absolute';
+        cal_box.className = 'calendarbox module';
+        cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);
+        document.body.appendChild(cal_box);
+        addEvent(cal_box, 'click', DateTimeShortcuts.cancelEventPropagation);
+
+        // next-prev links
+        var cal_nav = quickElement('div', cal_box, '');
+        var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev('+num+');');
+        cal_nav_prev.className = 'calendarnav-previous';
+        var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');');
+        cal_nav_next.className = 'calendarnav-next';
+
+        // main box
+        var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
+        cal_main.className = 'calendar';
+        DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
+        DateTimeShortcuts.calendars[num].drawCurrent();
+
+        // calendar shortcuts
+        var shortcuts = quickElement('div', cal_box, '');
+        shortcuts.className = 'calendar-shortcuts';
+        quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);');
+        shortcuts.appendChild(document.createTextNode('\240|\240'));
+        quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);');
+        shortcuts.appendChild(document.createTextNode('\240|\240'));
+        quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);');
+
+        // cancel bar
+        var cancel_p = quickElement('p', cal_box, '');
+        cancel_p.className = 'calendar-cancel';
+        quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
+    },
+    openCalendar: function(num) {
+        var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
+        var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
+        var inp = DateTimeShortcuts.calendarInputs[num];
+
+        // Determine if the current value in the input has a valid date.
+        // If so, draw the calendar with that date's year and month.
+        if (inp.value) {
+            var date_parts = inp.value.split('-');
+            var year = date_parts[0];
+            var month = parseFloat(date_parts[1]);
+            if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
+                DateTimeShortcuts.calendars[num].drawDate(month, year);
+            }
+        }
+
+        // Recalculate the clockbox position
+        // is it left-to-right or right-to-left layout ?
+        if (getStyle(document.body,'direction')!='rtl') {
+            cal_box.style.left = findPosX(cal_link) + 17 + 'px';
+        }
+        else {
+            // since style's width is in em, it'd be tough to calculate
+            // px value of it. let's use an estimated px for now
+            // TODO: IE returns wrong value for findPosX when in rtl mode
+            //       (it returns as it was left aligned), needs to be fixed.
+            cal_box.style.left = findPosX(cal_link) - 180 + 'px';
+        }
+        cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px';
+
+        cal_box.style.display = 'block';
+        addEvent(window.document, 'click', function() { DateTimeShortcuts.dismissCalendar(num); return true; });
+    },
+    dismissCalendar: function(num) {
+        document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'none';
+        window.document.onclick = null;
+    },
+    drawPrev: function(num) {
+        DateTimeShortcuts.calendars[num].drawPreviousMonth();
+    },
+    drawNext: function(num) {
+        DateTimeShortcuts.calendars[num].drawNextMonth();
+    },
+    handleCalendarCallback: function(num) {
+        format = get_format('DATE_INPUT_FORMATS')[0];
+        // the format needs to be escaped a little
+        format = format.replace('\\', '\\\\');
+        format = format.replace('\r', '\\r');
+        format = format.replace('\n', '\\n');
+        format = format.replace('\t', '\\t');
+        format = format.replace("'", "\\'");
+        return ["function(y, m, d) { DateTimeShortcuts.calendarInputs[",
+               num,
+               "].value = new Date(y, m-1, d).strftime('",
+               format,
+               "');DateTimeShortcuts.calendarInputs[",
+               num,
+               "].focus();document.getElementById(DateTimeShortcuts.calendarDivName1+",
+               num,
+               ").style.display='none';}"].join('');
+    },
+    handleCalendarQuickLink: function(num, offset) {
+       var d = new Date();
+       d.setDate(d.getDate() + offset)
+       DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
+       DateTimeShortcuts.calendarInputs[num].focus();
+       DateTimeShortcuts.dismissCalendar(num);
+    },
+    cancelEventPropagation: function(e) {
+        if (!e) e = window.event;
+        e.cancelBubble = true;
+        if (e.stopPropagation) e.stopPropagation();
+    }
+}
+
+addEvent(window, 'load', DateTimeShortcuts.init);
diff --git a/project/media/django/js/admin/RelatedObjectLookups.js b/project/media/django/js/admin/RelatedObjectLookups.js
new file mode 100644 (file)
index 0000000..1bc78f8
--- /dev/null
@@ -0,0 +1,96 @@
+// Handles related-objects functionality: lookup link for raw_id_fields
+// and Add Another links.
+
+function html_unescape(text) {
+    // Unescape a string that was escaped using django.utils.html.escape.
+    text = text.replace(/&lt;/g, '<');
+    text = text.replace(/&gt;/g, '>');
+    text = text.replace(/&quot;/g, '"');
+    text = text.replace(/&#39;/g, "'");
+    text = text.replace(/&amp;/g, '&');
+    return text;
+}
+
+// IE doesn't accept periods or dashes in the window name, but the element IDs
+// we use to generate popup window names may contain them, therefore we map them
+// to allowed characters in a reversible way so that we can locate the correct 
+// element when the popup window is dismissed.
+function id_to_windowname(text) {
+    text = text.replace(/\./g, '__dot__');
+    text = text.replace(/\-/g, '__dash__');
+    return text;
+}
+
+function windowname_to_id(text) {
+    text = text.replace(/__dot__/g, '.');
+    text = text.replace(/__dash__/g, '-');
+    return text;
+}
+
+function showRelatedObjectLookupPopup(triggeringLink) {
+    var name = triggeringLink.id.replace(/^lookup_/, '');
+    name = id_to_windowname(name);
+    var href;
+    if (triggeringLink.href.search(/\?/) >= 0) {
+        href = triggeringLink.href + '&pop=1';
+    } else {
+        href = triggeringLink.href + '?pop=1';
+    }
+    var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
+    win.focus();
+    return false;
+}
+
+function dismissRelatedLookupPopup(win, chosenId) {
+    var name = windowname_to_id(win.name);
+    var elem = document.getElementById(name);
+    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
+        elem.value += ',' + chosenId;
+    } else {
+        document.getElementById(name).value = chosenId;
+    }
+    win.close();
+}
+
+function showAddAnotherPopup(triggeringLink) {
+    var name = triggeringLink.id.replace(/^add_/, '');
+    name = id_to_windowname(name);
+    href = triggeringLink.href
+    if (href.indexOf('?') == -1) {
+        href += '?_popup=1';
+    } else {
+        href  += '&_popup=1';
+    }
+    var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
+    win.focus();
+    return false;
+}
+
+function dismissAddAnotherPopup(win, newId, newRepr) {
+    // newId and newRepr are expected to have previously been escaped by
+    // django.utils.html.escape.
+    newId = html_unescape(newId);
+    newRepr = html_unescape(newRepr);
+    var name = windowname_to_id(win.name);
+    var elem = document.getElementById(name);
+    if (elem) {
+        if (elem.nodeName == 'SELECT') {
+            var o = new Option(newRepr, newId);
+            elem.options[elem.options.length] = o;
+            o.selected = true;
+        } else if (elem.nodeName == 'INPUT') {
+            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
+                elem.value += ',' + newId;
+            } else {
+                elem.value = newId;
+            }
+        }
+    } else {
+        var toId = name + "_to";
+        elem = document.getElementById(toId);
+        var o = new Option(newRepr, newId);
+        SelectBox.add_to_cache(toId, o);
+        SelectBox.redisplay(toId);
+    }
+    win.close();
+}
diff --git a/project/media/django/js/admin/ordering.js b/project/media/django/js/admin/ordering.js
new file mode 100644 (file)
index 0000000..53c42f3
--- /dev/null
@@ -0,0 +1,137 @@
+addEvent(window, 'load', reorder_init);
+
+var lis;
+var top = 0;
+var left = 0;
+var height = 30;
+
+function reorder_init() {
+    lis = document.getElementsBySelector('ul#orderthese li');
+    var input = document.getElementsBySelector('input[name=order_]')[0];
+    setOrder(input.value.split(','));
+    input.disabled = true;
+    draw();
+    // Now initialise the dragging behaviour
+    var limit = (lis.length - 1) * height;
+    for (var i = 0; i < lis.length; i++) {
+        var li = lis[i];
+        var img = document.getElementById('handle'+li.id);
+        li.style.zIndex = 1;
+        Drag.init(img, li, left + 10, left + 10, top + 10, top + 10 + limit);
+        li.onDragStart = startDrag;
+        li.onDragEnd = endDrag;
+        img.style.cursor = 'move';
+    }
+}
+
+function submitOrderForm() {
+    var inputOrder = document.getElementsBySelector('input[name=order_]')[0];
+    inputOrder.value = getOrder();
+    inputOrder.disabled=false;
+}
+
+function startDrag() {
+    this.style.zIndex = '10';
+    this.className = 'dragging';
+}
+
+function endDrag(x, y) {
+    this.style.zIndex = '1';
+    this.className = '';
+    // Work out how far along it has been dropped, using x co-ordinate
+    var oldIndex = this.index;
+    var newIndex = Math.round((y - 10 - top) / height);
+    // 'Snap' to the correct position
+    this.style.top = (10 + top + newIndex * height) + 'px';
+    this.index = newIndex;
+    moveItem(oldIndex, newIndex);
+}
+
+function moveItem(oldIndex, newIndex) {
+    // Swaps two items, adjusts the index and left co-ord for all others
+    if (oldIndex == newIndex) {
+        return; // Nothing to swap;
+    }
+    var direction, lo, hi;
+    if (newIndex > oldIndex) {
+        lo = oldIndex;
+        hi = newIndex;
+        direction = -1;
+    } else {
+        direction = 1;
+        hi = oldIndex;
+        lo = newIndex;
+    }
+    var lis2 = new Array(); // We will build the new order in this array
+    for (var i = 0; i < lis.length; i++) {
+        if (i < lo || i > hi) {
+            // Position of items not between the indexes is unaffected
+            lis2[i] = lis[i];
+            continue;
+        } else if (i == newIndex) {
+            lis2[i] = lis[oldIndex];
+            continue;
+        } else {
+            // Item is between the two indexes - move it along 1
+            lis2[i] = lis[i - direction];
+        }
+    }
+    // Re-index everything
+    reIndex(lis2);
+    lis = lis2;
+    draw();
+//    document.getElementById('hiddenOrder').value = getOrder();
+    document.getElementsBySelector('input[name=order_]')[0].value = getOrder();
+}
+
+function reIndex(lis) {
+    for (var i = 0; i < lis.length; i++) {
+        lis[i].index = i;
+    }
+}
+
+function draw() {
+    for (var i = 0; i < lis.length; i++) {
+        var li = lis[i];
+        li.index = i;
+        li.style.position = 'absolute';
+        li.style.left = (10 + left) + 'px';
+        li.style.top = (10 + top + (i * height)) + 'px';
+    }
+}
+
+function getOrder() {
+    var order = new Array(lis.length);
+    for (var i = 0; i < lis.length; i++) {
+        order[i] = lis[i].id.substring(1, 100);
+    }
+    return order.join(',');
+}
+
+function setOrder(id_list) {
+    /* Set the current order to match the lsit of IDs */
+    var temp_lis = new Array();
+    for (var i = 0; i < id_list.length; i++) {
+        var id = 'p' + id_list[i];
+        temp_lis[temp_lis.length] = document.getElementById(id);
+    }
+    reIndex(temp_lis);
+    lis = temp_lis;
+    draw();
+}
+
+function addEvent(elm, evType, fn, useCapture)
+// addEvent and removeEvent
+// cross-browser event handling for IE5+,  NS6 and Mozilla
+// By Scott Andrew
+{
+  if (elm.addEventListener){
+    elm.addEventListener(evType, fn, useCapture);
+    return true;
+  } else if (elm.attachEvent){
+    var r = elm.attachEvent("on"+evType, fn);
+    return r;
+  } else {
+    elm['on'+evType] = fn;
+  }
+}
diff --git a/project/media/django/js/calendar.js b/project/media/django/js/calendar.js
new file mode 100644 (file)
index 0000000..c95a95d
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+calendar.js - Calendar functions by Adrian Holovaty
+*/
+
+function removeChildren(a) { // "a" is reference to an object
+    while (a.hasChildNodes()) a.removeChild(a.lastChild);
+}
+
+// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
+function quickElement() {
+    var obj = document.createElement(arguments[0]);
+    if (arguments[2] != '' && arguments[2] != null) {
+        var textNode = document.createTextNode(arguments[2]);
+        obj.appendChild(textNode);
+    }
+    var len = arguments.length;
+    for (var i = 3; i < len; i += 2) {
+        obj.setAttribute(arguments[i], arguments[i+1]);
+    }
+    arguments[1].appendChild(obj);
+    return obj;
+}
+
+// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
+var CalendarNamespace = {
+    monthsOfYear: gettext('January February March April May June July August September October November December').split(' '),
+    daysOfWeek: gettext('S M T W T F S').split(' '),
+    firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
+    isLeapYear: function(year) {
+        return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0));
+    },
+    getDaysInMonth: function(month,year) {
+        var days;
+        if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
+            days = 31;
+        }
+        else if (month==4 || month==6 || month==9 || month==11) {
+            days = 30;
+        }
+        else if (month==2 && CalendarNamespace.isLeapYear(year)) {
+            days = 29;
+        }
+        else {
+            days = 28;
+        }
+        return days;
+    },
+    draw: function(month, year, div_id, callback) { // month = 1-12, year = 1-9999
+        var today = new Date();
+        var todayDay = today.getDate();
+        var todayMonth = today.getMonth()+1;
+        var todayYear = today.getFullYear();
+        var todayClass = '';
+
+        month = parseInt(month);
+        year = parseInt(year);
+        var calDiv = document.getElementById(div_id);
+        removeChildren(calDiv);
+        var calTable = document.createElement('table');
+        quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year);
+        var tableBody = quickElement('tbody', calTable);
+
+        // Draw days-of-week header
+        var tableRow = quickElement('tr', tableBody);
+        for (var i = 0; i < 7; i++) {
+            quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
+        }
+
+        var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
+        var days = CalendarNamespace.getDaysInMonth(month, year);
+
+        // Draw blanks before first of month
+        tableRow = quickElement('tr', tableBody);
+        for (var i = 0; i < startingPos; i++) {
+            var _cell = quickElement('td', tableRow, ' ');
+            _cell.style.backgroundColor = '#f3f3f3';
+        }
+
+        // Draw days of month
+        var currentDay = 1;
+        for (var i = startingPos; currentDay <= days; i++) {
+            if (i%7 == 0 && currentDay != 1) {
+                tableRow = quickElement('tr', tableBody);
+            }
+            if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) {
+                todayClass='today';
+            } else {
+                todayClass='';
+            }
+            var cell = quickElement('td', tableRow, '', 'class', todayClass);
+
+            quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));');
+            currentDay++;
+        }
+
+        // Draw blanks after end of month (optional, but makes for valid code)
+        while (tableRow.childNodes.length < 7) {
+            var _cell = quickElement('td', tableRow, ' ');
+            _cell.style.backgroundColor = '#f3f3f3';
+        }
+
+        calDiv.appendChild(calTable);
+    }
+}
+
+// Calendar -- A calendar instance
+function Calendar(div_id, callback) {
+    // div_id (string) is the ID of the element in which the calendar will
+    //     be displayed
+    // callback (string) is the name of a JavaScript function that will be
+    //     called with the parameters (year, month, day) when a day in the
+    //     calendar is clicked
+    this.div_id = div_id;
+    this.callback = callback;
+    this.today = new Date();
+    this.currentMonth = this.today.getMonth() + 1;
+    this.currentYear = this.today.getFullYear();
+}
+Calendar.prototype = {
+    drawCurrent: function() {
+        CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback);
+    },
+    drawDate: function(month, year) {
+        this.currentMonth = month;
+        this.currentYear = year;
+        this.drawCurrent();
+    },
+    drawPreviousMonth: function() {
+        if (this.currentMonth == 1) {
+            this.currentMonth = 12;
+            this.currentYear--;
+        }
+        else {
+            this.currentMonth--;
+        }
+        this.drawCurrent();
+    },
+    drawNextMonth: function() {
+        if (this.currentMonth == 12) {
+            this.currentMonth = 1;
+            this.currentYear++;
+        }
+        else {
+            this.currentMonth++;
+        }
+        this.drawCurrent();
+    },
+    drawPreviousYear: function() {
+        this.currentYear--;
+        this.drawCurrent();
+    },
+    drawNextYear: function() {
+        this.currentYear++;
+        this.drawCurrent();
+    }
+}
diff --git a/project/media/django/js/collapse.js b/project/media/django/js/collapse.js
new file mode 100644 (file)
index 0000000..0a1e2d8
--- /dev/null
@@ -0,0 +1,27 @@
+(function($) {
+       $(document).ready(function() {
+               // Add anchor tag for Show/Hide link
+               $("fieldset.collapse").each(function(i, elem) {
+                       // Don't hide if fields in this fieldset have errors
+                       if ( $(elem).find("div.errors").length == 0 ) {
+                               $(elem).addClass("collapsed");
+                               $(elem).find("h2").first().append(' (<a id="fieldsetcollapser' +
+                                       i +'" class="collapse-toggle" href="#">' + gettext("Show") +
+                                       '</a>)');
+                       }
+               });
+               // Add toggle to anchor tag
+               $("fieldset.collapse a.collapse-toggle").toggle(
+                       function() { // Show
+                               $(this).text(gettext("Hide"));
+                               $(this).closest("fieldset").removeClass("collapsed");
+                               return false;
+                       },
+                       function() { // Hide
+                               $(this).text(gettext("Show"));
+                               $(this).closest("fieldset").addClass("collapsed");
+                               return false;
+                       }
+               );
+       });
+})(django.jQuery);
diff --git a/project/media/django/js/collapse.min.js b/project/media/django/js/collapse.min.js
new file mode 100644 (file)
index 0000000..428984e
--- /dev/null
@@ -0,0 +1,2 @@
+(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){if(a(b).find("div.errors").length==0){a(b).addClass("collapsed");a(b).find("h2").first().append(' (<a id="fieldsetcollapser'+c+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")}});a("fieldset.collapse a.collapse-toggle").toggle(function(){a(this).text(gettext("Hide"));a(this).closest("fieldset").removeClass("collapsed");return false},function(){a(this).text(gettext("Show"));a(this).closest("fieldset").addClass("collapsed");
+return false})})})(django.jQuery);
diff --git a/project/media/django/js/compress.py b/project/media/django/js/compress.py
new file mode 100755 (executable)
index 0000000..8d2caa2
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+import os
+import optparse
+import subprocess
+import sys
+
+here = os.path.dirname(__file__)
+
+def main():
+    usage = "usage: %prog [file1..fileN]"
+    description = """With no file paths given this script will automatically
+compress all jQuery-based files of the admin app. Requires the Google Closure
+Compiler library and Java version 6 or later."""
+    parser = optparse.OptionParser(usage, description=description)
+    parser.add_option("-c", dest="compiler", default="~/bin/compiler.jar",
+                      help="path to Closure Compiler jar file")
+    parser.add_option("-v", "--verbose",
+                      action="store_true", dest="verbose")
+    parser.add_option("-q", "--quiet",
+                      action="store_false", dest="verbose")
+    (options, args) = parser.parse_args()
+
+    compiler = os.path.expanduser(options.compiler)
+    if not os.path.exists(compiler):
+        sys.exit("Google Closure compiler jar file %s not found. Please use the -c option to specify the path." % compiler)
+
+    if not args:
+        if options.verbose:
+            sys.stdout.write("No filenames given; defaulting to admin scripts\n")
+        args = [os.path.join(here, f) for f in [
+            "actions.js", "collapse.js", "inlines.js", "prepopulate.js"]]
+
+    for arg in args:
+        if not arg.endswith(".js"):
+            arg = arg + ".js"
+        to_compress = os.path.expanduser(arg)
+        if os.path.exists(to_compress):
+            to_compress_min = "%s.min.js" % "".join(arg.rsplit(".js"))
+            cmd = "java -jar %s --js %s --js_output_file %s" % (compiler, to_compress, to_compress_min)
+            if options.verbose:
+                sys.stdout.write("Running: %s\n" % cmd)
+            subprocess.call(cmd.split())
+        else:
+            sys.stdout.write("File %s not found. Sure it exists?\n" % to_compress)
+
+if __name__ == '__main__':
+    main()
diff --git a/project/media/django/js/core.js b/project/media/django/js/core.js
new file mode 100644 (file)
index 0000000..3ca8ad0
--- /dev/null
@@ -0,0 +1,221 @@
+// Core javascript helper functions
+
+// basic browser identification & version
+var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion);
+var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
+
+// Cross-browser event handlers.
+function addEvent(obj, evType, fn) {
+    if (obj.addEventListener) {
+        obj.addEventListener(evType, fn, false);
+        return true;
+    } else if (obj.attachEvent) {
+        var r = obj.attachEvent("on" + evType, fn);
+        return r;
+    } else {
+        return false;
+    }
+}
+
+function removeEvent(obj, evType, fn) {
+    if (obj.removeEventListener) {
+        obj.removeEventListener(evType, fn, false);
+        return true;
+    } else if (obj.detachEvent) {
+        obj.detachEvent("on" + evType, fn);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+// quickElement(tagType, parentReference, textInChildNode, [, attribute, attributeValue ...]);
+function quickElement() {
+    var obj = document.createElement(arguments[0]);
+    if (arguments[2] != '' && arguments[2] != null) {
+        var textNode = document.createTextNode(arguments[2]);
+        obj.appendChild(textNode);
+    }
+    var len = arguments.length;
+    for (var i = 3; i < len; i += 2) {
+        obj.setAttribute(arguments[i], arguments[i+1]);
+    }
+    arguments[1].appendChild(obj);
+    return obj;
+}
+
+// ----------------------------------------------------------------------------
+// Cross-browser xmlhttp object
+// from http://jibbering.com/2002/4/httprequest.html
+// ----------------------------------------------------------------------------
+var xmlhttp;
+/*@cc_on @*/
+/*@if (@_jscript_version >= 5)
+    try {
+        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+    } catch (e) {
+        try {
+            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+        } catch (E) {
+            xmlhttp = false;
+        }
+    }
+@else
+    xmlhttp = false;
+@end @*/
+if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
+  xmlhttp = new XMLHttpRequest();
+}
+
+// ----------------------------------------------------------------------------
+// Find-position functions by PPK
+// See http://www.quirksmode.org/js/findpos.html
+// ----------------------------------------------------------------------------
+function findPosX(obj) {
+    var curleft = 0;
+    if (obj.offsetParent) {
+        while (obj.offsetParent) {
+            curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
+            obj = obj.offsetParent;
+        }
+        // IE offsetParent does not include the top-level
+        if (isIE && obj.parentElement){
+            curleft += obj.offsetLeft - obj.scrollLeft;
+        }
+    } else if (obj.x) {
+        curleft += obj.x;
+    }
+    return curleft;
+}
+
+function findPosY(obj) {
+    var curtop = 0;
+    if (obj.offsetParent) {
+        while (obj.offsetParent) {
+            curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
+            obj = obj.offsetParent;
+        }
+        // IE offsetParent does not include the top-level
+        if (isIE && obj.parentElement){
+            curtop += obj.offsetTop - obj.scrollTop;
+        }
+    } else if (obj.y) {
+        curtop += obj.y;
+    }
+    return curtop;
+}
+
+//-----------------------------------------------------------------------------
+// Date object extensions
+// ----------------------------------------------------------------------------
+Date.prototype.getCorrectYear = function() {
+    // Date.getYear() is unreliable --
+    // see http://www.quirksmode.org/js/introdate.html#year
+    var y = this.getYear() % 100;
+    return (y < 38) ? y + 2000 : y + 1900;
+}
+
+Date.prototype.getTwelveHours = function() {
+    hours = this.getHours();
+    if (hours == 0) {
+        return 12;
+    }
+    else {
+        return hours <= 12 ? hours : hours-12
+    }
+}
+
+Date.prototype.getTwoDigitMonth = function() {
+    return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
+}
+
+Date.prototype.getTwoDigitDate = function() {
+    return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
+}
+
+Date.prototype.getTwoDigitTwelveHour = function() {
+    return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
+}
+
+Date.prototype.getTwoDigitHour = function() {
+    return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
+}
+
+Date.prototype.getTwoDigitMinute = function() {
+    return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
+}
+
+Date.prototype.getTwoDigitSecond = function() {
+    return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
+}
+
+Date.prototype.getISODate = function() {
+    return this.getCorrectYear() + '-' + this.getTwoDigitMonth() + '-' + this.getTwoDigitDate();
+}
+
+Date.prototype.getHourMinute = function() {
+    return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
+}
+
+Date.prototype.getHourMinuteSecond = function() {
+    return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
+}
+
+Date.prototype.strftime = function(format) {
+    var fields = {
+        c: this.toString(),
+        d: this.getTwoDigitDate(),
+        H: this.getTwoDigitHour(),
+        I: this.getTwoDigitTwelveHour(),
+        m: this.getTwoDigitMonth(),
+        M: this.getTwoDigitMinute(),
+        p: (this.getHours() >= 12) ? 'PM' : 'AM',
+        S: this.getTwoDigitSecond(),
+        w: '0' + this.getDay(),
+        x: this.toLocaleDateString(),
+        X: this.toLocaleTimeString(),
+        y: ('' + this.getFullYear()).substr(2, 4),
+        Y: '' + this.getFullYear(),
+        '%' : '%'
+    };
+    var result = '', i = 0;
+    while (i < format.length) {
+        if (format.charAt(i) === '%') {
+            result = result + fields[format.charAt(i + 1)];
+            ++i;
+        }
+        else {
+            result = result + format.charAt(i);
+        }
+        ++i;
+    }
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+// String object extensions
+// ----------------------------------------------------------------------------
+String.prototype.pad_left = function(pad_length, pad_string) {
+    var new_string = this;
+    for (var i = 0; new_string.length < pad_length; i++) {
+        new_string = pad_string + new_string;
+    }
+    return new_string;
+}
+
+// ----------------------------------------------------------------------------
+// Get the computed style for and element
+// ----------------------------------------------------------------------------
+function getStyle(oElm, strCssRule){
+    var strValue = "";
+    if(document.defaultView && document.defaultView.getComputedStyle){
+        strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
+    }
+    else if(oElm.currentStyle){
+        strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
+            return p1.toUpperCase();
+        });
+        strValue = oElm.currentStyle[strCssRule];
+    }
+    return strValue;
+}
diff --git a/project/media/django/js/dateparse.js b/project/media/django/js/dateparse.js
new file mode 100644 (file)
index 0000000..e1c870e
--- /dev/null
@@ -0,0 +1,233 @@
+/* 'Magic' date parsing, by Simon Willison (6th October 2003)
+   http://simon.incutio.com/archive/2003/10/06/betterDateInput
+   Adapted for 6newslawrence.com, 28th January 2004
+*/
+
+/* Finds the index of the first occurence of item in the array, or -1 if not found */
+if (typeof Array.prototype.indexOf == 'undefined') {
+    Array.prototype.indexOf = function(item) {
+        var len = this.length;
+        for (var i = 0; i < len; i++) {
+            if (this[i] == item) {
+                return i;
+            }
+        }
+        return -1;
+    };
+}
+/* Returns an array of items judged 'true' by the passed in test function */
+if (typeof Array.prototype.filter == 'undefined') {
+    Array.prototype.filter = function(test) {
+        var matches = [];
+        var len = this.length;
+        for (var i = 0; i < len; i++) {
+            if (test(this[i])) {
+                matches[matches.length] = this[i];
+            }
+        }
+        return matches;
+    };
+}
+
+var monthNames = gettext("January February March April May June July August September October November December").split(" ");
+var weekdayNames = gettext("Sunday Monday Tuesday Wednesday Thursday Friday Saturday").split(" ");
+
+/* Takes a string, returns the index of the month matching that string, throws
+   an error if 0 or more than 1 matches
+*/
+function parseMonth(month) {
+    var matches = monthNames.filter(function(item) { 
+        return new RegExp("^" + month, "i").test(item);
+    });
+    if (matches.length == 0) {
+        throw new Error("Invalid month string");
+    }
+    if (matches.length > 1) {
+        throw new Error("Ambiguous month");
+    }
+    return monthNames.indexOf(matches[0]);
+}
+/* Same as parseMonth but for days of the week */
+function parseWeekday(weekday) {
+    var matches = weekdayNames.filter(function(item) {
+        return new RegExp("^" + weekday, "i").test(item);
+    });
+    if (matches.length == 0) {
+        throw new Error("Invalid day string");
+    }
+    if (matches.length > 1) {
+        throw new Error("Ambiguous weekday");
+    }
+    return weekdayNames.indexOf(matches[0]);
+}
+
+/* Array of objects, each has 're', a regular expression and 'handler', a 
+   function for creating a date from something that matches the regular 
+   expression. Handlers may throw errors if string is unparseable. 
+*/
+var dateParsePatterns = [
+    // Today
+    {   re: /^tod/i,
+        handler: function() { 
+            return new Date();
+        } 
+    },
+    // Tomorrow
+    {   re: /^tom/i,
+        handler: function() {
+            var d = new Date(); 
+            d.setDate(d.getDate() + 1); 
+            return d;
+        }
+    },
+    // Yesterday
+    {   re: /^yes/i,
+        handler: function() {
+            var d = new Date();
+            d.setDate(d.getDate() - 1);
+            return d;
+        }
+    },
+    // 4th
+    {   re: /^(\d{1,2})(st|nd|rd|th)?$/i, 
+        handler: function(bits) {
+            var d = new Date();
+            d.setDate(parseInt(bits[1], 10));
+            return d;
+        }
+    },
+    // 4th Jan
+    {   re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i, 
+        handler: function(bits) {
+            var d = new Date();
+            d.setDate(parseInt(bits[1], 10));
+            d.setMonth(parseMonth(bits[2]));
+            return d;
+        }
+    },
+    // 4th Jan 2003
+    {   re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i,
+        handler: function(bits) {
+            var d = new Date();
+            d.setDate(parseInt(bits[1], 10));
+            d.setMonth(parseMonth(bits[2]));
+            d.setYear(bits[3]);
+            return d;
+        }
+    },
+    // Jan 4th
+    {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i, 
+        handler: function(bits) {
+            var d = new Date();
+            d.setDate(parseInt(bits[2], 10));
+            d.setMonth(parseMonth(bits[1]));
+            return d;
+        }
+    },
+    // Jan 4th 2003
+    {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i,
+        handler: function(bits) {
+            var d = new Date();
+            d.setDate(parseInt(bits[2], 10));
+            d.setMonth(parseMonth(bits[1]));
+            d.setYear(bits[3]);
+            return d;
+        }
+    },
+    // next Tuesday - this is suspect due to weird meaning of "next"
+    {   re: /^next (\w+)$/i,
+        handler: function(bits) {
+            var d = new Date();
+            var day = d.getDay();
+            var newDay = parseWeekday(bits[1]);
+            var addDays = newDay - day;
+            if (newDay <= day) {
+                addDays += 7;
+            }
+            d.setDate(d.getDate() + addDays);
+            return d;
+        }
+    },
+    // last Tuesday
+    {   re: /^last (\w+)$/i,
+        handler: function(bits) {
+            throw new Error("Not yet implemented");
+        }
+    },
+    // mm/dd/yyyy (American style)
+    {   re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
+        handler: function(bits) {
+            var d = new Date();
+            d.setYear(bits[3]);
+            d.setDate(parseInt(bits[2], 10));
+            d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
+            return d;
+        }
+    },
+    // yyyy-mm-dd (ISO style)
+    {   re: /(\d{4})-(\d{1,2})-(\d{1,2})/,
+        handler: function(bits) {
+            var d = new Date();
+            d.setYear(parseInt(bits[1]));
+            d.setMonth(parseInt(bits[2], 10) - 1);
+            d.setDate(parseInt(bits[3], 10));
+            return d;
+        }
+    },
+];
+
+function parseDateString(s) {
+    for (var i = 0; i < dateParsePatterns.length; i++) {
+        var re = dateParsePatterns[i].re;
+        var handler = dateParsePatterns[i].handler;
+        var bits = re.exec(s);
+        if (bits) {
+            return handler(bits);
+        }
+    }
+    throw new Error("Invalid date string");
+}
+
+function fmt00(x) {
+    // fmt00: Tags leading zero onto numbers 0 - 9.
+    // Particularly useful for displaying results from Date methods.
+    //
+    if (Math.abs(parseInt(x)) < 10){
+        x = "0"+ Math.abs(x);
+    }
+    return x;
+}
+
+function parseDateStringISO(s) {
+    try {
+        var d = parseDateString(s);
+        return d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' + fmt00(d.getDate())
+    }
+    catch (e) { return s; }
+}
+function magicDate(input) {
+    var messagespan = input.id + 'Msg';
+    try {
+        var d = parseDateString(input.value);
+        input.value = d.getFullYear() + '-' + (fmt00(d.getMonth() + 1)) + '-' + 
+            fmt00(d.getDate());
+        input.className = '';
+        // Human readable date
+        if (document.getElementById(messagespan)) {
+            document.getElementById(messagespan).firstChild.nodeValue = d.toDateString();
+            document.getElementById(messagespan).className = 'normal';
+        }
+    }
+    catch (e) {
+        input.className = 'error';
+        var message = e.message;
+        // Fix for IE6 bug
+        if (message.indexOf('is null or not an object') > -1) {
+            message = 'Invalid date string';
+        }
+        if (document.getElementById(messagespan)) {
+            document.getElementById(messagespan).firstChild.nodeValue = message;
+            document.getElementById(messagespan).className = 'error';
+        }
+    }
+}
diff --git a/project/media/django/js/getElementsBySelector.js b/project/media/django/js/getElementsBySelector.js
new file mode 100644 (file)
index 0000000..15b57a1
--- /dev/null
@@ -0,0 +1,167 @@
+/* document.getElementsBySelector(selector)
+   - returns an array of element objects from the current document
+     matching the CSS selector. Selectors can contain element names, 
+     class names and ids and can be nested. For example:
+     
+       elements = document.getElementsBySelect('div#main p a.external')
+     
+     Will return an array of all 'a' elements with 'external' in their 
+     class attribute that are contained inside 'p' elements that are 
+     contained inside the 'div' element which has id="main"
+
+   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
+   See http://www.w3.org/TR/css3-selectors/#attribute-selectors
+
+   Version 0.4 - Simon Willison, March 25th 2003
+   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
+   -- Opera 7 fails 
+*/
+
+function getAllChildren(e) {
+  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
+  return e.all ? e.all : e.getElementsByTagName('*');
+}
+
+document.getElementsBySelector = function(selector) {
+  // Attempt to fail gracefully in lesser browsers
+  if (!document.getElementsByTagName) {
+    return new Array();
+  }
+  // Split selector in to tokens
+  var tokens = selector.split(' ');
+  var currentContext = new Array(document);
+  for (var i = 0; i < tokens.length; i++) {
+    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
+    if (token.indexOf('#') > -1) {
+      // Token is an ID selector
+      var bits = token.split('#');
+      var tagName = bits[0];
+      var id = bits[1];
+      var element = document.getElementById(id);
+      if (!element || (tagName && element.nodeName.toLowerCase() != tagName)) {
+        // ID not found or tag with that ID not found, return false.
+        return new Array();
+      }
+      // Set currentContext to contain just this element
+      currentContext = new Array(element);
+      continue; // Skip to next token
+    }
+    if (token.indexOf('.') > -1) {
+      // Token contains a class selector
+      var bits = token.split('.');
+      var tagName = bits[0];
+      var className = bits[1];
+      if (!tagName) {
+        tagName = '*';
+      }
+      // Get elements matching tag, filter them for class selector
+      var found = new Array;
+      var foundCount = 0;
+      for (var h = 0; h < currentContext.length; h++) {
+        var elements;
+        if (tagName == '*') {
+            elements = getAllChildren(currentContext[h]);
+        } else {
+            try {
+                elements = currentContext[h].getElementsByTagName(tagName);
+            }
+            catch(e) {
+                elements = [];
+            }
+        }
+        for (var j = 0; j < elements.length; j++) {
+          found[foundCount++] = elements[j];
+        }
+      }
+      currentContext = new Array;
+      var currentContextIndex = 0;
+      for (var k = 0; k < found.length; k++) {
+        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
+          currentContext[currentContextIndex++] = found[k];
+        }
+      }
+      continue; // Skip to next token
+    }
+    // Code to deal with attribute selectors
+    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
+      var tagName = RegExp.$1;
+      var attrName = RegExp.$2;
+      var attrOperator = RegExp.$3;
+      var attrValue = RegExp.$4;
+      if (!tagName) {
+        tagName = '*';
+      }
+      // Grab all of the tagName elements within current context
+      var found = new Array;
+      var foundCount = 0;
+      for (var h = 0; h < currentContext.length; h++) {
+        var elements;
+        if (tagName == '*') {
+            elements = getAllChildren(currentContext[h]);
+        } else {
+            elements = currentContext[h].getElementsByTagName(tagName);
+        }
+        for (var j = 0; j < elements.length; j++) {
+          found[foundCount++] = elements[j];
+        }
+      }
+      currentContext = new Array;
+      var currentContextIndex = 0;
+      var checkFunction; // This function will be used to filter the elements
+      switch (attrOperator) {
+        case '=': // Equality
+          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
+          break;
+        case '~': // Match one of space seperated words 
+          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
+          break;
+        case '|': // Match start with value followed by optional hyphen
+          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
+          break;
+        case '^': // Match starts with value
+          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
+          break;
+        case '$': // Match ends with value - fails with "Warning" in Opera 7
+          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
+          break;
+        case '*': // Match ends with value
+          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
+          break;
+        default :
+          // Just test for existence of attribute
+          checkFunction = function(e) { return e.getAttribute(attrName); };
+      }
+      currentContext = new Array;
+      var currentContextIndex = 0;
+      for (var k = 0; k < found.length; k++) {
+        if (checkFunction(found[k])) {
+          currentContext[currentContextIndex++] = found[k];
+        }
+      }
+      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
+      continue; // Skip to next token
+    }
+    // If we get here, token is JUST an element (not a class or ID selector)
+    tagName = token;
+    var found = new Array;
+    var foundCount = 0;
+    for (var h = 0; h < currentContext.length; h++) {
+      var elements = currentContext[h].getElementsByTagName(tagName);
+      for (var j = 0; j < elements.length; j++) {
+        found[foundCount++] = elements[j];
+      }
+    }
+    currentContext = found;
+  }
+  return currentContext;
+}
+
+/* That revolting regular expression explained 
+/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
+  \---/  \---/\-------------/    \-------/
+    |      |         |               |
+    |      |         |           The value
+    |      |    ~,|,^,$,* or =
+    |   Attribute 
+   Tag
+*/
diff --git a/project/media/django/js/inlines.js b/project/media/django/js/inlines.js
new file mode 100644 (file)
index 0000000..0153a41
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+ * Django admin inlines
+ *
+ * Based on jQuery Formset 1.1
+ * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
+ * @requires jQuery 1.2.6 or later
+ *
+ * Copyright (c) 2009, Stanislaus Madueke
+ * All rights reserved.
+ *
+ * Spiced up with Code from Zain Memon's GSoC project 2009
+ * and modified for Django by Jannis Leidel
+ *
+ * Licensed under the New BSD License
+ * See: http://www.opensource.org/licenses/bsd-license.php
+ */
+(function($) {
+       $.fn.formset = function(opts) {
+               var options = $.extend({}, $.fn.formset.defaults, opts);
+               var updateElementIndex = function(el, prefix, ndx) {
+                       var id_regex = new RegExp("(" + prefix + "-\\d+)");
+                       var replacement = prefix + "-" + ndx;
+                       if ($(el).attr("for")) {
+                               $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
+                       }
+                       if (el.id) {
+                               el.id = el.id.replace(id_regex, replacement);
+                       }
+                       if (el.name) {
+                               el.name = el.name.replace(id_regex, replacement);
+                       }
+               };
+               var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").attr("autocomplete", "off");
+               var nextIndex = parseInt(totalForms.val());
+               var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").attr("autocomplete", "off");
+               // only show the add button if we are allowed to add more items,
+        // note that max_num = None translates to a blank string.
+               var showAddButton = maxForms.val() == '' || (maxForms.val()-totalForms.val()) > 0;
+               $(this).each(function(i) {
+                       $(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
+               });
+               if ($(this).length && showAddButton) {
+                       var addButton;
+                       if ($(this).attr("tagName") == "TR") {
+                               // If forms are laid out as table rows, insert the
+                               // "add" button in a new table row:
+                               var numCols = this.eq(0).children().length;
+                               $(this).parent().append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="javascript:void(0)">' + options.addText + "</a></tr>");
+                               addButton = $(this).parent().find("tr:last a");
+                       } else {
+                               // Otherwise, insert it immediately after the last form:
+                               $(this).filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>");
+                               addButton = $(this).filter(":last").next().find("a");
+                       }
+                       addButton.click(function() {
+                               var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS");
+                               var template = $("#" + options.prefix + "-empty");
+                               var row = template.clone(true);
+                               row.removeClass(options.emptyCssClass)
+                                   .addClass(options.formCssClass)
+                                   .attr("id", options.prefix + "-" + nextIndex);
+                               nextIndex += 1;
+                               row.find("*")
+                                   .filter(function() {
+                                       var el = $(this);
+                                       return el.attr("id") && el.attr("id").search(/__prefix__/) >= 0;
+                                   }).each(function() {
+                                       var el = $(this);
+                                       el.attr("id", el.attr("id").replace(/__prefix__/g, nextIndex));
+                                   })
+                                   .end()
+                                   .filter(function() {
+                                       var el = $(this);
+                                       return el.attr("name") && el.attr("name").search(/__prefix__/) >= 0;
+                                   }).each(function() {
+                                       var el = $(this);
+                                       el.attr("name", el.attr("name").replace(/__prefix__/g, nextIndex));
+                                   })
+                                   .end()
+                                   .filter(function() {
+                                       var el = $(this);
+                                       return el.attr("for") && el.attr("for").search(/__prefix__/) >= 0;
+                                   }).each(function() {
+                                       var el = $(this);
+                                       el.attr("for", el.attr("for").replace(/__prefix__/g, nextIndex));
+                                   });
+                               if (row.is("tr")) {
+                                       // If the forms are laid out in table rows, insert
+                                       // the remove button into the last table cell:
+                                       row.children(":last").append('<div><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></div>");
+                               } else if (row.is("ul") || row.is("ol")) {
+                                       // If they're laid out as an ordered/unordered list,
+                                       // insert an <li> after the last list item:
+                                       row.append('<li><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></li>");
+                               } else {
+                                       // Otherwise, just insert the remove button as the
+                                       // last child element of the form's container:
+                                       row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></span>");
+                               }
+                               row.find("input,select,textarea,label,a").each(function() {
+                                       updateElementIndex(this, options.prefix, totalForms.val());
+                               });
+                               // Insert the new form when it has been fully edited
+                               row.insertBefore($(template));
+                               // Update number of total forms
+                               $(totalForms).val(parseInt(totalForms.val()) + 1);
+                               // Hide add button in case we've hit the max, except we want to add infinitely
+                               if ((maxForms.val() != '') && (maxForms.val()-totalForms.val()) <= 0) {
+                                       addButton.parent().hide();
+                               }
+                               // The delete button of each row triggers a bunch of other things
+                               row.find("a." + options.deleteCssClass).click(function() {
+                                       // Remove the parent form containing this button:
+                                       var row = $(this).parents("." + options.formCssClass);
+                                       row.remove();
+                                       // If a post-delete callback was provided, call it with the deleted form:
+                                       if (options.removed) {
+                                               options.removed(row);
+                                       }
+                                       // Update the TOTAL_FORMS form count.
+                                       var forms = $("." + options.formCssClass);
+                                       $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
+                                       // Show add button again once we drop below max
+                                       if ((maxForms.val() == '') || (maxForms.val()-forms.length) > 0) {
+                                               addButton.parent().show();
+                                       }
+                                       // Also, update names and ids for all remaining form controls
+                                       // so they remain in sequence:
+                                       for (var i=0, formCount=forms.length; i<formCount; i++)
+                                       {
+                                               $(forms.get(i)).find("input,select,textarea,label,a").each(function() {
+                                                       updateElementIndex(this, options.prefix, i);
+                                               });
+                                       }
+                                       return false;
+                               });
+                               // If a post-add callback was supplied, call it with the added form:
+                               if (options.added) {
+                                       options.added(row);
+                               }
+                               return false;
+                       });
+               }
+               return this;
+       }
+       /* Setup plugin defaults */
+       $.fn.formset.defaults = {
+               prefix: "form",                                 // The form prefix for your django formset
+               addText: "add another",                 // Text for the add link
+               deleteText: "remove",                   // Text for the delete link
+               addCssClass: "add-row",                 // CSS class applied to the add link
+               deleteCssClass: "delete-row",   // CSS class applied to the delete link
+               emptyCssClass: "empty-row",             // CSS class applied to the empty row
+               formCssClass: "dynamic-form",   // CSS class applied to each form in a formset
+               added: null,                                    // Function called each time a new form is added
+               removed: null                                   // Function called each time a form is deleted
+       }
+})(django.jQuery);
diff --git a/project/media/django/js/inlines.min.js b/project/media/django/js/inlines.min.js
new file mode 100644 (file)
index 0000000..fa3540b
--- /dev/null
@@ -0,0 +1,6 @@
+(function(a){a.fn.formset=function(g){var b=a.extend({},a.fn.formset.defaults,g),l=function(d,f,e){var c=RegExp("("+f+"-\\d+)");f=f+"-"+e;a(d).attr("for")&&a(d).attr("for",a(d).attr("for").replace(c,f));if(d.id)d.id=d.id.replace(c,f);if(d.name)d.name=d.name.replace(c,f)};g=a("#id_"+b.prefix+"-TOTAL_FORMS").attr("autocomplete","off");var i=parseInt(g.val()),h=a("#id_"+b.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off");g=h.val()==""||h.val()-g.val()>0;a(this).each(function(){a(this).not("."+b.emptyCssClass).addClass(b.formCssClass)});
+if(a(this).length&&g){var j;if(a(this).attr("tagName")=="TR"){g=this.eq(0).children().length;a(this).parent().append('<tr class="'+b.addCssClass+'"><td colspan="'+g+'"><a href="javascript:void(0)">'+b.addText+"</a></tr>");j=a(this).parent().find("tr:last a")}else{a(this).filter(":last").after('<div class="'+b.addCssClass+'"><a href="javascript:void(0)">'+b.addText+"</a></div>");j=a(this).filter(":last").next().find("a")}j.click(function(){var d=a("#id_"+b.prefix+"-TOTAL_FORMS"),f=a("#"+b.prefix+"-empty"),
+e=f.clone(true);e.removeClass(b.emptyCssClass).addClass(b.formCssClass).attr("id",b.prefix+"-"+i);i+=1;e.find("*").filter(function(){var c=a(this);return c.attr("id")&&c.attr("id").search(/__prefix__/)>=0}).each(function(){var c=a(this);c.attr("id",c.attr("id").replace(/__prefix__/g,i))}).end().filter(function(){var c=a(this);return c.attr("name")&&c.attr("name").search(/__prefix__/)>=0}).each(function(){var c=a(this);c.attr("name",c.attr("name").replace(/__prefix__/g,i))}).end().filter(function(){var c=
+a(this);return c.attr("for")&&c.attr("for").search(/__prefix__/)>=0}).each(function(){var c=a(this);c.attr("for",c.attr("for").replace(/__prefix__/g,i))});if(e.is("tr"))e.children(":last").append('<div><a class="'+b.deleteCssClass+'" href="javascript:void(0)">'+b.deleteText+"</a></div>");else e.is("ul")||e.is("ol")?e.append('<li><a class="'+b.deleteCssClass+'" href="javascript:void(0)">'+b.deleteText+"</a></li>"):e.children(":first").append('<span><a class="'+b.deleteCssClass+'" href="javascript:void(0)">'+
+b.deleteText+"</a></span>");e.find("input,select,textarea,label,a").each(function(){l(this,b.prefix,d.val())});e.insertBefore(a(f));a(d).val(parseInt(d.val())+1);h.val()!=""&&h.val()-d.val()<=0&&j.parent().hide();e.find("a."+b.deleteCssClass).click(function(){var c=a(this).parents("."+b.formCssClass);c.remove();b.removed&&b.removed(c);c=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(c.length);if(h.val()==""||h.val()-c.length>0)j.parent().show();for(var k=0,m=c.length;k<m;k++)a(c.get(k)).find("input,select,textarea,label,a").each(function(){l(this,
+b.prefix,k)});return false});b.added&&b.added(e);return false})}return this};a.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null}})(django.jQuery);
diff --git a/project/media/django/js/jquery.init.js b/project/media/django/js/jquery.init.js
new file mode 100644 (file)
index 0000000..85a7973
--- /dev/null
@@ -0,0 +1,4 @@
+// Puts the included jQuery into our own namespace
+var django = {
+    "jQuery": jQuery.noConflict(true)
+};
diff --git a/project/media/django/js/jquery.js b/project/media/django/js/jquery.js
new file mode 100644 (file)
index 0000000..fff6776
--- /dev/null
@@ -0,0 +1,6240 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+               // The jQuery object is actually just the init constructor 'enhanced'
+               return new jQuery.fn.init( selector, context );
+       },
+
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+
+       // Map over the $ in case of overwrite
+       _$ = window.$,
+
+       // Use the correct document accordingly with window argument (sandbox)
+       document = window.document,
+
+       // A central reference to the root jQuery(document)
+       rootjQuery,
+
+       // A simple way to check for HTML strings or ID strings
+       // (both of which we optimize for)
+       quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+       // Is it a simple selector
+       isSimple = /^.[^:#\[\.,]*$/,
+
+       // Check if a string has a non-whitespace character in it
+       rnotwhite = /\S/,
+
+       // Used for trimming whitespace
+       rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+       // Match a standalone tag
+       rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+       // Keep a UserAgent string for use with jQuery.browser
+       userAgent = navigator.userAgent,
+
+       // For matching the engine and version of the browser
+       browserMatch,
+       
+       // Has the ready events already been bound?
+       readyBound = false,
+       
+       // The functions to execute on DOM ready
+       readyList = [],
+
+       // The ready event handler
+       DOMContentLoaded,
+
+       // Save a reference to some core methods
+       toString = Object.prototype.toString,
+       hasOwnProperty = Object.prototype.hasOwnProperty,
+       push = Array.prototype.push,
+       slice = Array.prototype.slice,
+       indexOf = Array.prototype.indexOf;
+
+jQuery.fn = jQuery.prototype = {
+       init: function( selector, context ) {
+               var match, elem, ret, doc;
+
+               // Handle $(""), $(null), or $(undefined)
+               if ( !selector ) {
+                       return this;
+               }
+
+               // Handle $(DOMElement)
+               if ( selector.nodeType ) {
+                       this.context = this[0] = selector;
+                       this.length = 1;
+                       return this;
+               }
+               
+               // The body element only exists once, optimize finding it
+               if ( selector === "body" && !context ) {
+                       this.context = document;
+                       this[0] = document.body;
+                       this.selector = "body";
+                       this.length = 1;
+                       return this;
+               }
+
+               // Handle HTML strings
+               if ( typeof selector === "string" ) {
+                       // Are we dealing with HTML string or an ID?
+                       match = quickExpr.exec( selector );
+
+                       // Verify a match, and that no context was specified for #id
+                       if ( match && (match[1] || !context) ) {
+
+                               // HANDLE: $(html) -> $(array)
+                               if ( match[1] ) {
+                                       doc = (context ? context.ownerDocument || context : document);
+
+                                       // If a single string is passed in and it's a single tag
+                                       // just do a createElement and skip the rest
+                                       ret = rsingleTag.exec( selector );
+
+                                       if ( ret ) {
+                                               if ( jQuery.isPlainObject( context ) ) {
+                                                       selector = [ document.createElement( ret[1] ) ];
+                                                       jQuery.fn.attr.call( selector, context, true );
+
+                                               } else {
+                                                       selector = [ doc.createElement( ret[1] ) ];
+                                               }
+
+                                       } else {
+                                               ret = buildFragment( [ match[1] ], [ doc ] );
+                                               selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+                                       }
+                                       
+                                       return jQuery.merge( this, selector );
+                                       
+                               // HANDLE: $("#id")
+                               } else {
+                                       elem = document.getElementById( match[2] );
+
+                                       if ( elem ) {
+                                               // Handle the case where IE and Opera return items
+                                               // by name instead of ID
+                                               if ( elem.id !== match[2] ) {
+                                                       return rootjQuery.find( selector );
+                                               }
+
+                                               // Otherwise, we inject the element directly into the jQuery object
+                                               this.length = 1;
+                                               this[0] = elem;
+                                       }
+
+                                       this.context = document;
+                                       this.selector = selector;
+                                       return this;
+                               }
+
+                       // HANDLE: $("TAG")
+                       } else if ( !context && /^\w+$/.test( selector ) ) {
+                               this.selector = selector;
+                               this.context = document;
+                               selector = document.getElementsByTagName( selector );
+                               return jQuery.merge( this, selector );
+
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return (context || rootjQuery).find( selector );
+
+                       // HANDLE: $(expr, context)
+                       // (which is just equivalent to: $(context).find(expr)
+                       } else {
+                               return jQuery( context ).find( selector );
+                       }
+
+               // HANDLE: $(function)
+               // Shortcut for document ready
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return rootjQuery.ready( selector );
+               }
+
+               if (selector.selector !== undefined) {
+                       this.selector = selector.selector;
+                       this.context = selector.context;
+               }
+
+               return jQuery.makeArray( selector, this );
+       },
+
+       // Start with an empty selector
+       selector: "",
+
+       // The current version of jQuery being used
+       jquery: "1.4.2",
+
+       // The default length of a jQuery object is 0
+       length: 0,
+
+       // The number of elements contained in the matched element set
+       size: function() {
+               return this.length;
+       },
+
+       toArray: function() {
+               return slice.call( this, 0 );
+       },
+
+       // Get the Nth element in the matched element set OR
+       // Get the whole matched element set as a clean array
+       get: function( num ) {
+               return num == null ?
+
+                       // Return a 'clean' array
+                       this.toArray() :
+
+                       // Return just the object
+                       ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+       },
+
+       // Take an array of elements and push it onto the stack
+       // (returning the new matched element set)
+       pushStack: function( elems, name, selector ) {
+               // Build a new jQuery matched element set
+               var ret = jQuery();
+
+               if ( jQuery.isArray( elems ) ) {
+                       push.apply( ret, elems );
+               
+               } else {
+                       jQuery.merge( ret, elems );
+               }
+
+               // Add the old object onto the stack (as a reference)
+               ret.prevObject = this;
+
+               ret.context = this.context;
+
+               if ( name === "find" ) {
+                       ret.selector = this.selector + (this.selector ? " " : "") + selector;
+               } else if ( name ) {
+                       ret.selector = this.selector + "." + name + "(" + selector + ")";
+               }
+
+               // Return the newly-formed element set
+               return ret;
+       },
+
+       // Execute a callback for every element in the matched set.
+       // (You can seed the arguments with an array of args, but this is
+       // only used internally.)
+       each: function( callback, args ) {
+               return jQuery.each( this, callback, args );
+       },
+       
+       ready: function( fn ) {
+               // Attach the listeners
+               jQuery.bindReady();
+
+               // If the DOM is already ready
+               if ( jQuery.isReady ) {
+                       // Execute the function immediately
+                       fn.call( document, jQuery );
+
+               // Otherwise, remember the function for later
+               } else if ( readyList ) {
+                       // Add the function to the wait list
+                       readyList.push( fn );
+               }
+
+               return this;
+       },
+       
+       eq: function( i ) {
+               return i === -1 ?
+                       this.slice( i ) :
+                       this.slice( i, +i + 1 );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       slice: function() {
+               return this.pushStack( slice.apply( this, arguments ),
+                       "slice", slice.call(arguments).join(",") );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map(this, function( elem, i ) {
+                       return callback.call( elem, i, elem );
+               }));
+       },
+       
+       end: function() {
+               return this.prevObject || jQuery(null);
+       },
+
+       // For internal use only.
+       // Behaves like an Array's method, not like a jQuery method.
+       push: push,
+       sort: [].sort,
+       splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+       // copy reference to target object
+       var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+               target = arguments[1] || {};
+               // skip the boolean and the target
+               i = 2;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+               target = {};
+       }
+
+       // extend jQuery itself if only one argument is passed
+       if ( length === i ) {
+               target = this;
+               --i;
+       }
+
+       for ( ; i < length; i++ ) {
+               // Only deal with non-null/undefined values
+               if ( (options = arguments[ i ]) != null ) {
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging object literal values or arrays
+                               if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+                                       var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+                                               : jQuery.isArray(copy) ? [] : {};
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = jQuery.extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+jQuery.extend({
+       noConflict: function( deep ) {
+               window.$ = _$;
+
+               if ( deep ) {
+                       window.jQuery = _jQuery;
+               }
+
+               return jQuery;
+       },
+       
+       // Is the DOM ready to be used? Set to true once it occurs.
+       isReady: false,
+       
+       // Handle when the DOM is ready
+       ready: function() {
+               // Make sure that the DOM is not already loaded
+               if ( !jQuery.isReady ) {
+                       // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+                       if ( !document.body ) {
+                               return setTimeout( jQuery.ready, 13 );
+                       }
+
+                       // Remember that the DOM is ready
+                       jQuery.isReady = true;
+
+                       // If there are functions bound, to execute
+                       if ( readyList ) {
+                               // Execute all of them
+                               var fn, i = 0;
+                               while ( (fn = readyList[ i++ ]) ) {
+                                       fn.call( document, jQuery );
+                               }
+
+                               // Reset the list of functions
+                               readyList = null;
+                       }
+
+                       // Trigger any bound ready events
+                       if ( jQuery.fn.triggerHandler ) {
+                               jQuery( document ).triggerHandler( "ready" );
+                       }
+               }
+       },
+       
+       bindReady: function() {
+               if ( readyBound ) {
+                       return;
+               }
+
+               readyBound = true;
+
+               // Catch cases where $(document).ready() is called after the
+               // browser event has already occurred.
+               if ( document.readyState === "complete" ) {
+                       return jQuery.ready();
+               }
+
+               // Mozilla, Opera and webkit nightlies currently support this event
+               if ( document.addEventListener ) {
+                       // Use the handy event callback
+                       document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+                       
+                       // A fallback to window.onload, that will always work
+                       window.addEventListener( "load", jQuery.ready, false );
+
+               // If IE event model is used
+               } else if ( document.attachEvent ) {
+                       // ensure firing before onload,
+                       // maybe late but safe also for iframes
+                       document.attachEvent("onreadystatechange", DOMContentLoaded);
+                       
+                       // A fallback to window.onload, that will always work
+                       window.attachEvent( "onload", jQuery.ready );
+
+                       // If IE and not a frame
+                       // continually check to see if the document is ready
+                       var toplevel = false;
+
+                       try {
+                               toplevel = window.frameElement == null;
+                       } catch(e) {}
+
+                       if ( document.documentElement.doScroll && toplevel ) {
+                               doScrollCheck();
+                       }
+               }
+       },
+
+       // See test/unit/core.js for details concerning isFunction.
+       // Since version 1.3, DOM methods and functions like alert
+       // aren't supported. They return false on IE (#2968).
+       isFunction: function( obj ) {
+               return toString.call(obj) === "[object Function]";
+       },
+
+       isArray: function( obj ) {
+               return toString.call(obj) === "[object Array]";
+       },
+
+       isPlainObject: function( obj ) {
+               // Must be an Object.
+               // Because of IE, we also have to check the presence of the constructor property.
+               // Make sure that DOM nodes and window objects don't pass through, as well
+               if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+                       return false;
+               }
+               
+               // Not own constructor property must be Object
+               if ( obj.constructor
+                       && !hasOwnProperty.call(obj, "constructor")
+                       && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+                       return false;
+               }
+               
+               // Own properties are enumerated firstly, so to speed up,
+               // if last one is own, then all properties are own.
+       
+               var key;
+               for ( key in obj ) {}
+               
+               return key === undefined || hasOwnProperty.call( obj, key );
+       },
+
+       isEmptyObject: function( obj ) {
+               for ( var name in obj ) {
+                       return false;
+               }
+               return true;
+       },
+       
+       error: function( msg ) {
+               throw msg;
+       },
+       
+       parseJSON: function( data ) {
+               if ( typeof data !== "string" || !data ) {
+                       return null;
+               }
+
+               // Make sure leading/trailing whitespace is removed (IE can't handle it)
+               data = jQuery.trim( data );
+               
+               // Make sure the incoming data is actual JSON
+               // Logic borrowed from http://json.org/json2.js
+               if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+                       .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+                       .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+                       // Try to use the native JSON parser first
+                       return window.JSON && window.JSON.parse ?
+                               window.JSON.parse( data ) :
+                               (new Function("return " + data))();
+
+               } else {
+                       jQuery.error( "Invalid JSON: " + data );
+               }
+       },
+
+       noop: function() {},
+
+       // Evalulates a script in a global context
+       globalEval: function( data ) {
+               if ( data && rnotwhite.test(data) ) {
+                       // Inspired by code by Andrea Giammarchi
+                       // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+                       var head = document.getElementsByTagName("head")[0] || document.documentElement,
+                               script = document.createElement("script");
+
+                       script.type = "text/javascript";
+
+                       if ( jQuery.support.scriptEval ) {
+                               script.appendChild( document.createTextNode( data ) );
+                       } else {
+                               script.text = data;
+                       }
+
+                       // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+                       // This arises when a base node is used (#2709).
+                       head.insertBefore( script, head.firstChild );
+                       head.removeChild( script );
+               }
+       },
+
+       nodeName: function( elem, name ) {
+               return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+       },
+
+       // args is for internal usage only
+       each: function( object, callback, args ) {
+               var name, i = 0,
+                       length = object.length,
+                       isObj = length === undefined || jQuery.isFunction(object);
+
+               if ( args ) {
+                       if ( isObj ) {
+                               for ( name in object ) {
+                                       if ( callback.apply( object[ name ], args ) === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( ; i < length; ) {
+                                       if ( callback.apply( object[ i++ ], args ) === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               // A special, fast, case for the most common use of each
+               } else {
+                       if ( isObj ) {
+                               for ( name in object ) {
+                                       if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( var value = object[0];
+                                       i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+                       }
+               }
+
+               return object;
+       },
+
+       trim: function( text ) {
+               return (text || "").replace( rtrim, "" );
+       },
+
+       // results is for internal usage only
+       makeArray: function( array, results ) {
+               var ret = results || [];
+
+               if ( array != null ) {
+                       // The window, strings (and functions) also have 'length'
+                       // The extra typeof function check is to prevent crashes
+                       // in Safari 2 (See: #3039)
+                       if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+                               push.call( ret, array );
+                       } else {
+                               jQuery.merge( ret, array );
+                       }
+               }
+
+               return ret;
+       },
+
+       inArray: function( elem, array ) {
+               if ( array.indexOf ) {
+                       return array.indexOf( elem );
+               }
+
+               for ( var i = 0, length = array.length; i < length; i++ ) {
+                       if ( array[ i ] === elem ) {
+                               return i;
+                       }
+               }
+
+               return -1;
+       },
+
+       merge: function( first, second ) {
+               var i = first.length, j = 0;
+
+               if ( typeof second.length === "number" ) {
+                       for ( var l = second.length; j < l; j++ ) {
+                               first[ i++ ] = second[ j ];
+                       }
+               
+               } else {
+                       while ( second[j] !== undefined ) {
+                               first[ i++ ] = second[ j++ ];
+                       }
+               }
+
+               first.length = i;
+
+               return first;
+       },
+
+       grep: function( elems, callback, inv ) {
+               var ret = [];
+
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( var i = 0, length = elems.length; i < length; i++ ) {
+                       if ( !inv !== !callback( elems[ i ], i ) ) {
+                               ret.push( elems[ i ] );
+                       }
+               }
+
+               return ret;
+       },
+
+       // arg is for internal usage only
+       map: function( elems, callback, arg ) {
+               var ret = [], value;
+
+               // Go through the array, translating each of the items to their
+               // new value (or values).
+               for ( var i = 0, length = elems.length; i < length; i++ ) {
+                       value = callback( elems[ i ], i, arg );
+
+                       if ( value != null ) {
+                               ret[ ret.length ] = value;
+                       }
+               }
+
+               return ret.concat.apply( [], ret );
+       },
+
+       // A global GUID counter for objects
+       guid: 1,
+
+       proxy: function( fn, proxy, thisObject ) {
+               if ( arguments.length === 2 ) {
+                       if ( typeof proxy === "string" ) {
+                               thisObject = fn;
+                               fn = thisObject[ proxy ];
+                               proxy = undefined;
+
+                       } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+                               thisObject = proxy;
+                               proxy = undefined;
+                       }
+               }
+
+               if ( !proxy && fn ) {
+                       proxy = function() {
+                               return fn.apply( thisObject || this, arguments );
+                       };
+               }
+
+               // Set the guid of unique handler to the same of original handler, so it can be removed
+               if ( fn ) {
+                       proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+               }
+
+               // So proxy can be declared as an argument
+               return proxy;
+       },
+
+       // Use of jQuery.browser is frowned upon.
+       // More details: http://docs.jquery.com/Utilities/jQuery.browser
+       uaMatch: function( ua ) {
+               ua = ua.toLowerCase();
+
+               var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+                       /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+                       /(msie) ([\w.]+)/.exec( ua ) ||
+                       !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+                       [];
+
+               return { browser: match[1] || "", version: match[2] || "0" };
+       },
+
+       browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+       jQuery.browser[ browserMatch.browser ] = true;
+       jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+       jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+       jQuery.inArray = function( elem, array ) {
+               return indexOf.call( array, elem );
+       };
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+       DOMContentLoaded = function() {
+               document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+               jQuery.ready();
+       };
+
+} else if ( document.attachEvent ) {
+       DOMContentLoaded = function() {
+               // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+               if ( document.readyState === "complete" ) {
+                       document.detachEvent( "onreadystatechange", DOMContentLoaded );
+                       jQuery.ready();
+               }
+       };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+       if ( jQuery.isReady ) {
+               return;
+       }
+
+       try {
+               // If IE is used, use the trick by Diego Perini
+               // http://javascript.nwbox.com/IEContentLoaded/
+               document.documentElement.doScroll("left");
+       } catch( error ) {
+               setTimeout( doScrollCheck, 1 );
+               return;
+       }
+
+       // and execute any waiting functions
+       jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+       if ( elem.src ) {
+               jQuery.ajax({
+                       url: elem.src,
+                       async: false,
+                       dataType: "script"
+               });
+       } else {
+               jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+       }
+
+       if ( elem.parentNode ) {
+               elem.parentNode.removeChild( elem );
+       }
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+       var length = elems.length;
+       
+       // Setting many attributes
+       if ( typeof key === "object" ) {
+               for ( var k in key ) {
+                       access( elems, k, key[k], exec, fn, value );
+               }
+               return elems;
+       }
+       
+       // Setting one attribute
+       if ( value !== undefined ) {
+               // Optionally, function values get executed if exec is true
+               exec = !pass && exec && jQuery.isFunction(value);
+               
+               for ( var i = 0; i < length; i++ ) {
+                       fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+               }
+               
+               return elems;
+       }
+       
+       // Getting an attribute
+       return length ? fn( elems[0], key ) : undefined;
+}
+
+function now() {
+       return (new Date).getTime();
+}
+(function() {
+
+       jQuery.support = {};
+
+       var root = document.documentElement,
+               script = document.createElement("script"),
+               div = document.createElement("div"),
+               id = "script" + now();
+
+       div.style.display = "none";
+       div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+       var all = div.getElementsByTagName("*"),
+               a = div.getElementsByTagName("a")[0];
+
+       // Can't get basic test support
+       if ( !all || !all.length || !a ) {
+               return;
+       }
+
+       jQuery.support = {
+               // IE strips leading whitespace when .innerHTML is used
+               leadingWhitespace: div.firstChild.nodeType === 3,
+
+               // Make sure that tbody elements aren't automatically inserted
+               // IE will insert them into empty tables
+               tbody: !div.getElementsByTagName("tbody").length,
+
+               // Make sure that link elements get serialized correctly by innerHTML
+               // This requires a wrapper element in IE
+               htmlSerialize: !!div.getElementsByTagName("link").length,
+
+               // Get the style information from getAttribute
+               // (IE uses .cssText insted)
+               style: /red/.test( a.getAttribute("style") ),
+
+               // Make sure that URLs aren't manipulated
+               // (IE normalizes it by default)
+               hrefNormalized: a.getAttribute("href") === "/a",
+
+               // Make sure that element opacity exists
+               // (IE uses filter instead)
+               // Use a regex to work around a WebKit issue. See #5145
+               opacity: /^0.55$/.test( a.style.opacity ),
+
+               // Verify style float existence
+               // (IE uses styleFloat instead of cssFloat)
+               cssFloat: !!a.style.cssFloat,
+
+               // Make sure that if no value is specified for a checkbox
+               // that it defaults to "on".
+               // (WebKit defaults to "" instead)
+               checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+               // Make sure that a selected-by-default option has a working selected property.
+               // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+               optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+               parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
+
+               // Will be defined later
+               deleteExpando: true,
+               checkClone: false,
+               scriptEval: false,
+               noCloneEvent: true,
+               boxModel: null
+       };
+
+       script.type = "text/javascript";
+       try {
+               script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+       } catch(e) {}
+
+       root.insertBefore( script, root.firstChild );
+
+       // Make sure that the execution of code works by injecting a script
+       // tag with appendChild/createTextNode
+       // (IE doesn't support this, fails, and uses .text instead)
+       if ( window[ id ] ) {
+               jQuery.support.scriptEval = true;
+               delete window[ id ];
+       }
+
+       // Test to see if it's possible to delete an expando from an element
+       // Fails in Internet Explorer
+       try {
+               delete script.test;
+       
+       } catch(e) {
+               jQuery.support.deleteExpando = false;
+       }
+
+       root.removeChild( script );
+
+       if ( div.attachEvent && div.fireEvent ) {
+               div.attachEvent("onclick", function click() {
+                       // Cloning a node shouldn't copy over any
+                       // bound event handlers (IE does this)
+                       jQuery.support.noCloneEvent = false;
+                       div.detachEvent("onclick", click);
+               });
+               div.cloneNode(true).fireEvent("onclick");
+       }
+
+       div = document.createElement("div");
+       div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+       var fragment = document.createDocumentFragment();
+       fragment.appendChild( div.firstChild );
+
+       // WebKit doesn't clone checked state correctly in fragments
+       jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+       // Figure out if the W3C box model works as expected
+       // document.body must exist before we can do this
+       jQuery(function() {
+               var div = document.createElement("div");
+               div.style.width = div.style.paddingLeft = "1px";
+
+               document.body.appendChild( div );
+               jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+               document.body.removeChild( div ).style.display = 'none';
+
+               div = null;
+       });
+
+       // Technique from Juriy Zaytsev
+       // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+       var eventSupported = function( eventName ) { 
+               var el = document.createElement("div"); 
+               eventName = "on" + eventName; 
+
+               var isSupported = (eventName in el); 
+               if ( !isSupported ) { 
+                       el.setAttribute(eventName, "return;"); 
+                       isSupported = typeof el[eventName] === "function"; 
+               } 
+               el = null; 
+
+               return isSupported; 
+       };
+       
+       jQuery.support.submitBubbles = eventSupported("submit");
+       jQuery.support.changeBubbles = eventSupported("change");
+
+       // release memory in IE
+       root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+       "for": "htmlFor",
+       "class": "className",
+       readonly: "readOnly",
+       maxlength: "maxLength",
+       cellspacing: "cellSpacing",
+       rowspan: "rowSpan",
+       colspan: "colSpan",
+       tabindex: "tabIndex",
+       usemap: "useMap",
+       frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+       cache: {},
+       
+       expando:expando,
+
+       // The following elements throw uncatchable exceptions if you
+       // attempt to add expando properties to them.
+       noData: {
+               "embed": true,
+               "object": true,
+               "applet": true
+       },
+
+       data: function( elem, name, data ) {
+               if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+                       return;
+               }
+
+               elem = elem == window ?
+                       windowData :
+                       elem;
+
+               var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+               if ( !id && typeof name === "string" && data === undefined ) {
+                       return null;
+               }
+
+               // Compute a unique ID for the element
+               if ( !id ) { 
+                       id = ++uuid;
+               }
+
+               // Avoid generating a new cache unless none exists and we
+               // want to manipulate it.
+               if ( typeof name === "object" ) {
+                       elem[ expando ] = id;
+                       thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+
+               } else if ( !cache[ id ] ) {
+                       elem[ expando ] = id;
+                       cache[ id ] = {};
+               }
+
+               thisCache = cache[ id ];
+
+               // Prevent overriding the named cache with undefined values
+               if ( data !== undefined ) {
+                       thisCache[ name ] = data;
+               }
+
+               return typeof name === "string" ? thisCache[ name ] : thisCache;
+       },
+
+       removeData: function( elem, name ) {
+               if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+                       return;
+               }
+
+               elem = elem == window ?
+                       windowData :
+                       elem;
+
+               var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+               // If we want to remove a specific section of the element's data
+               if ( name ) {
+                       if ( thisCache ) {
+                               // Remove the section of cache data
+                               delete thisCache[ name ];
+
+                               // If we've removed all the data, remove the element's cache
+                               if ( jQuery.isEmptyObject(thisCache) ) {
+                                       jQuery.removeData( elem );
+                               }
+                       }
+
+               // Otherwise, we want to remove all of the element's data
+               } else {
+                       if ( jQuery.support.deleteExpando ) {
+                               delete elem[ jQuery.expando ];
+
+                       } else if ( elem.removeAttribute ) {
+                               elem.removeAttribute( jQuery.expando );
+                       }
+
+                       // Completely remove the data cache
+                       delete cache[ id ];
+               }
+       }
+});
+
+jQuery.fn.extend({
+       data: function( key, value ) {
+               if ( typeof key === "undefined" && this.length ) {
+                       return jQuery.data( this[0] );
+
+               } else if ( typeof key === "object" ) {
+                       return this.each(function() {
+                               jQuery.data( this, key );
+                       });
+               }
+
+               var parts = key.split(".");
+               parts[1] = parts[1] ? "." + parts[1] : "";
+
+               if ( value === undefined ) {
+                       var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+                       if ( data === undefined && this.length ) {
+                               data = jQuery.data( this[0], key );
+                       }
+                       return data === undefined && parts[1] ?
+                               this.data( parts[0] ) :
+                               data;
+               } else {
+                       return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+                               jQuery.data( this, key, value );
+                       });
+               }
+       },
+
+       removeData: function( key ) {
+               return this.each(function() {
+                       jQuery.removeData( this, key );
+               });
+       }
+});
+jQuery.extend({
+       queue: function( elem, type, data ) {
+               if ( !elem ) {
+                       return;
+               }
+
+               type = (type || "fx") + "queue";
+               var q = jQuery.data( elem, type );
+
+               // Speed up dequeue by getting out quickly if this is just a lookup
+               if ( !data ) {
+                       return q || [];
+               }
+
+               if ( !q || jQuery.isArray(data) ) {
+                       q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+               } else {
+                       q.push( data );
+               }
+
+               return q;
+       },
+
+       dequeue: function( elem, type ) {
+               type = type || "fx";
+
+               var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+               // If the fx queue is dequeued, always remove the progress sentinel
+               if ( fn === "inprogress" ) {
+                       fn = queue.shift();
+               }
+
+               if ( fn ) {
+                       // Add a progress sentinel to prevent the fx queue from being
+                       // automatically dequeued
+                       if ( type === "fx" ) {
+                               queue.unshift("inprogress");
+                       }
+
+                       fn.call(elem, function() {
+                               jQuery.dequeue(elem, type);
+                       });
+               }
+       }
+});
+
+jQuery.fn.extend({
+       queue: function( type, data ) {
+               if ( typeof type !== "string" ) {
+                       data = type;
+                       type = "fx";
+               }
+
+               if ( data === undefined ) {
+                       return jQuery.queue( this[0], type );
+               }
+               return this.each(function( i, elem ) {
+                       var queue = jQuery.queue( this, type, data );
+
+                       if ( type === "fx" && queue[0] !== "inprogress" ) {
+                               jQuery.dequeue( this, type );
+                       }
+               });
+       },
+       dequeue: function( type ) {
+               return this.each(function() {
+                       jQuery.dequeue( this, type );
+               });
+       },
+
+       // Based off of the plugin by Clint Helfers, with permission.
+       // http://blindsignals.com/index.php/2009/07/jquery-delay/
+       delay: function( time, type ) {
+               time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+               type = type || "fx";
+
+               return this.queue( type, function() {
+                       var elem = this;
+                       setTimeout(function() {
+                               jQuery.dequeue( elem, type );
+                       }, time );
+               });
+       },
+
+       clearQueue: function( type ) {
+               return this.queue( type || "fx", [] );
+       }
+});
+var rclass = /[\n\t]/g,
+       rspace = /\s+/,
+       rreturn = /\r/g,
+       rspecialurl = /href|src|style/,
+       rtype = /(button|input)/i,
+       rfocusable = /(button|input|object|select|textarea)/i,
+       rclickable = /^(a|area)$/i,
+       rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+       attr: function( name, value ) {
+               return access( this, name, value, true, jQuery.attr );
+       },
+
+       removeAttr: function( name, fn ) {
+               return this.each(function(){
+                       jQuery.attr( this, name, "" );
+                       if ( this.nodeType === 1 ) {
+                               this.removeAttribute( name );
+                       }
+               });
+       },
+
+       addClass: function( value ) {
+               if ( jQuery.isFunction(value) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               self.addClass( value.call(this, i, self.attr("class")) );
+                       });
+               }
+
+               if ( value && typeof value === "string" ) {
+                       var classNames = (value || "").split( rspace );
+
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               var elem = this[i];
+
+                               if ( elem.nodeType === 1 ) {
+                                       if ( !elem.className ) {
+                                               elem.className = value;
+
+                                       } else {
+                                               var className = " " + elem.className + " ", setClass = elem.className;
+                                               for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+                                                       if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+                                                               setClass += " " + classNames[c];
+                                                       }
+                                               }
+                                               elem.className = jQuery.trim( setClass );
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       removeClass: function( value ) {
+               if ( jQuery.isFunction(value) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               self.removeClass( value.call(this, i, self.attr("class")) );
+                       });
+               }
+
+               if ( (value && typeof value === "string") || value === undefined ) {
+                       var classNames = (value || "").split(rspace);
+
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               var elem = this[i];
+
+                               if ( elem.nodeType === 1 && elem.className ) {
+                                       if ( value ) {
+                                               var className = (" " + elem.className + " ").replace(rclass, " ");
+                                               for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+                                                       className = className.replace(" " + classNames[c] + " ", " ");
+                                               }
+                                               elem.className = jQuery.trim( className );
+
+                                       } else {
+                                               elem.className = "";
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       toggleClass: function( value, stateVal ) {
+               var type = typeof value, isBool = typeof stateVal === "boolean";
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function(i) {
+                               var self = jQuery(this);
+                               self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+                       });
+               }
+
+               return this.each(function() {
+                       if ( type === "string" ) {
+                               // toggle individual class names
+                               var className, i = 0, self = jQuery(this),
+                                       state = stateVal,
+                                       classNames = value.split( rspace );
+
+                               while ( (className = classNames[ i++ ]) ) {
+                                       // check each className given, space seperated list
+                                       state = isBool ? state : !self.hasClass( className );
+                                       self[ state ? "addClass" : "removeClass" ]( className );
+                               }
+
+                       } else if ( type === "undefined" || type === "boolean" ) {
+                               if ( this.className ) {
+                                       // store className if set
+                                       jQuery.data( this, "__className__", this.className );
+                               }
+
+                               // toggle whole className
+                               this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+                       }
+               });
+       },
+
+       hasClass: function( selector ) {
+               var className = " " + selector + " ";
+               for ( var i = 0, l = this.length; i < l; i++ ) {
+                       if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       },
+
+       val: function( value ) {
+               if ( value === undefined ) {
+                       var elem = this[0];
+
+                       if ( elem ) {
+                               if ( jQuery.nodeName( elem, "option" ) ) {
+                                       return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+                               }
+
+                               // We need to handle select boxes special
+                               if ( jQuery.nodeName( elem, "select" ) ) {
+                                       var index = elem.selectedIndex,
+                                               values = [],
+                                               options = elem.options,
+                                               one = elem.type === "select-one";
+
+                                       // Nothing was selected
+                                       if ( index < 0 ) {
+                                               return null;
+                                       }
+
+                                       // Loop through all the selected options
+                                       for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+                                               var option = options[ i ];
+
+                                               if ( option.selected ) {
+                                                       // Get the specifc value for the option
+                                                       value = jQuery(option).val();
+
+                                                       // We don't need an array for one selects
+                                                       if ( one ) {
+                                                               return value;
+                                                       }
+
+                                                       // Multi-Selects return an array
+                                                       values.push( value );
+                                               }
+                                       }
+
+                                       return values;
+                               }
+
+                               // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+                               if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+                                       return elem.getAttribute("value") === null ? "on" : elem.value;
+                               }
+                               
+
+                               // Everything else, we just grab the value
+                               return (elem.value || "").replace(rreturn, "");
+
+                       }
+
+                       return undefined;
+               }
+
+               var isFunction = jQuery.isFunction(value);
+
+               return this.each(function(i) {
+                       var self = jQuery(this), val = value;
+
+                       if ( this.nodeType !== 1 ) {
+                               return;
+                       }
+
+                       if ( isFunction ) {
+                               val = value.call(this, i, self.val());
+                       }
+
+                       // Typecast each time if the value is a Function and the appended
+                       // value is therefore different each time.
+                       if ( typeof val === "number" ) {
+                               val += "";
+                       }
+
+                       if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+                               this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+                       } else if ( jQuery.nodeName( this, "select" ) ) {
+                               var values = jQuery.makeArray(val);
+
+                               jQuery( "option", this ).each(function() {
+                                       this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+                               });
+
+                               if ( !values.length ) {
+                                       this.selectedIndex = -1;
+                               }
+
+                       } else {
+                               this.value = val;
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       attrFn: {
+               val: true,
+               css: true,
+               html: true,
+               text: true,
+               data: true,
+               width: true,
+               height: true,
+               offset: true
+       },
+               
+       attr: function( elem, name, value, pass ) {
+               // don't set attributes on text and comment nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return undefined;
+               }
+
+               if ( pass && name in jQuery.attrFn ) {
+                       return jQuery(elem)[name](value);
+               }
+
+               var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+                       // Whether we are setting (or getting)
+                       set = value !== undefined;
+
+               // Try to normalize/fix the name
+               name = notxml && jQuery.props[ name ] || name;
+
+               // Only do all the following if this is a node (faster for style)
+               if ( elem.nodeType === 1 ) {
+                       // These attributes require special treatment
+                       var special = rspecialurl.test( name );
+
+                       // Safari mis-reports the default selected property of an option
+                       // Accessing the parent's selectedIndex property fixes it
+                       if ( name === "selected" && !jQuery.support.optSelected ) {
+                               var parent = elem.parentNode;
+                               if ( parent ) {
+                                       parent.selectedIndex;
+       
+                                       // Make sure that it also works with optgroups, see #5701
+                                       if ( parent.parentNode ) {
+                                               parent.parentNode.selectedIndex;
+                                       }
+                               }
+                       }
+
+                       // If applicable, access the attribute via the DOM 0 way
+                       if ( name in elem && notxml && !special ) {
+                               if ( set ) {
+                                       // We can't allow the type property to be changed (since it causes problems in IE)
+                                       if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+                                               jQuery.error( "type property can't be changed" );
+                                       }
+
+                                       elem[ name ] = value;
+                               }
+
+                               // browsers index elements by id/name on forms, give priority to attributes.
+                               if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+                                       return elem.getAttributeNode( name ).nodeValue;
+                               }
+
+                               // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               if ( name === "tabIndex" ) {
+                                       var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+                                       return attributeNode && attributeNode.specified ?
+                                               attributeNode.value :
+                                               rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+                                                       0 :
+                                                       undefined;
+                               }
+
+                               return elem[ name ];
+                       }
+
+                       if ( !jQuery.support.style && notxml && name === "style" ) {
+                               if ( set ) {
+                                       elem.style.cssText = "" + value;
+                               }
+
+                               return elem.style.cssText;
+                       }
+
+                       if ( set ) {
+                               // convert the value to a string (all browsers do this but IE) see #1070
+                               elem.setAttribute( name, "" + value );
+                       }
+
+                       var attr = !jQuery.support.hrefNormalized && notxml && special ?
+                                       // Some attributes require a special call on IE
+                                       elem.getAttribute( name, 2 ) :
+                                       elem.getAttribute( name );
+
+                       // Non-existent attributes return null, we normalize to undefined
+                       return attr === null ? undefined : attr;
+               }
+
+               // elem is actually elem.style ... set the style
+               // Using attr for specific style information is now deprecated. Use style instead.
+               return jQuery.style( elem, name, value );
+       }
+});
+var rnamespaces = /\.(.*)$/,
+       fcleanup = function( nm ) {
+               return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+                       return "\\" + ch;
+               });
+       };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+       // Bind an event to an element
+       // Original by Dean Edwards
+       add: function( elem, types, handler, data ) {
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               // For whatever reason, IE has trouble passing the window object
+               // around, causing it to be cloned in the process
+               if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+                       elem = window;
+               }
+
+               var handleObjIn, handleObj;
+
+               if ( handler.handler ) {
+                       handleObjIn = handler;
+                       handler = handleObjIn.handler;
+               }
+
+               // Make sure that the function being executed has a unique ID
+               if ( !handler.guid ) {
+                       handler.guid = jQuery.guid++;
+               }
+
+               // Init the element's event structure
+               var elemData = jQuery.data( elem );
+
+               // If no elemData is found then we must be trying to bind to one of the
+               // banned noData elements
+               if ( !elemData ) {
+                       return;
+               }
+
+               var events = elemData.events = elemData.events || {},
+                       eventHandle = elemData.handle, eventHandle;
+
+               if ( !eventHandle ) {
+                       elemData.handle = eventHandle = function() {
+                               // Handle the second event of a trigger and when
+                               // an event is called after a page has unloaded
+                               return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+                                       jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+                                       undefined;
+                       };
+               }
+
+               // Add elem as a property of the handle function
+               // This is to prevent a memory leak with non-native events in IE.
+               eventHandle.elem = elem;
+
+               // Handle multiple events separated by a space
+               // jQuery(...).bind("mouseover mouseout", fn);
+               types = types.split(" ");
+
+               var type, i = 0, namespaces;
+
+               while ( (type = types[ i++ ]) ) {
+                       handleObj = handleObjIn ?
+                               jQuery.extend({}, handleObjIn) :
+                               { handler: handler, data: data };
+
+                       // Namespaced event handlers
+                       if ( type.indexOf(".") > -1 ) {
+                               namespaces = type.split(".");
+                               type = namespaces.shift();
+                               handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+                       } else {
+                               namespaces = [];
+                               handleObj.namespace = "";
+                       }
+
+                       handleObj.type = type;
+                       handleObj.guid = handler.guid;
+
+                       // Get the current list of functions bound to this event
+                       var handlers = events[ type ],
+                               special = jQuery.event.special[ type ] || {};
+
+                       // Init the event handler queue
+                       if ( !handlers ) {
+                               handlers = events[ type ] = [];
+
+                               // Check for a special event handler
+                               // Only use addEventListener/attachEvent if the special
+                               // events handler returns false
+                               if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+                                       // Bind the global event handler to the element
+                                       if ( elem.addEventListener ) {
+                                               elem.addEventListener( type, eventHandle, false );
+
+                                       } else if ( elem.attachEvent ) {
+                                               elem.attachEvent( "on" + type, eventHandle );
+                                       }
+                               }
+                       }
+                       
+                       if ( special.add ) { 
+                               special.add.call( elem, handleObj ); 
+
+                               if ( !handleObj.handler.guid ) {
+                                       handleObj.handler.guid = handler.guid;
+                               }
+                       }
+
+                       // Add the function to the element's handler list
+                       handlers.push( handleObj );
+
+                       // Keep track of which events have been used, for global triggering
+                       jQuery.event.global[ type ] = true;
+               }
+
+               // Nullify elem to prevent memory leaks in IE
+               elem = null;
+       },
+
+       global: {},
+
+       // Detach an event or set of events from an element
+       remove: function( elem, types, handler, pos ) {
+               // don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+                       elemData = jQuery.data( elem ),
+                       events = elemData && elemData.events;
+
+               if ( !elemData || !events ) {
+                       return;
+               }
+
+               // types is actually an event object here
+               if ( types && types.type ) {
+                       handler = types.handler;
+                       types = types.type;
+               }
+
+               // Unbind all events for the element
+               if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+                       types = types || "";
+
+                       for ( type in events ) {
+                               jQuery.event.remove( elem, type + types );
+                       }
+
+                       return;
+               }
+
+               // Handle multiple events separated by a space
+               // jQuery(...).unbind("mouseover mouseout", fn);
+               types = types.split(" ");
+
+               while ( (type = types[ i++ ]) ) {
+                       origType = type;
+                       handleObj = null;
+                       all = type.indexOf(".") < 0;
+                       namespaces = [];
+
+                       if ( !all ) {
+                               // Namespaced event handlers
+                               namespaces = type.split(".");
+                               type = namespaces.shift();
+
+                               namespace = new RegExp("(^|\\.)" + 
+                                       jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
+                       }
+
+                       eventType = events[ type ];
+
+                       if ( !eventType ) {
+                               continue;
+                       }
+
+                       if ( !handler ) {
+                               for ( var j = 0; j < eventType.length; j++ ) {
+                                       handleObj = eventType[ j ];
+
+                                       if ( all || namespace.test( handleObj.namespace ) ) {
+                                               jQuery.event.remove( elem, origType, handleObj.handler, j );
+                                               eventType.splice( j--, 1 );
+                                       }
+                               }
+
+                               continue;
+