From 8ea8d070279b9911eb9026ad91b2a88195354af1 Mon Sep 17 00:00:00 2001 From: Etzelia Date: Fri, 26 Jul 2019 12:36:03 -0500 Subject: [PATCH 01/22] Initial local commit Signed-off-by: Etzelia --- .gitignore | 5 + README.md | 1 - __init__.py | 0 admin.py | 26 + apps.py | 5 + migrations/0001_initial.py | 302 +++ migrations/__init__.py | 0 models.py | 289 +++ router.py | 38 + static/coreprotect/css/datepicker.css | 100 + static/coreprotect/css/datetimepicker.css | 10 + static/coreprotect/css/main.less | 436 +++++ static/coreprotect/css/slider.css | 77 + static/coreprotect/js/controllers.js | 187 ++ static/coreprotect/js/lib/angular.js | 161 ++ static/coreprotect/js/lib/angularui.js | 1461 ++++++++++++++ static/coreprotect/js/lib/datatables.js | 157 ++ static/coreprotect/js/lib/datetimepicker.js | 1902 +++++++++++++++++++ static/coreprotect/js/lib/jquery.js | 2 + static/coreprotect/js/lib/jquerycookie.js | 94 + static/coreprotect/js/lib/jqueryui.js | 7 + static/coreprotect/js/lib/less.js | 9 + static/coreprotect/js/login.js | 16 + static/coreprotect/js/main.js | 146 ++ templates/coreprotect/coreprotect.html | 160 ++ tests.py | 3 + views.py | 6 + 27 files changed, 5599 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 __init__.py create mode 100644 admin.py create mode 100644 apps.py create mode 100644 migrations/0001_initial.py create mode 100644 migrations/__init__.py create mode 100644 models.py create mode 100644 router.py create mode 100644 static/coreprotect/css/datepicker.css create mode 100644 static/coreprotect/css/datetimepicker.css create mode 100644 static/coreprotect/css/main.less create mode 100644 static/coreprotect/css/slider.css create mode 100644 static/coreprotect/js/controllers.js create mode 100644 static/coreprotect/js/lib/angular.js create mode 100644 static/coreprotect/js/lib/angularui.js create mode 100644 static/coreprotect/js/lib/datatables.js create mode 100644 static/coreprotect/js/lib/datetimepicker.js create mode 100644 static/coreprotect/js/lib/jquery.js create mode 100644 static/coreprotect/js/lib/jquerycookie.js create mode 100644 static/coreprotect/js/lib/jqueryui.js create mode 100644 static/coreprotect/js/lib/less.js create mode 100644 static/coreprotect/js/login.js create mode 100644 static/coreprotect/js/main.js create mode 100644 templates/coreprotect/coreprotect.html create mode 100644 tests.py create mode 100644 views.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9b3836 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# PyCharm +.idea + +# Compiled +*.pyc \ No newline at end of file diff --git a/README.md b/README.md index 5ec832e..bfe6e35 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ # DjangoCoreProtect - diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/admin.py b/admin.py new file mode 100644 index 0000000..1c6e392 --- /dev/null +++ b/admin.py @@ -0,0 +1,26 @@ +from django.contrib import admin + +from django_coreprotect.models import CoArtMap, CoBlock, CoBlockdataMap, CoChat, CoCommand, CoContainer, CoDatabaseLock, \ + CoEntity, CoEntityMap, CoMaterialMap, CoSession, CoSign, CoSkull, CoUser, CoUsernameLog, CoVersion, CoWorld + +try: + pass + # admin.site.register(CoArtMap) + # admin.site.register(CoBlock) + # admin.site.register(CoBlockdataMap) + # admin.site.register(CoChat) + # admin.site.register(CoCommand) + # admin.site.register(CoContainer) + # admin.site.register(CoDatabaseLock) + # admin.site.register(CoEntity) + # admin.site.register(CoEntityMap) + # admin.site.register(CoMaterialMap) + # admin.site.register(CoSession) + # admin.site.register(CoSign) + # admin.site.register(CoSkull) + # admin.site.register(CoUser) + # admin.site.register(CoUsernameLog) + # admin.site.register(CoVersion) + # admin.site.register(CoWorld) +except admin.sites.AlreadyRegistered: + pass diff --git a/apps.py b/apps.py new file mode 100644 index 0000000..c06930e --- /dev/null +++ b/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DjangoCoreprotectConfig(AppConfig): + name = 'django_coreprotect' diff --git a/migrations/0001_initial.py b/migrations/0001_initial.py new file mode 100644 index 0000000..c275431 --- /dev/null +++ b/migrations/0001_initial.py @@ -0,0 +1,302 @@ +# Generated by Django 2.2.3 on 2019-07-26 17:01 + +import django.contrib.auth.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0011_update_proxy_permissions'), + ] + + operations = [ + migrations.CreateModel( + name='CoArtMap', + fields=[ + ('id', models.IntegerField(primary_key=True, serialize=False)), + ('art', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Art Map', + 'verbose_name_plural': 'Art Maps', + 'db_table': 'co_art_map', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoBlock', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.IntegerField(blank=True, null=True)), + ('wid', models.IntegerField(blank=True, null=True)), + ('x', models.IntegerField(blank=True, null=True)), + ('y', models.IntegerField(blank=True, null=True)), + ('z', models.IntegerField(blank=True, null=True)), + ('type', models.IntegerField(blank=True, null=True)), + ('data', models.IntegerField(blank=True, null=True)), + ('meta', models.BinaryField(blank=True, null=True)), + ('blockdata', models.BinaryField(blank=True, null=True)), + ('action', models.IntegerField(blank=True, null=True)), + ('rolled_back', models.IntegerField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Block', + 'verbose_name_plural': 'Blocks', + 'db_table': 'co_block', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoBlockdataMap', + fields=[ + ('id', models.IntegerField(primary_key=True, serialize=False)), + ('data', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'BlockData Map', + 'verbose_name_plural': 'BlockData Maps', + 'db_table': 'co_blockdata_map', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoChat', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.IntegerField(blank=True, null=True)), + ('message', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Chat Message', + 'verbose_name_plural': 'Chat Messages', + 'db_table': 'co_chat', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoCommand', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.IntegerField(blank=True, null=True)), + ('message', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Command', + 'verbose_name_plural': 'Commands', + 'db_table': 'co_command', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoContainer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.IntegerField(blank=True, null=True)), + ('wid', models.IntegerField(blank=True, null=True)), + ('x', models.IntegerField(blank=True, null=True)), + ('y', models.IntegerField(blank=True, null=True)), + ('z', models.IntegerField(blank=True, null=True)), + ('type', models.IntegerField(blank=True, null=True)), + ('data', models.IntegerField(blank=True, null=True)), + ('amount', models.IntegerField(blank=True, null=True)), + ('metadata', models.BinaryField(blank=True, null=True)), + ('action', models.IntegerField(blank=True, null=True)), + ('rolled_back', models.IntegerField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Container Transaction', + 'verbose_name_plural': 'Container Transactions', + 'db_table': 'co_container', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoDatabaseLock', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.IntegerField(blank=True, null=True)), + ('time', models.IntegerField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Database Lock', + 'verbose_name_plural': 'Database Locks', + 'db_table': 'co_database_lock', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoEntity', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('data', models.BinaryField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Entity', + 'verbose_name_plural': 'Entities', + 'db_table': 'co_entity', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoEntityMap', + fields=[ + ('id', models.IntegerField(primary_key=True, serialize=False)), + ('entity', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Entity Mapping', + 'verbose_name_plural': 'Entity Mappings', + 'db_table': 'co_entity_map', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoMaterialMap', + fields=[ + ('id', models.IntegerField(primary_key=True, serialize=False)), + ('material', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Material Mapping', + 'verbose_name_plural': 'Material Mappings', + 'db_table': 'co_material_map', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoSession', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.IntegerField(blank=True, null=True)), + ('wid', models.IntegerField(blank=True, null=True)), + ('x', models.IntegerField(blank=True, null=True)), + ('y', models.IntegerField(blank=True, null=True)), + ('z', models.IntegerField(blank=True, null=True)), + ('action', models.IntegerField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Session', + 'verbose_name_plural': 'Sessions', + 'db_table': 'co_session', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoSign', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.IntegerField(blank=True, null=True)), + ('wid', models.IntegerField(blank=True, null=True)), + ('x', models.IntegerField(blank=True, null=True)), + ('y', models.IntegerField(blank=True, null=True)), + ('z', models.IntegerField(blank=True, null=True)), + ('color', models.IntegerField(blank=True, null=True)), + ('line_1', models.TextField(blank=True, null=True)), + ('line_2', models.TextField(blank=True, null=True)), + ('line_3', models.TextField(blank=True, null=True)), + ('line_4', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Sign', + 'verbose_name_plural': 'Signs', + 'db_table': 'co_sign', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoSkull', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('owner', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Skull', + 'verbose_name_plural': 'Skulls', + 'db_table': 'co_skull', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoUser', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('user', models.TextField(blank=True, null=True)), + ('uuid', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'User', + 'verbose_name_plural': 'Users', + 'db_table': 'co_user', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoUsernameLog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('uuid', models.TextField(blank=True, null=True)), + ('user', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Username', + 'verbose_name_plural': 'Usernames', + 'db_table': 'co_username_log', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoVersion', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.IntegerField(blank=True, null=True)), + ('version', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'Version', + 'verbose_name_plural': 'Versions', + 'db_table': 'co_version', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoWorld', + fields=[ + ('id', models.IntegerField(primary_key=True, serialize=False)), + ('world', models.TextField(blank=True, null=True)), + ], + options={ + 'verbose_name': 'World', + 'verbose_name_plural': 'Worlds', + 'db_table': 'co_world', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CoreProtectUser', + fields=[ + ], + options={ + 'permissions': (('coreprotect_partial', 'Can use CoreProtect GUI except Command/Chat searches'), ('coreprotect_full', 'Can use full CoreProtect GUI'), ('coreprotect_activity', 'Can use CoreProtect Activity Monitor')), + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('auth.user',), + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/migrations/__init__.py b/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models.py b/models.py new file mode 100644 index 0000000..d21c3ad --- /dev/null +++ b/models.py @@ -0,0 +1,289 @@ +from django.db import models +from django.contrib.auth.models import User + + +class CoreProtectUser(User): + + class Meta: + proxy = True + permissions = ( + ('coreprotect_partial', 'Can use CoreProtect GUI except Command/Chat searches'), + ('coreprotect_full', 'Can use full CoreProtect GUI'), + ('coreprotect_activity', 'Can use CoreProtect Activity Monitor'), + ) + + +class CoArtMap(models.Model): + id = models.IntegerField(primary_key=True) + art = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_art_map' + verbose_name = 'Art Map' + verbose_name_plural = 'Art Maps' + + def __str__(self): + return self.art + + +class CoBlock(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.IntegerField(blank=True, null=True) + wid = models.IntegerField(blank=True, null=True) + x = models.IntegerField(blank=True, null=True) + y = models.IntegerField(blank=True, null=True) + z = models.IntegerField(blank=True, null=True) + type = models.IntegerField(blank=True, null=True) + data = models.IntegerField(blank=True, null=True) + meta = models.BinaryField(blank=True, null=True) + blockdata = models.BinaryField(blank=True, null=True) + action = models.IntegerField(blank=True, null=True) + rolled_back = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_block' + verbose_name = 'Block' + verbose_name_plural = 'Blocks' + + def __str__(self): + return self.type + + +class CoBlockdataMap(models.Model): + id = models.IntegerField(primary_key=True) + data = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_blockdata_map' + verbose_name = 'BlockData Map' + verbose_name_plural = 'BlockData Maps' + + def __str__(self): + return self.data + + +class CoChat(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.IntegerField(blank=True, null=True) + message = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_chat' + verbose_name = 'Chat Message' + verbose_name_plural = 'Chat Messages' + + def __str__(self): + return self.message + + +class CoCommand(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.IntegerField(blank=True, null=True) + message = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_command' + verbose_name = 'Command' + verbose_name_plural = 'Commands' + + def __str__(self): + return self.message + + +class CoContainer(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.IntegerField(blank=True, null=True) + wid = models.IntegerField(blank=True, null=True) + x = models.IntegerField(blank=True, null=True) + y = models.IntegerField(blank=True, null=True) + z = models.IntegerField(blank=True, null=True) + type = models.IntegerField(blank=True, null=True) + data = models.IntegerField(blank=True, null=True) + amount = models.IntegerField(blank=True, null=True) + metadata = models.BinaryField(blank=True, null=True) + action = models.IntegerField(blank=True, null=True) + rolled_back = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_container' + verbose_name = 'Container Transaction' + verbose_name_plural = 'Container Transactions' + + def __str__(self): + return self.user + + +class CoDatabaseLock(models.Model): + status = models.IntegerField(blank=True, null=True) + time = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_database_lock' + verbose_name = 'Database Lock' + verbose_name_plural = 'Database Locks' + + def __str__(self): + return self.status + + +class CoEntity(models.Model): + time = models.IntegerField(blank=True, null=True) + data = models.BinaryField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_entity' + verbose_name = 'Entity' + verbose_name_plural = 'Entities' + + def __str__(self): + return self.time + + +class CoEntityMap(models.Model): + id = models.IntegerField(primary_key=True) + entity = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_entity_map' + verbose_name = 'Entity Mapping' + verbose_name_plural = 'Entity Mappings' + + def __str__(self): + return self.entity + + +class CoMaterialMap(models.Model): + id = models.IntegerField(primary_key=True) + material = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_material_map' + verbose_name = 'Material Mapping' + verbose_name_plural = 'Material Mappings' + + def __str__(self): + return self.material + + +class CoSession(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.IntegerField(blank=True, null=True) + wid = models.IntegerField(blank=True, null=True) + x = models.IntegerField(blank=True, null=True) + y = models.IntegerField(blank=True, null=True) + z = models.IntegerField(blank=True, null=True) + action = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_session' + verbose_name = 'Session' + verbose_name_plural = 'Sessions' + + def __str__(self): + return self.user + + +class CoSign(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.IntegerField(blank=True, null=True) + wid = models.IntegerField(blank=True, null=True) + x = models.IntegerField(blank=True, null=True) + y = models.IntegerField(blank=True, null=True) + z = models.IntegerField(blank=True, null=True) + color = models.IntegerField(blank=True, null=True) + line_1 = models.TextField(blank=True, null=True) + line_2 = models.TextField(blank=True, null=True) + line_3 = models.TextField(blank=True, null=True) + line_4 = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_sign' + verbose_name = 'Sign' + verbose_name_plural = 'Signs' + + def __str__(self): + return "{} | {} | {} | {}".format(self.line_1, self.line_2, self.line_3, self.line_4) + + +class CoSkull(models.Model): + time = models.IntegerField(blank=True, null=True) + owner = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_skull' + verbose_name = 'Skull' + verbose_name_plural = 'Skulls' + + def __str__(self): + return self.owner + + +class CoUser(models.Model): + time = models.IntegerField(blank=True, null=True) + user = models.TextField(blank=True, null=True) + uuid = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_user' + verbose_name = 'User' + verbose_name_plural = 'Users' + + def __str__(self): + return self.user + + +class CoUsernameLog(models.Model): + time = models.IntegerField(blank=True, null=True) + uuid = models.TextField(blank=True, null=True) + user = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_username_log' + verbose_name = 'Username' + verbose_name_plural = 'Usernames' + + def __str__(self): + return self.user + + +class CoVersion(models.Model): + time = models.IntegerField(blank=True, null=True) + version = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_version' + verbose_name = 'Version' + verbose_name_plural = 'Versions' + + def __str__(self): + return self.version + + +class CoWorld(models.Model): + id = models.IntegerField(primary_key=True) + world = models.TextField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'co_world' + verbose_name = 'World' + verbose_name_plural = 'Worlds' + + def __str__(self): + return self.world diff --git a/router.py b/router.py new file mode 100644 index 0000000..46c052d --- /dev/null +++ b/router.py @@ -0,0 +1,38 @@ +class CoreProtectRouter: + """ + A router to control all database operations on models in the + auth application. + """ + def db_for_read(self, model, **hints): + """ + Attempts to read auth models go to auth_db. + """ + if model._meta.app_label == 'django_coreprotect': + return 'django_coreprotect' + return None + + def db_for_write(self, model, **hints): + """ + Attempts to write django_coreprotect models go to django_coreprotect. + """ + if model._meta.app_label == 'django_coreprotect': + return 'django_coreprotect' + return None + + def allow_relation(self, obj1, obj2, **hints): + """ + Allow relations if a model in the django_coreprotect app is involved. + """ + if obj1._meta.app_label == 'django_coreprotect' or \ + obj2._meta.app_label == 'django_coreprotect': + return True + return None + + def allow_migrate(self, db, app_label, model_name=None, **hints): + """ + Make sure the django_coreprotect app only appears in the 'django_coreprotect' + database. + """ + if app_label == 'django_coreprotect': + return db == 'django_coreprotect' + return None \ No newline at end of file diff --git a/static/coreprotect/css/datepicker.css b/static/coreprotect/css/datepicker.css new file mode 100644 index 0000000..8ff2cee --- /dev/null +++ b/static/coreprotect/css/datepicker.css @@ -0,0 +1,100 @@ +/*! + * jQuery UI Datepicker 1.10.0 + * http://jqueryui.com + * + * Copyright 2013 jQuery Foundation and other contributors + * Released under the MIT license. + * 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; + + &:hover { + cursor: pointer; + } +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + text-align: center; + line-height: 25px; +} +.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; +} \ No newline at end of file diff --git a/static/coreprotect/css/datetimepicker.css b/static/coreprotect/css/datetimepicker.css new file mode 100644 index 0000000..b93a85f --- /dev/null +++ b/static/coreprotect/css/datetimepicker.css @@ -0,0 +1,10 @@ +.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } +.ui-timepicker-div dl { text-align: left; } +.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } +.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } +.ui-timepicker-div td { font-size: 90%; } +.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } + +.ui-timepicker-rtl{ direction: rtl; } +.ui-timepicker-rtl dl { text-align: right; } +.ui-timepicker-rtl dl dd { margin: 0 65px 10px 10px; } \ No newline at end of file diff --git a/static/coreprotect/css/main.less b/static/coreprotect/css/main.less new file mode 100644 index 0000000..9bd17ab --- /dev/null +++ b/static/coreprotect/css/main.less @@ -0,0 +1,436 @@ + +/* + * Defaults, will be overridden by javascript + */ +@font: #444444; +@bg: #E7E7E2; + +@light: #eeeeee; +@medium: #dbdbd6; +@dark: #c2c2bd; +@accent: #ff6139; + +@border: #aaaaaa; +@link: #556677; +@error: #ff6358; + +/* + * Global variables + */ +@fonts: Ubuntu, Arial, Helvetica, Sans-serif; +@fontSize: 14px; + +@mainWidth: 1200px; +@leftWidth: 400px; +@rightWidth: 800px; + +/* + * Default elements + */ +body, html { + width: 100%; + height: 100%; + padding: 0; + margin: 0; +} +body { + background: @bg; + color: @font; + font-family: @fonts; + font-size: @fontSize; +} +a { + text-decoration: none; + color: @link; +} +a:hover { + color: @font; +} + +/* + * Inputs + */ +input[type=text], input[type=password]{ + padding: 5px; + margin: 0; + border: 0; + background: @medium; + color: @font; + font-family: @fonts; + border-bottom: 1px solid @border; + + &:hover, &:focus { + background: @light; + } +} +button, input[type=submit] { + margin: 0 2px; + padding: 10px 0; + width: 90px; + border: 1px solid @border; + background: @medium; + color: @link; + + &:hover { + cursor: pointer; + color: @font; + background: @light; + } + &:active { + background: @accent; + } +} +select { + background: @medium; + border: none; + padding: 0; + margin: 0; + color: @font; +} +#limit-container { + text-align: center; + #limit { + text-align: left; + } +} + +/* + * Custom inputs + */ +label.custom-check { + color: @link; + background: @medium; + cursor: pointer; + border-bottom: 1px solid @border; + height: 32px; + width: 100%; + display: block; + + &:hover { + color: @font; + background: @light; + } + &:active { + background: @accent; + } + input[type=checkbox] { + display: none; + + &:checked + div span { + background: @font; + } + &:checked + div { + height: 32px; + background: @accent; + color: @font; + } + } + div span { + display: inline-block; + margin: 8px; + width: 16px; + height: 16px; + background: @dark; + vertical-align: middle; + } +} +.text-full { + width: 179px; +} +.text-third { + width: 53px; +} + +/* + * Header + */ +header { + width: @mainWidth; + background: @dark; + border-bottom: 1px solid @border; + margin-bottom: 10px; + text-align: center; + position: relative; + + h1 { + padding: 10px; + margin: 0 auto; + } + select { + position: absolute; + right: 20px; + top: 20px; + } +} + +/* + * Main panels + */ +#main { + background: @dark; + margin: 0 auto; + width: @mainWidth; + min-height: 100%; + max-height: auto; +} +#left-pane { + float: left; + width: @leftWidth; +} +#right-pane { + float: left; + width: @rightWidth; +} + +/* + * Left pane + */ +#options-top { + background: @dark; + width: @leftWidth; +} +.option-column { + width: @leftWidth / 2; + float: left; +} +.option-column menu { + margin: 5px; + padding: 0; + + h3 { + text-align: center; + font-weight: bold; + font-size: 1.2em; + padding: 5px 0; + margin: 0; + } +} +#options-bottom { + width: @leftWidth; + margin-top: 10px; +} +#more-options-container { + width: @leftWidth; + float: left; +} + +/* + * Right pane + */ +#results-container { + padding: 5px; + margin-left: 10px; + margin-bottom: 70px; +} +#results-table { + width: 100%; + font-size: 0.9em; +} + +/* + * Footer + */ +#footer { + left: 0; + width: @mainWidth; + bottom: 0; + height: 60px; + position: fixed; + width: 100%; +} +#footer-container { + border-top: 1px solid @border; + margin: 0 auto; + background: @dark; + width: @mainWidth; + height: 100px; +} +#footer-info { + text-align: center; + line-height: 60px; + width: 100%; +} + +/* + * JQueryUI overrides + */ +.ui-button, .ui-state-default, .ui-state-hover { + background: @medium; + color: @link; + text-align: center !important; + + &:hover { + color: @font; + background: @light; + } + &:active { + background: @accent; + } +} +.ui-state-active, .ui-selected, .ui-selecting { + color: @font; + background: @accent !important; +} +.ui-slider-handle { + background: @accent; +} + +/* + * Datepicker Overrides + */ +.ui-datepicker { + background: @medium; + width: 240px !important; +} +.ui-slider { + background: @dark; +} +.ui-slider-handle { + background: @link; +} +.ui-datepicker-calendar td a { + text-align: center; + + &:hover { + color: @font !important; + background: @light !important; + } +} + +/* + * DataTables overrides + */ +.DataTables_sort_wrapper span { + display: none; +} +#results-table { + margin-top: 10px; + border-collapse: collapse; + cursor: pointer; + + table { + border-spacing: 0; + border-collapse: collapse; + } + th { + border-bottom: 1px solid @border; + padding: 5px 0; + + &[aria-sort="ascending"], &[aria-sort="descending"] { + color: @font; + background: @accent !important; + } + &:hover { + color: @font; + background: @light; + } + &:active { + background: @accent; + } + } + td { + margin: 0; + padding: 3px 5px; + } + tbody tr:hover { + background: @light; + } + .odd { + background: @medium; + } + .data { + max-width: 200px; + } +} +#results-table_length { + display: inline-block; + float: left; +} +#results-table_paginate { + display: inline-block; + text-align: center; + margin: 0 auto; + + a { + padding: 5px; + margin: 2px; + } + & > .ui-state-disabled { + opacity: 0.2; + } + span a.ui-state-disabled { + background: @accent; + color: @font; + } +} + +#results-table_filter { + display: inline-block; + float: right; + + label input { + margin-top: -3px; + } +} +.top { + text-align: center; +} + +/* + * Angular + */ +.ng-invalid { + background: @error !important; +} +.disabled { + cursor: default; + background: @dark !important; +} + +/* + * Miscellaneous + */ +.clearfix { + clear: both; +} +.hidden { + display: none; +} +.error { + background: @error !important; +} +.message { + text-align: center; + padding: 5px; + margin: 2px 0; +} + +/* + * Tooltip + */ +.tooltip { + padding: 15px; + color: @font; + border: 1px solid @border; + background: @medium; + position: fixed; + line-height: 1.5em; +} + +/* + * Login + */ +.login { + border: 1px solid @border; + width: 300px; + margin: 50px auto; + padding: 10px; + text-align: center; + + h3 { + margin: 0; + } + div { + margin-top: 10px; + } +} \ No newline at end of file diff --git a/static/coreprotect/css/slider.css b/static/coreprotect/css/slider.css new file mode 100644 index 0000000..cadd7d5 --- /dev/null +++ b/static/coreprotect/css/slider.css @@ -0,0 +1,77 @@ +/*! + * jQuery UI Slider 1.10.0 + * http://jqueryui.com + * + * Copyright 2013 jQuery Foundation and other contributors + * Released under the MIT license. + * 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; + + &:hover { + cursor: pointer; + } +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* For IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.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; +} diff --git a/static/coreprotect/js/controllers.js b/static/coreprotect/js/controllers.js new file mode 100644 index 0000000..cb10007 --- /dev/null +++ b/static/coreprotect/js/controllers.js @@ -0,0 +1,187 @@ +function inputsCtrl($scope, $http) { + $scope.actions = { + "-block": { + "display": "Block Break", + "selected": true + }, + "blockplace": { + "display": "Block Place", + "selected": false + }, + "interact": { + "display": "Interact", + "selected": false + }, + "sign": { + "display": "Sign Place", + "selected": false + }, + "chest": { + "display": "Chest Use", + "selected": false + }, + "chat": { + "display": "Chat", + "selected": false + }, + "command": { + "display": "Command", + "selected": false + }, + "session": { + "display": "Login/Logout", + "selected": false + } + }; + + $scope.worlds = []; + $http.post('', {action: "worlds"}).success(function(data) { + if(typeof data == "string") { + $('#loading-worlds').html('Error loading worlds from database.

Check your connection info'); + $('#results-container').html(data); + } else { + $scope.worlds = data; + } + }); + + $scope.texts = { + players: '', + x: '', + y: '', + z: '', + radius: '', + blocks: '', + from: '', + to: '' + } + + $scope.options = { + ignoreEnv: { + display: "Ignore Environment", + def: false, + val: false + }, + limit: { + display: "Limit", + def: 200, + val: 200 + } + } + + $scope.process = function() { + var actions = [], + worlds = [], + options = {}, + texts = {}; + + $.each($scope.actions, function(actionName, action) { + if(action.selected) + actions.push(actionName); + }); + $.each($scope.worlds, function(i, world) { + if(world.selected) + worlds.push(world.id); + }); + $.each($scope.options, function(optionName, option) { + options[optionName] = option.val; + }); + + texts.players = ($scope.texts.players || '').replace(/\s*,\s*/g, ',').replace(/^\s*|\s*$/g, '').split(','); + texts.blocks = ($scope.texts.blocks || '').replace(/\s*,\s*/g, ',').replace(/^\s*|\s*$/g, '').split(','); + texts.radius = $scope.texts.radius; + texts.from = isValidTime($scope.texts.from) ? toUnix($scope.texts.from) : 0; + texts.to = isValidTime($scope.texts.to) ? toUnix($scope.texts.to) : now(); + texts.x = $scope.texts.x; + texts.y = $scope.texts.y; + texts.z = $scope.texts.z; + texts.radius = $scope.texts.radius; + + process({actions: actions, worlds: worlds, options: options, texts: texts}); + } + + $scope.clear = function() { + for(var action in $scope.actions) { + $scope.actions[action].selected = false; + } + for(var world in $scope.worlds) { + $scope.worlds[world].selected = false; + } + for(var option in $scope.options) { + $scope.options[option].val = $scope.options[option].def; + } + for(var text in $scope.texts) { + $scope.texts[text] = ''; + } + $("#date-from, #date-to").val(''); + + angular.resetForm($scope, "optionsForm"); + } + + $scope.formIsInvalid = function() { + if($scope.fromDateIsInvalid() || $scope.toDateIsInvalid() || $scope.actionNotSelected()) + return true + } + + $scope.actionNotSelected = function() { + for(var action in $scope.actions) { + if($scope.actions[action].selected) { + return false; + } + } + return "Select an action."; + } + + $scope.fromDateIsInvalid = function() { + var from = $scope.texts.from; + var to = $scope.texts.to; + if(from) { + if(isNaN(Date.parse(from))) + return "From date is invalid"; + if(Date.parse(from) > new Date()) + return "From date is set in the future"; + if(to && Date.parse(from) > Date.parse(to)) + return "From date is after To date"; + } + } + + $scope.toDateIsInvalid = function() { + var from = $scope.texts.from; + var to = $scope.texts.to; + if(to) { + if(isNaN(Date.parse(to))) { + return "To date is invalid"; + } + } + } + + $scope.templateXray = function() { + $scope.actions['-block'].selected = true; + $scope.worlds[0].selected = true; + $scope.texts.y = "8"; + $scope.texts.radius = "8"; + $scope.texts.blocks = "diamond"; + $scope.options.limit.val = '1000'; + } +} + +angular.resetForm = function (scope, formName, defaults) { + $('form, form .ng-dirty').removeClass('ng-dirty').removeClass('ng-invalid').removeClass('ng-invalid-integer').addClass('ng-pristine'); + var form = scope[formName]; + form.$dirty = false; + form.$pristine = true; + form.$invalid = false; + for(var field in form) { + if(form[field].$pristine == false) { + form[field].$pristine = true; + } + if(form[field].$dirty == true) { + form[field].$dirty = false; + } + if(form[field].$valid == false) { + form[field].$valid = true; + } + if(form[field].$invalid == true) { + form[field].$invalid = false; + } + } +}; diff --git a/static/coreprotect/js/lib/angular.js b/static/coreprotect/js/lib/angular.js new file mode 100644 index 0000000..07ea01c --- /dev/null +++ b/static/coreprotect/js/lib/angular.js @@ -0,0 +1,161 @@ +/* + AngularJS v1.0.5 + (c) 2010-2012 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(X,Y,q){'use strict';function n(b,a,c){var d;if(b)if(H(b))for(d in b)d!="prototype"&&d!="length"&&d!="name"&&b.hasOwnProperty(d)&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==n)b.forEach(a,c);else if(!b||typeof b.length!=="number"?0:typeof b.hasOwnProperty!="function"&&typeof b.constructor!="function"||b instanceof L||ca&&b instanceof ca||xa.call(b)!=="[object Object]"||typeof b.callee==="function")for(d=0;d=0&&b.splice(c,1);return a}function U(b,a){if(pa(b)|| +b&&b.$evalAsync&&b.$watch)throw Error("Can't copy Window or Scope");if(a){if(b===a)throw Error("Can't copy equivalent objects or arrays");if(B(b))for(var c=a.length=0;c2?ha.call(arguments,2):[];return H(a)&&!(a instanceof RegExp)?c.length?function(){return arguments.length?a.apply(b,c.concat(ha.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}:a}function ic(b,a){var c=a;/^\$+/.test(b)?c=q:pa(a)?c="$WINDOW":a&&Y===a?c="$DOCUMENT":a&&a.$evalAsync&&a.$watch&&(c="$SCOPE");return c}function da(b,a){return JSON.stringify(b,ic,a?" ":null)}function ob(b){return A(b)?JSON.parse(b):b}function Va(b){b&&b.length!== +0?(b=y(""+b),b=!(b=="f"||b=="0"||b=="false"||b=="no"||b=="n"||b=="[]")):b=!1;return b}function qa(b){b=u(b).clone();try{b.html("")}catch(a){}var c=u("
").append(b).html();try{return b[0].nodeType===3?y(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+y(b)})}catch(d){return y(c)}}function Wa(b){var a={},c,d;n((b||"").split("&"),function(b){b&&(c=b.split("="),d=decodeURIComponent(c[0]),a[d]=x(c[1])?decodeURIComponent(c[1]):!0)});return a}function pb(b){var a=[];n(b,function(b, +d){a.push(Xa(d,!0)+(b===!0?"":"="+Xa(b,!0)))});return a.length?a.join("&"):""}function Ya(b){return Xa(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Xa(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(a?null:/%20/g,"+")}function jc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,h=["ng:app","ng-app","x-ng-app","data-ng-app"],f=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;n(h,function(a){h[a]=!0;c(Y.getElementById(a)); +a=a.replace(":","\\:");b.querySelectorAll&&(n(b.querySelectorAll("."+a),c),n(b.querySelectorAll("."+a+"\\:"),c),n(b.querySelectorAll("["+a+"]"),c))});n(d,function(a){if(!e){var b=f.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):n(a.attributes,function(b){if(!e&&h[b.name])e=a,g=b.value})}});e&&a(e,g?[g]:[])}function qb(b,a){b=u(b);a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");var c=rb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector", +function(a,b,c,h){a.$apply(function(){b.data("$injector",h);c(b)(a)})}]);return c}function Za(b,a){a=a||"_";return b.replace(kc,function(b,d){return(d?a:"")+b.toLowerCase()})}function $a(b,a,c){if(!b)throw Error("Argument '"+(a||"?")+"' is "+(c||"required"));return b}function ra(b,a,c){c&&B(b)&&(b=b[b.length-1]);$a(H(b),a,"not a function, got "+(b&&typeof b=="object"?b.constructor.name||"Object":typeof b));return b}function lc(b){function a(a,b,e){return a[b]||(a[b]=e())}return a(a(b,"angular",Object), +"module",function(){var b={};return function(d,e,g){e&&b.hasOwnProperty(d)&&(b[d]=null);return a(b,d,function(){function a(c,d,e){return function(){b[e||"push"]([c,d,arguments]);return k}}if(!e)throw Error("No module: "+d);var b=[],c=[],i=a("$injector","invoke"),k={_invokeQueue:b,_runBlocks:c,requires:e,name:d,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),filter:a("$filterProvider", +"register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:i,run:function(a){c.push(a);return this}};g&&i(g);return k})}})}function sb(b){return b.replace(mc,function(a,b,d,e){return e?d.toUpperCase():d}).replace(nc,"Moz$1")}function ab(b,a){function c(){var e;for(var b=[this],c=a,h,f,j,i,k,m;b.length;){h=b.shift();f=0;for(j=h.length;f 
"+b;a.removeChild(a.firstChild);bb(this,a.childNodes);this.remove()}else bb(this,b)}function cb(b){return b.cloneNode(!0)}function sa(b){tb(b);for(var a=0,b=b.childNodes||[];a-1}function wb(b,a){a&&n(a.split(" "),function(a){b.className=O((" "+b.className+" ").replace(/[\n\t]/g," ").replace(" "+O(a)+" "," "))})}function xb(b,a){a&&n(a.split(" "),function(a){if(!Da(b,a))b.className=O(b.className+" "+O(a))})}function bb(b,a){if(a)for(var a=!a.nodeName&&x(a.length)&&!pa(a)?a:[a],c=0;c4096&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!")}else{if(j.cookie!== +$){$=j.cookie;d=$.split("; ");r={};for(f=0;f0&&(r[unescape(e.substring(0,i))]=unescape(e.substring(i+1)))}return r}};f.defer=function(a,b){var c;o++;c=m(function(){delete t[c];e(a)},b||0);t[c]=!0;return c};f.defer.cancel=function(a){return t[a]?(delete t[a],l(a),e(C),!0):!1}}function wc(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new vc(b,d,a,c)}]}function xc(){this.$get=function(){function b(b,d){function e(a){if(a!=m){if(l){if(l== +a)l=a.n}else l=a;g(a.n,a.p);g(a,m);m=a;m.n=null}}function g(a,b){if(a!=b){if(a)a.p=b;if(b)b.n=a}}if(b in a)throw Error("cacheId "+b+" taken");var h=0,f=v({},d,{id:b}),j={},i=d&&d.capacity||Number.MAX_VALUE,k={},m=null,l=null;return a[b]={put:function(a,b){var c=k[a]||(k[a]={key:a});e(c);w(b)||(a in j||h++,j[a]=b,h>i&&this.remove(l.key))},get:function(a){var b=k[a];if(b)return e(b),j[a]},remove:function(a){var b=k[a];if(b){if(b==m)m=b.p;if(b==l)l=b.n;g(b.n,b.p);delete k[a];delete j[a];h--}},removeAll:function(){j= +{};h=0;k={};m=l=null},destroy:function(){k=f=j=null;delete a[b]},info:function(){return v({},f,{size:h})}}}var a={};b.info=function(){var b={};n(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function yc(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function Cb(b){var a={},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,g="Template must have exactly one root element. was: ",h=/^\s*(https?|ftp|mailto):/; +this.directive=function j(d,e){A(d)?($a(e,"directive"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];n(a[d],function(a){try{var g=b.invoke(a);if(H(g))g={compile:I(g)};else if(!g.compile&&g.link)g.compile=I(g.link);g.priority=g.priority||0;g.name=g.name||d;g.require=g.require||g.controller&&g.name;g.restrict=g.restrict||"A";e.push(g)}catch(h){c(h)}});return e}])),a[d].push(e)):n(d,nb(j));return this};this.urlSanitizationWhitelist=function(a){return x(a)? +(h=a,this):h};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document",function(b,i,k,m,l,t,o,p,s){function J(a,b,c){a instanceof u||(a=u(a));n(a,function(b,c){b.nodeType==3&&b.nodeValue.match(/\S+/)&&(a[c]=u(b).wrap("").parent()[0])});var d=z(a,b,a,c);return function(b,c){$a(b,"scope");for(var e=c?va.clone.call(a):a,g=0,i=e.length;gr.priority)break;if(W=r.scope)ua("isolated scope",K,r,D),M(W)&&(F(D,"ng-isolate-scope"),K=r),F(D,"ng-scope"),p=p||r;G=r.name;if(W=r.controller)x=x||{}, +ua("'"+G+"' controller",x[G],r,D),x[G]=r;if(W=r.transclude)ua("transclusion",ka,r,D),ka=r,l=r.priority,W=="element"?(S=u(b),D=c.$$element=u(Y.createComment(" "+G+": "+c[G]+" ")),b=D[0],C(e,u(S[0]),b),R=J(S,d,l)):(S=u(cb(b)).contents(),D.html(""),R=J(S,d));if(W=r.template)if(ua("template",z,r,D),z=r,W=Eb(W),r.replace){S=u("
"+O(W)+"
").contents();b=S[0];if(S.length!=1||b.nodeType!==1)throw Error(g+W);C(e,D,b);G={$attr:{}};a=a.concat(V(b,a.splice(v+1,a.length-(v+1)),G));$(c,G);y=a.length}else D.html(W); +if(r.templateUrl)ua("template",z,r,D),z=r,j=P(a.splice(v,a.length-v),j,D,c,e,r.replace,R),y=a.length;else if(r.compile)try{w=r.compile(D,c,R),H(w)?i(null,w):w&&i(w.pre,w.post)}catch(E){k(E,qa(D))}if(r.terminal)j.terminal=!0,l=Math.max(l,r.priority)}j.scope=p&&p.scope;j.transclude=ka&&R;return j}function r(d,e,i,g){var h=!1;if(a.hasOwnProperty(e))for(var l,e=b.get(e+c),o=0,m=e.length;ol.priority)&&l.restrict.indexOf(i)!=-1)d.push(l),h=!0}catch(t){k(t)}return h}function $(a, +b){var c=b.$attr,d=a.$attr,e=a.$$element;n(a,function(d,e){e.charAt(0)!="$"&&(b[e]&&(d+=(e==="style"?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});n(b,function(b,i){i=="class"?(F(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):i=="style"?e.attr("style",e.attr("style")+";"+b):i.charAt(0)!="$"&&!a.hasOwnProperty(i)&&(a[i]=b,d[i]=c[i])})}function P(a,b,c,d,e,i,h){var j=[],k,o,t=c[0],s=a.shift(),p=v({},s,{controller:null,templateUrl:null,transclude:null,scope:null});c.html("");m.get(s.templateUrl,{cache:l}).success(function(l){var m, +s,l=Eb(l);if(i){s=u("
"+O(l)+"
").contents();m=s[0];if(s.length!=1||m.nodeType!==1)throw Error(g+l);l={$attr:{}};C(e,c,m);V(m,a,l);$(d,l)}else m=t,c.html(l);a.unshift(p);k=K(a,m,d,h);for(o=z(c.contents(),h);j.length;){var ia=j.pop(),l=j.pop();s=j.pop();var r=j.pop(),D=m;s!==t&&(D=cb(m),C(l,u(s),D));k(function(){b(o,r,D,e,ia)},r,D,e,ia)}j=null}).error(function(a,b,c,d){throw Error("Failed to load template: "+d.url);});return function(a,c,d,e,i){j?(j.push(c),j.push(d),j.push(e),j.push(i)): +k(function(){b(o,c,d,e,i)},c,d,e,i)}}function G(a,b){return b.priority-a.priority}function ua(a,b,c,d){if(b)throw Error("Multiple directives ["+b.name+", "+c.name+"] asking for "+a+" on: "+qa(d));}function x(a,b){var c=i(b,!0);c&&a.push({priority:0,compile:I(function(a,b){var d=b.parent(),e=d.data("$binding")||[];e.push(c);F(d.data("$binding",e),"ng-binding");a.$watch(c,function(a){b[0].nodeValue=a})})})}function R(a,b,c,d){var e=i(c,!0);e&&b.push({priority:100,compile:I(function(a,b,c){b=c.$$observers|| +(c.$$observers={});d==="class"&&(e=i(c[d],!0));c[d]=q;(b[d]||(b[d]=[])).$$inter=!0;(c.$$observers&&c.$$observers[d].$$scope||a).$watch(e,function(a){c.$set(d,a)})})})}function C(a,b,c){var d=b[0],e=d.parentNode,i,g;if(a){i=0;for(g=a.length;i +0){var e=P[0],f=e.text;if(f==a||f==b||f==c||f==d||!a&&!b&&!c&&!d)return e}return!1}function f(b,c,d,f){return(b=h(b,c,d,f))?(a&&!b.json&&e("is not valid json",b),P.shift(),b):!1}function j(a){f(a)||e("is unexpected, expecting ["+a+"]",h())}function i(a,b){return function(c,d){return a(c,d,b)}}function k(a,b,c){return function(d,e){return b(d,e,a,c)}}function m(){for(var a=[];;)if(P.length>0&&!h("}",")",";","]")&&a.push(w()),!f(";"))return a.length==1?a[0]:function(b,c){for(var d,e=0;e","<=",">="))a=k(a,b.fn,s());return a}function J(){for(var a=n(),b;b=f("*","/","%");)a=k(a,b.fn,n());return a}function n(){var a;return f("+")?z():(a=f("-"))?k(r,a.fn,n()):(a=f("!"))?i(a.fn,n()):z()}function z(){var a;if(f("("))a=w(),j(")");else if(f("["))a=V();else if(f("{"))a=K();else{var b=f();(a=b.fn)||e("not a primary expression",b)}for(var c;b=f("(","[",".");)b.text==="("?(a=x(a,c),c=null):b.text==="["?(c=a,a=R(a)):b.text==="."?(c=a,a=u(a)):e("IMPOSSIBLE");return a}function V(){var a= +[];if(g().text!="]"){do a.push(G());while(f(","))}j("]");return function(b,c){for(var d=[],e=0;e1;d++){var e=a.shift(),g=b[e];g||(g={},b[e]=g);b=g}return b[a.shift()]= +c}function gb(b,a,c){if(!a)return b;for(var a=a.split("."),d,e=b,g=a.length,h=0;h7),hasEvent:function(c){if(c=="input"&&Z==9)return!1;if(w(a[c])){var e=b.document.createElement("div");a[c]="on"+c in e}return a[c]},csp:!1}}]}function Uc(){this.$get=I(X)}function Nb(b){var a={},c,d,e;if(!b)return a;n(b.split("\n"),function(b){e=b.indexOf(":");c=y(O(b.substr(0, +e)));d=O(b.substr(e+1));c&&(a[c]?a[c]+=", "+d:a[c]=d)});return a}function Ob(b){var a=M(b)?b:q;return function(c){a||(a=Nb(b));return c?a[y(c)]||null:a}}function Pb(b,a,c){if(H(c))return c(b,a);n(c,function(c){b=c(b,a)});return b}function Vc(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d=this.defaults={transformResponse:[function(d){A(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=ob(d,!0)));return d}],transformRequest:[function(a){return M(a)&&xa.apply(a)!=="[object File]"?da(a):a}], +headers:{common:{Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"},post:{"Content-Type":"application/json;charset=utf-8"},put:{"Content-Type":"application/json;charset=utf-8"}}},e=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,j,i,k){function m(a){function c(a){var b=v({},a,{data:Pb(a.data,a.headers,f)});return 200<=a.status&&a.status<300?b:i.reject(b)}a.method=ma(a.method);var e=a.transformRequest|| +d.transformRequest,f=a.transformResponse||d.transformResponse,g=d.headers,g=v({"X-XSRF-TOKEN":b.cookies()["XSRF-TOKEN"]},g.common,g[y(a.method)],a.headers),e=Pb(a.data,Ob(g),e),j;w(a.data)&&delete g["Content-Type"];j=l(a,e,g);j=j.then(c,c);n(p,function(a){j=a(j)});j.success=function(b){j.then(function(c){b(c.data,c.status,c.headers,a)});return j};j.error=function(b){j.then(null,function(c){b(c.data,c.status,c.headers,a)});return j};return j}function l(b,c,d){function e(a,b,c){n&&(200<=a&&a<300?n.put(q, +[a,b,Nb(c)]):n.remove(q));f(b,a,c);j.$apply()}function f(a,c,d){c=Math.max(c,0);(200<=c&&c<300?k.resolve:k.reject)({data:a,status:c,headers:Ob(d),config:b})}function h(){var a=Aa(m.pendingRequests,b);a!==-1&&m.pendingRequests.splice(a,1)}var k=i.defer(),l=k.promise,n,p,q=t(b.url,b.params);m.pendingRequests.push(b);l.then(h,h);b.cache&&b.method=="GET"&&(n=M(b.cache)?b.cache:o);if(n)if(p=n.get(q))if(p.then)return p.then(h,h),p;else B(p)?f(p[1],p[0],U(p[2])):f(p,200,{});else n.put(q,l);p||a(b.method, +q,c,e,d,b.timeout,b.withCredentials);return l}function t(a,b){if(!b)return a;var c=[];fc(b,function(a,b){a==null||a==q||(M(a)&&(a=da(a)),c.push(encodeURIComponent(b)+"="+encodeURIComponent(a)))});return a+(a.indexOf("?")==-1?"?":"&")+c.join("&")}var o=c("$http"),p=[];n(e,function(a){p.push(A(a)?k.get(a):k.invoke(a))});m.pendingRequests=[];(function(a){n(arguments,function(a){m[a]=function(b,c){return m(v(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){n(arguments,function(a){m[a]= +function(b,c,d){return m(v(d||{},{method:a,url:b,data:c}))}})})("post","put");m.defaults=d;return m}]}function Wc(){this.$get=["$browser","$window","$document",function(b,a,c){return Xc(b,Yc,b.defer,a.angular.callbacks,c[0],a.location.protocol.replace(":",""))}]}function Xc(b,a,c,d,e,g){function h(a,b){var c=e.createElement("script"),d=function(){e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;Z?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror= +d;e.body.appendChild(c)}return function(e,j,i,k,m,l,t){function o(a,c,d,e){c=(j.match(Gb)||["",g])[1]=="file"?d?200:404:c;a(c==1223?204:c,d,e);b.$$completeOutstandingRequest(C)}b.$$incOutstandingRequestCount();j=j||b.url();if(y(e)=="jsonp"){var p="_"+(d.counter++).toString(36);d[p]=function(a){d[p].data=a};h(j.replace("JSON_CALLBACK","angular.callbacks."+p),function(){d[p].data?o(k,200,d[p].data):o(k,-2);delete d[p]})}else{var s=new a;s.open(e,j,!0);n(m,function(a,b){a&&s.setRequestHeader(b,a)}); +var q;s.onreadystatechange=function(){if(s.readyState==4){var a=s.getAllResponseHeaders(),b=["Cache-Control","Content-Language","Content-Type","Expires","Last-Modified","Pragma"];a||(a="",n(b,function(b){var c=s.getResponseHeader(b);c&&(a+=b+": "+c+"\n")}));o(k,q||s.status,s.responseText,a)}};if(t)s.withCredentials=!0;s.send(i||"");l>0&&c(function(){q=-1;s.abort()},l)}}}function Zc(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0, +maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),SHORTMONTH:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),DAY:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),SHORTDAY:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","), +AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return b===1?"one":"other"}}}}function $c(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,f,j){var i=c.defer(),k=i.promise,m=x(j)&&!j,f=a.defer(function(){try{i.resolve(e())}catch(a){i.reject(a),d(a)}m||b.$apply()},f),j=function(){delete g[k.$$timeoutId]}; +k.$$timeoutId=f;g[f]=i;k.then(j,j);return k}var g={};e.cancel=function(b){return b&&b.$$timeoutId in g?(g[b.$$timeoutId].reject("canceled"),a.defer.cancel(b.$$timeoutId)):!1};return e}]}function Qb(b){function a(a,e){return b.factory(a+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Rb);a("date",Sb);a("filter",ad);a("json",bd);a("limitTo",cd);a("lowercase",dd);a("number",Tb);a("orderBy",Ub);a("uppercase",ed)}function ad(){return function(b, +a){if(!B(b))return b;var c=[];c.check=function(a){for(var b=0;b-1;case "object":for(var c in a)if(c.charAt(0)!=="$"&&d(a[c],b))return!0;return!1;case "array":for(c=0;ce+1?h="0":(f=h,i=!0)}if(!i){h=(h.split(Wb)[1]||"").length;w(e)&&(e=Math.min(Math.max(a.minFrac,h),a.maxFrac));var h=Math.pow(10,e),b=Math.round(b*h)/h,b=(""+b).split(Wb),h=b[0],b=b[1]||"",i=0,k=a.lgSize, +m=a.gSize;if(h.length>=k+m)for(var i=h.length-k,l=0;l0||e>-c)e+= +c;e===0&&c==-12&&(e=12);return jb(e,a,d)}}function Ka(b,a){return function(c,d){var e=c["get"+b](),g=ma(a?"SHORT"+b:b);return d[g][e]}}function Sb(b){function a(a){var b;if(b=a.match(c)){var a=new Date(0),g=0,h=0;b[9]&&(g=E(b[9]+b[10]),h=E(b[9]+b[11]));a.setUTCFullYear(E(b[1]),E(b[2])-1,E(b[3]));a.setUTCHours(E(b[4]||0)-g,E(b[5]||0)-h,E(b[6]||0),E(b[7]||0))}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g= +"",h=[],f,j,e=e||"mediumDate",e=b.DATETIME_FORMATS[e]||e;A(c)&&(c=fd.test(c)?E(c):a(c));Ra(c)&&(c=new Date(c));if(!oa(c))return c;for(;e;)(j=gd.exec(e))?(h=h.concat(ha.call(j,1)),e=h.pop()):(h.push(e),e=null);n(h,function(a){f=hd[a];g+=f?f(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function bd(){return function(b){return da(b,!0)}}function cd(){return function(b,a){if(!(b instanceof Array))return b;var a=E(a),c=[],d,e;if(!b||!(b instanceof Array))return c;a>b.length? +a=b.length:a<-b.length&&(a=-b.length);a>0?(d=0,e=a):(d=b.length+a,e=b.length);for(;dm?(d.$setValidity("maxlength",!1),q):(d.$setValidity("maxlength",!0),a)};d.$parsers.push(c);d.$formatters.push(c)}}function kb(b,a){b="ngClass"+b;return Q(function(c,d,e){function g(b){if(a===!0||c.$index%2===a)j&&b!==j&&h(j),f(b);j=b}function h(a){M(a)&&!B(a)&&(a=Sa(a,function(a,b){if(a)return b}));d.removeClass(B(a)? +a.join(" "):a)}function f(a){M(a)&&!B(a)&&(a=Sa(a,function(a,b){if(a)return b}));a&&d.addClass(B(a)?a.join(" "):a)}var j=q;c.$watch(e[b],g,!0);e.$observe("class",function(){var a=c.$eval(e[b]);g(a,a)});b!=="ngClass"&&c.$watch("$index",function(d,g){var j=d%2;j!==g%2&&(j==a?f(c.$eval(e[b])):h(c.$eval(e[b])))})})}var y=function(b){return A(b)?b.toLowerCase():b},ma=function(b){return A(b)?b.toUpperCase():b},Z=E((/msie (\d+)/.exec(y(navigator.userAgent))||[])[1]),u,ca,ha=[].slice,Qa=[].push,xa=Object.prototype.toString, +Zb=X.angular||(X.angular={}),ta,fb,aa=["0","0","0"];C.$inject=[];na.$inject=[];fb=Z<9?function(b){b=b.nodeName?b:b[0];return b.scopeName&&b.scopeName!="HTML"?ma(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var kc=/[A-Z]/g,id={full:"1.0.5",major:1,minor:0,dot:5,codeName:"flatulent-propulsion"},Ca=L.cache={},Ba=L.expando="ng-"+(new Date).getTime(),oc=1,$b=X.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+ +a,c)},db=X.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)},mc=/([\:\-\_]+(.))/g,nc=/^moz([A-Z])/,va=L.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;this.bind("DOMContentLoaded",a);L(X).bind("load",a)},toString:function(){var b=[];n(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return b>=0?u(this[b]):u(this[this.length+b])},length:0,push:Qa,sort:[].sort,splice:[].splice},Fa={};n("multiple,selected,checked,disabled,readOnly,required".split(","), +function(b){Fa[y(b)]=b});var Ab={};n("input,select,option,textarea,button,form".split(","),function(b){Ab[ma(b)]=!0});n({data:vb,inheritedData:Ea,scope:function(b){return Ea(b,"$scope")},controller:yb,injector:function(b){return Ea(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Da,css:function(b,a,c){a=sb(a);if(x(c))b.style[a]=c;else{var d;Z<=8&&(d=b.currentStyle&&b.currentStyle[a],d===""&&(d="auto"));d=d||b.style[a];Z<=8&&(d=d===""?q:d);return d}},attr:function(b,a,c){var d= +y(a);if(Fa[d])if(x(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:q;else if(x(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),b===null?q:b},prop:function(b,a,c){if(x(c))b[a]=c;else return b[a]},text:v(Z<9?function(b,a){if(b.nodeType==1){if(w(a))return b.innerText;b.innerText=a}else{if(w(a))return b.nodeValue;b.nodeValue=a}}:function(b,a){if(w(a))return b.textContent;b.textContent=a},{$dv:""}), +val:function(b,a){if(w(a))return b.value;b.value=a},html:function(b,a){if(w(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Lc= +{n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'},ib={},Yc=X.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");};Qb.$inject=["$provide"];Rb.$inject=["$locale"];Tb.$inject=["$locale"];var Wb=".",hd={yyyy:N("FullYear",4),yy:N("FullYear",2,0,!0),y:N("FullYear",1),MMMM:Ka("Month"), +MMM:Ka("Month",!0),MM:N("Month",2,1),M:N("Month",1,1),dd:N("Date",2),d:N("Date",1),HH:N("Hours",2),H:N("Hours",1),hh:N("Hours",2,-12),h:N("Hours",1,-12),mm:N("Minutes",2),m:N("Minutes",1),ss:N("Seconds",2),s:N("Seconds",1),EEEE:Ka("Day"),EEE:Ka("Day",!0),a:function(a,c){return a.getHours()<12?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){var a=-1*a.getTimezoneOffset(),c=a>=0?"+":"";c+=jb(a/60,2)+jb(Math.abs(a%60),2);return c}},gd=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/, +fd=/^\d+$/;Sb.$inject=["$locale"];var dd=I(y),ed=I(ma);Ub.$inject=["$parse"];var jd=I({restrict:"E",compile:function(a,c){Z<=8&&(!c.href&&!c.name&&c.$set("href",""),a.append(Y.createComment("IE fix")));return function(a,c){c.bind("click",function(a){c.attr("href")||a.preventDefault()})}}}),lb={};n(Fa,function(a,c){var d=ea("ng-"+c);lb[d]=function(){return{priority:100,compile:function(){return function(a,g,h){a.$watch(h[d],function(a){h.$set(c,!!a)})}}}}});n(["src","href"],function(a){var c=ea("ng-"+ +a);lb[c]=function(){return{priority:99,link:function(d,e,g){g.$observe(c,function(c){c&&(g.$set(a,c),Z&&e.prop(a,g[a]))})}}}});var Na={$addControl:C,$removeControl:C,$setValidity:C,$setDirty:C};Xb.$inject=["$element","$attrs","$scope"];var Qa=function(a){return["$timeout",function(c){var d={name:"form",restrict:"E",controller:Xb,compile:function(){return{pre:function(a,d,h,f){if(!h.action){var j=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};$b(d[0],"submit",j);d.bind("$destroy", +function(){c(function(){db(d[0],"submit",j)},0,!1)})}var i=d.parent().controller("form"),k=h.name||h.ngForm;k&&(a[k]=f);i&&d.bind("$destroy",function(){i.$removeControl(f);k&&(a[k]=q);v(f,Na)})}}}};return a?v(U(d),{restrict:"EAC"}):d}]},kd=Qa(),ld=Qa(!0),md=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,nd=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/,od=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,bc={text:Pa,number:function(a,c,d,e,g,h){Pa(a,c,d,e,g,h);e.$parsers.push(function(a){var c= +T(a);return c||od.test(a)?(e.$setValidity("number",!0),a===""?null:c?a:parseFloat(a)):(e.$setValidity("number",!1),q)});e.$formatters.push(function(a){return T(a)?"":""+a});if(d.min){var f=parseFloat(d.min),a=function(a){return!T(a)&&aj?(e.$setValidity("max",!1),q):(e.$setValidity("max",!0),a)};e.$parsers.push(d);e.$formatters.push(d)}e.$formatters.push(function(a){return T(a)|| +Ra(a)?(e.$setValidity("number",!0),a):(e.$setValidity("number",!1),q)})},url:function(a,c,d,e,g,h){Pa(a,c,d,e,g,h);a=function(a){return T(a)||md.test(a)?(e.$setValidity("url",!0),a):(e.$setValidity("url",!1),q)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,h){Pa(a,c,d,e,g,h);a=function(a){return T(a)||nd.test(a)?(e.$setValidity("email",!0),a):(e.$setValidity("email",!1),q)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){w(d.name)&&c.attr("name",ya());c.bind("click", +function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,h=d.ngFalseValue;A(g)||(g=!0);A(h)||(h=!1);c.bind("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:h})},hidden:C,button:C,submit:C,reset:C}, +cc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,h){h&&(bc[y(g.type)]||bc.text)(d,e,g,h,c,a)}}}],Ma="ng-valid",La="ng-invalid",Oa="ng-pristine",Yb="ng-dirty",pd=["$scope","$exceptionHandler","$attrs","$element","$parse",function(a,c,d,e,g){function h(a,c){c=c?"-"+Za(c,"-"):"";e.removeClass((a?La:Ma)+c).addClass((a?Ma:La)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine= +!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var f=g(d.ngModel),j=f.assign;if(!j)throw Error(Db+d.ngModel+" ("+qa(e)+")");this.$render=C;var i=e.inheritedData("$formController")||Na,k=0,m=this.$error={};e.addClass(Oa);h(!0);this.$setValidity=function(a,c){if(m[a]!==!c){if(c){if(m[a]&&k--,!k)h(!0),this.$valid=!0,this.$invalid=!1}else h(!1),this.$invalid=!0,this.$valid=!1,k++;m[a]=!c;h(c,a);i.$setValidity(a,c,this)}};this.$setViewValue=function(d){this.$viewValue=d;if(this.$pristine)this.$dirty= +!0,this.$pristine=!1,e.removeClass(Oa).addClass(Yb),i.$setDirty();n(this.$parsers,function(a){d=a(d)});if(this.$modelValue!==d)this.$modelValue=d,j(a,d),n(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}})};var l=this;a.$watch(function(){var c=f(a);if(l.$modelValue!==c){var d=l.$formatters,e=d.length;for(l.$modelValue=c;e--;)c=d[e](c);if(l.$viewValue!==c)l.$viewValue=c,l.$render()}})}],qd=function(){return{require:["ngModel","^?form"],controller:pd,link:function(a,c,d,e){var g=e[0],h= +e[1]||Na;h.$addControl(g);c.bind("$destroy",function(){h.$removeControl(g)})}}},rd=I({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),dc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&(T(a)||a===!1))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},sd=function(){return{require:"ngModel", +link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){var c=[];a&&n(a.split(g),function(a){a&&c.push(O(a))});return c});e.$formatters.push(function(a){return B(a)?a.join(", "):q})}}},td=/^(true|false|\d+)$/,ud=function(){return{priority:100,compile:function(a,c){return td.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a,!1)})}}}},vd=Q(function(a,c,d){c.addClass("ng-binding").data("$binding", +d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==q?"":a)})}),wd=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],xd=[function(){return function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBindHtmlUnsafe);a.$watch(d.ngBindHtmlUnsafe,function(a){c.html(a||"")})}}],yd=kb("",!0),zd=kb("Odd",0),Ad=kb("Even",1),Bd=Q({compile:function(a,c){c.$set("ngCloak",q); +a.removeClass("ng-cloak")}}),Cd=[function(){return{scope:!0,controller:"@"}}],Dd=["$sniffer",function(a){return{priority:1E3,compile:function(){a.csp=!0}}}],ec={};n("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave".split(" "),function(a){var c=ea("ng-"+a);ec[c]=["$parse",function(d){return function(e,g,h){var f=d(h[c]);g.bind(y(a),function(a){e.$apply(function(){f(e,{$event:a})})})}}]});var Ed=Q(function(a,c,d){c.bind("submit",function(){a.$apply(d.ngSubmit)})}), +Fd=["$http","$templateCache","$anchorScroll","$compile",function(a,c,d,e){return{restrict:"ECA",terminal:!0,compile:function(g,h){var f=h.ngInclude||h.src,j=h.onload||"",i=h.autoscroll;return function(g,h){var l=0,n,o=function(){n&&(n.$destroy(),n=null);h.html("")};g.$watch(f,function(f){var s=++l;f?a.get(f,{cache:c}).success(function(a){s===l&&(n&&n.$destroy(),n=g.$new(),h.html(a),e(h.contents())(n),x(i)&&(!i||g.$eval(i))&&d(),n.$emit("$includeContentLoaded"),g.$eval(j))}).error(function(){s===l&& +o()}):o()})}}}}],Gd=Q({compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),Hd=Q({terminal:!0,priority:1E3}),Id=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,h){var f=h.count,j=g.attr(h.$attr.when),i=h.offset||0,k=e.$eval(j),m={},l=c.startSymbol(),t=c.endSymbol();n(k,function(a,e){m[e]=c(a.replace(d,l+f+"-"+i+t))});e.$watch(function(){var c=parseFloat(e.$eval(f));return isNaN(c)?"":(k[c]||(c=a.pluralCat(c-i)),m[c](e,g,!0))},function(a){g.text(a)})}}}], +Jd=Q({transclude:"element",priority:1E3,terminal:!0,compile:function(a,c,d){return function(a,c,h){var f=h.ngRepeat,h=f.match(/^\s*(.+)\s+in\s+(.*)\s*$/),j,i,k;if(!h)throw Error("Expected ngRepeat in form of '_item_ in _collection_' but got '"+f+"'.");f=h[1];j=h[2];h=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!h)throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '"+f+"'.");i=h[3]||h[1];k=h[2];var m=new eb;a.$watch(function(a){var e,f,h=a.$eval(j), +n=c,q=new eb,x,z,u,w,r,v;if(B(h))r=h||[];else{r=[];for(u in h)h.hasOwnProperty(u)&&u.charAt(0)!="$"&&r.push(u);r.sort()}x=r.length;e=0;for(f=r.length;eA;)u.pop().element.remove()}for(;r.length>y;)r.pop()[0].element.remove()}var i;if(!(i=p.match(d)))throw Error("Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '"+p+"'.");var j=c(i[2]||i[1]),k=i[4]||i[6],l=i[5],m=c(i[3]||""), +n=c(i[2]?i[1]:k),t=c(i[7]),r=[[{element:f,label:""}]];s&&(a(s)(e),s.removeClass("ng-scope"),s.remove());f.html("");f.bind("change",function(){e.$apply(function(){var a,c=t(e)||[],d={},h,i,j,m,p,s;if(o){i=[];m=0;for(s=r.length;m@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}'); diff --git a/static/coreprotect/js/lib/angularui.js b/static/coreprotect/js/lib/angularui.js new file mode 100644 index 0000000..ddb3c4b --- /dev/null +++ b/static/coreprotect/js/lib/angularui.js @@ -0,0 +1,1461 @@ +/** + * AngularUI - The companion suite for AngularJS + * @version v0.4.0 - 2013-02-15 + * @link http://angular-ui.github.com + * @license MIT License, http://www.opensource.org/licenses/MIT + */ + + +angular.module('ui.config', []).value('ui.config', {}); +angular.module('ui.filters', ['ui.config']); +angular.module('ui.directives', ['ui.config']); +angular.module('ui', ['ui.filters', 'ui.directives', 'ui.config']); + +/** + * Animates the injection of new DOM elements by simply creating the DOM with a class and then immediately removing it + * Animations must be done using CSS3 transitions, but provide excellent flexibility + * + * @todo Add proper support for animating out + * @param [options] {mixed} Can be an object with multiple options, or a string with the animation class + * class {string} the CSS class(es) to use. For example, 'ui-hide' might be an excellent alternative class. + * @example
  • {{item}}
  • + */ +angular.module('ui.directives').directive('uiAnimate', ['ui.config', '$timeout', function (uiConfig, $timeout) { + var options = {}; + if (angular.isString(uiConfig.animate)) { + options['class'] = uiConfig.animate; + } else if (uiConfig.animate) { + options = uiConfig.animate; + } + return { + restrict: 'A', // supports using directive as element, attribute and class + link: function ($scope, element, attrs) { + var opts = {}; + if (attrs.uiAnimate) { + opts = $scope.$eval(attrs.uiAnimate); + if (angular.isString(opts)) { + opts = {'class': opts}; + } + } + opts = angular.extend({'class': 'ui-animate'}, options, opts); + + element.addClass(opts['class']); + $timeout(function () { + element.removeClass(opts['class']); + }, 20, false); + } + }; +}]); + + +/* +* AngularJs Fullcalendar Wrapper for the JQuery FullCalendar +* API @ http://arshaw.com/fullcalendar/ +* +* Angular Calendar Directive that takes in the [eventSources] nested array object as the ng-model and watches (eventSources.length + eventSources[i].length) for changes. +* Can also take in multiple event urls as a source object(s) and feed the events per view. +* The calendar will watch any eventSource array and update itself when a delta is created +* An equalsTracker attrs has been added for use cases that would render the overall length tracker the same even though the events have changed to force updates. +* +*/ + +angular.module('ui.directives').directive('uiCalendar',['ui.config', '$parse', function (uiConfig,$parse) { + uiConfig.uiCalendar = uiConfig.uiCalendar || {}; + //returns calendar + return { + require: 'ngModel', + restrict: 'A', + link: function(scope, elm, attrs, $timeout) { + var sources = scope.$eval(attrs.ngModel); + var tracker = 0; + /* returns the length of all source arrays plus the length of eventSource itself */ + var getSources = function () { + var equalsTracker = scope.$eval(attrs.equalsTracker); + tracker = 0; + angular.forEach(sources,function(value,key){ + if(angular.isArray(value)){ + tracker += value.length; + } + }); + if(angular.isNumber(equalsTracker)){ + return tracker + sources.length + equalsTracker; + }else{ + return tracker + sources.length; + } + }; + /* update the calendar with the correct options */ + function update() { + //calendar object exposed on scope + scope.calendar = elm.html(''); + var view = scope.calendar.fullCalendar('getView'); + if(view){ + view = view.name; //setting the default view to be whatever the current view is. This can be overwritten. + } + /* If the calendar has options added then render them */ + var expression, + options = { + defaultView : view, + eventSources: sources + }; + if (attrs.uiCalendar) { + expression = scope.$eval(attrs.uiCalendar); + } else { + expression = {}; + } + angular.extend(options, uiConfig.uiCalendar, expression); + scope.calendar.fullCalendar(options); + } + update(); + /* watches all eventSources */ + scope.$watch(getSources, function( newVal, oldVal ) + { + update(); + }); + } + }; +}]); +/*global angular, CodeMirror, Error*/ +/** + * Binds a CodeMirror widget to a