├── .gitignore ├── LICENCE ├── README ├── README.rst ├── __init__.py ├── manage.py ├── rpg ├── __init__.py ├── fixtures │ └── initial_data.json ├── models.py └── views.py ├── run.py ├── settings.py ├── static ├── 1_blue.gif ├── character.js ├── characters.html ├── common.js ├── effects.js ├── face.html ├── face.svg ├── game.css ├── game.js ├── jquery.js ├── jquery.json-2.2.js ├── jquery.min.js ├── jscolor │ ├── arrow.gif │ ├── cross.gif │ ├── demo.html │ ├── hs.png │ ├── hv.png │ └── jscolor.js ├── output.py ├── sound.mp3 ├── soundmanager2.js ├── soundmanager2.swf ├── svg2canvas.jar ├── tileset.png ├── walk.gif ├── walk2.png └── walk2.xcf ├── templates ├── 404.html ├── 500.html ├── index.html └── message.html └── urls.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | dev.db 3 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, Batiste Bieler 2 | All rights reserved. 3 | 4 | The graphic/sound contents in this package are the property of their 5 | authors and follow their own licence. The folowing licence 6 | apply only on the source code of this package. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following 16 | disclaimer in the documentation and/or other materials provided 17 | with the distribution. 18 | * Neither the name of the author nor the names of other 19 | contributors may be used to endorse or promote products derived 20 | from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.rst 2 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | A browser based Role Playing Game 2 | ================================= 3 | 4 | A Role Playing Game skeleton that use django and gevent. To start the server, run:: 5 | 6 | $ python run.py 7 | 8 | Example chat room from http://bitbucket.org/denis/gevent/src/tip/examples/webchat/chat/views.py 9 | 10 | Tested on Opera, Firefox, Chrome. 11 | 12 | Screenshot 13 | ========== 14 | 15 | .. image:: http://batiste.dosimple.ch/django-rpg-screenshot.png 16 | 17 | 18 | Install 19 | ======= 20 | 21 | To install on a ubuntu distribution:: 22 | 23 | $ sudo apt-get install python python-django python-pip git sqlite3 24 | $ sudo pip install gevent 25 | $ git clone git://github.com/batiste/django-rpg.git 26 | $ cd django-rpg/ 27 | $ python manage.py syncdb 28 | $ python run.py 29 | 30 | 31 | Features 32 | ======== 33 | 34 | * The goal is to be massively multiplayer 35 | * Room Chat 36 | * Non player characters example 37 | * Basic example of spell 38 | * Map editing 39 | 40 | Goals 41 | ===== 42 | 43 | * Write down a gameplay 44 | * Player experience, spells learning, combact mode, quests, crafting 45 | * Add a second layer on the map for objects 46 | * Get some graphics designer involved 47 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/__init__.py -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from django.core.management import execute_manager 3 | try: 4 | import settings # Assumed to be in the same directory. 5 | except ImportError: 6 | import sys 7 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) 8 | sys.exit(1) 9 | 10 | if __name__ == "__main__": 11 | execute_manager(settings) 12 | -------------------------------------------------------------------------------- /rpg/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/rpg/__init__.py -------------------------------------------------------------------------------- /rpg/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | import simplejson 3 | import math 4 | import uuid 5 | 6 | # not use right now 7 | class Map(models.Model): 8 | 9 | name = models.CharField(max_length=50, blank=True) 10 | x = models.IntegerField() 11 | y = models.IntegerField() 12 | 13 | forbidden = [ 14 | [9, 1],[10, 2],[0, 9],[1, 9],[2, 9],[0, 10],[1, 10], 15 | [2, 10],[3, 10],[4, 10],[5, 10],[8, 9], [6, 8], [6, 10], 16 | [7, 9],[7, 8],[7, 10],[6, 7], [6, 9],[9, 7],[10, 7], 17 | [8, 8], [8 ,10], [9, 8], 18 | [10, 8],[9, 9],[9, 10],[10, 10] 19 | ] 20 | 21 | content = models.TextField() 22 | 23 | def serialized(self): 24 | return { 25 | "id":self.id, 26 | "x":self.x, 27 | "y":self.y, 28 | "name":self.name, 29 | "content":self.content.replace("\n", "") 30 | } 31 | 32 | # the grid is presented by vertical line first 33 | # then by horizontal line, eg: _ground[y][x] 34 | _ground = None 35 | 36 | def get_ground(self): 37 | try: 38 | self._ground = simplejson.loads(self.content.replace("\n", "")) 39 | except (ValueError): 40 | pass 41 | return self._ground 42 | 43 | def set_ground(self, content): 44 | self.content = content.replace("\n", "") 45 | self.get_ground() 46 | 47 | ground = property(get_ground, set_ground) 48 | 49 | def is_safe_position(self, pos): 50 | x = int(round(pos[0] / 16.)) 51 | y = int(round(pos[1] / 16.)) 52 | if self.ground is None: 53 | return False 54 | if x <= 0 or y <= 0: 55 | return False 56 | if y >= len(self.ground): 57 | return False 58 | if x >= len(self.ground[0]): 59 | return False 60 | block = self.ground[y][x] 61 | if block in self.forbidden: 62 | return False 63 | return True 64 | 65 | 66 | def __unicode__(self): 67 | return self.name 68 | 69 | 70 | class Player(models.Model): 71 | 72 | def __init__(self, *args, **kwargs): 73 | if not kwargs.get('private_key', False): 74 | kwargs['private_key'] = str(uuid.uuid4()) 75 | if not kwargs.get('public_key', False): 76 | kwargs['public_key'] = str(uuid.uuid4()) 77 | 78 | return super(Player, self).__init__(*args, **kwargs) 79 | 80 | public_key = models.CharField(max_length=50) 81 | private_key = models.CharField(max_length=50) 82 | name = models.CharField(max_length=50) 83 | xp = models.IntegerField(default=0) 84 | vitality = models.IntegerField(default=20) 85 | str_position = models.CharField(max_length=20, default='[32,32]') 86 | 87 | def set_position(self, pos): 88 | self.str_position = str(pos) 89 | 90 | def get_position(self): 91 | return simplejson.loads(self.str_position) 92 | 93 | position = property(get_position, set_position) 94 | 95 | map_id = models.IntegerField(null=True) 96 | 97 | def pub(self): 98 | return { 99 | 'name':self.name, 100 | 'key':self.public_key, 101 | 'position':self.position, 102 | } 103 | 104 | def priv(self): 105 | return { 106 | 'name':self.name, 107 | 'key':self.public_key, 108 | 'private_key':self.private_key, 109 | 'position':self.position, 110 | } 111 | 112 | def __unicode__(self): 113 | return self.private_key 114 | 115 | 116 | class Fight(object): 117 | 118 | def __init__(self, room_map, player, adversary): 119 | self.public_key = str(uuid.uuid4()) 120 | self.player = player 121 | self.adversary = adversary 122 | self.room_map = room_map 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /rpg/views.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | import simplejson 3 | from django.shortcuts import render_to_response 4 | from django.template.loader import render_to_string 5 | from django.http import HttpResponse 6 | from gevent.event import Event 7 | from gevent import spawn_later 8 | from django.conf import settings 9 | from django.utils.html import escape 10 | 11 | from rpg.models import Map, Player, Fight 12 | import random 13 | 14 | def pub_key(request): 15 | return request.COOKIES.get('public_key', False) 16 | 17 | def priv_key(request): 18 | return request.COOKIES.get('private_key', False) 19 | 20 | class ChatRoom(object): 21 | 22 | def __init__(self, room_id): 23 | self.pk = room_id 24 | self.room_map = Map.objects.get(pk=self.pk) 25 | self.last_message = [] 26 | self.players = [] 27 | spawn_later(5, self.move_pnj) 28 | self.cache = [] 29 | self.room_event = Event() 30 | self.event_cursor = 0 31 | self.event_buffer = [] 32 | self.fights = [] 33 | for v in range(0, 9): 34 | self.event_buffer.append(None) 35 | npc = Player(name='Wise man') 36 | self.npc = npc 37 | self.players.append(self.npc) 38 | self.new_event(['new_player', npc.pub()]) 39 | 40 | def move_pnj(self): 41 | npc = self.npc 42 | if npc: 43 | pos = [npc.position[0], npc.position[1]] 44 | pos[0] += random.randint(-50, 50) 45 | pos[1] += random.randint(-50, 50) 46 | safe = self.room_map.is_safe_position(pos) 47 | if safe: 48 | npc.position = pos 49 | self.new_event(['update_player_position', 50 | [npc.public_key, npc.position]]) 51 | spawn_later(5, self.move_pnj) 52 | 53 | def main(self, request): 54 | key = priv_key(request) 55 | player = self.get_player(key) 56 | return render_to_response( 57 | 'index.html', 58 | { 59 | 'player':player, 60 | 'map':self.room_map, 61 | 'map_content':self.room_map.content.replace("\n", ""), 62 | 'MEDIA_URL': settings.MEDIA_URL 63 | } 64 | ) 65 | 66 | def new_event(self, value): 67 | self.event_cursor += 1 68 | if self.event_cursor >= len(self.event_buffer): 69 | self.event_cursor = 0 70 | self.event_buffer[self.event_cursor] = value 71 | self.room_event.set() 72 | self.room_event.clear() 73 | 74 | def get_player(self, key): 75 | for p in self.players: 76 | if p.public_key == key: 77 | return p 78 | if p.private_key == key: 79 | return p 80 | return None 81 | 82 | def remove_player(self, key): 83 | for p in self.players: 84 | if p.private_key == key: 85 | self.players.remove(p) 86 | return p 87 | return None 88 | 89 | def save_map(self, request): 90 | self.room_map.ground = request.POST['content'] 91 | self.room_map.save() 92 | self.new_event({'update_map':self.room_map.serialized()}) 93 | return json_response([1]) 94 | 95 | def player_new(self, request): 96 | key = priv_key(request) 97 | new_player = self.get_player(key) 98 | if not new_player: 99 | name = escape(request.POST['body']) 100 | new_player = Player( 101 | name=name, 102 | position='[20,20]' 103 | ) 104 | new_player.save() 105 | event_list = [] 106 | # send all the other player to the new one 107 | for player in self.players: 108 | event_list.append(['new_player', player.pub()]) 109 | self.players.append(new_player) 110 | self.new_event(['new_player', new_player.pub()]) 111 | response = json_response({ 112 | 'you':new_player.priv(), 113 | 'events':event_list 114 | }) 115 | response.set_cookie('private_key', new_player.private_key) 116 | return response 117 | 118 | def player_update_position(self, request): 119 | key = priv_key(request) 120 | player = self.get_player(key) 121 | pos = request.POST.get('body', False) 122 | if(pos): 123 | player.position = pos 124 | self.new_event([ 125 | 'update_player_position', 126 | [player.public_key, player.position] 127 | ]) 128 | return json_response([1]) 129 | 130 | def message_new(self, request): 131 | key = priv_key(request) 132 | player = self.get_player(key) 133 | msg = escape(request.POST['body']) 134 | #player.last_message = msg 135 | self.new_event(['last_message', [player.public_key, msg]]) 136 | return json_response([1]) 137 | 138 | def fight_new(self, request): 139 | key = priv_key(request) 140 | player = self.get_player(key) 141 | bad = Player(name='bad') 142 | self.new_event(['player_leave_room', player.pub()]) 143 | new_room.new_event(['new_player', player.pub()]) 144 | self.remove_player(key) 145 | adversary = Player(name='Rogue level 1') 146 | fight = Fight( 147 | player=player, 148 | adversary=adversary, 149 | room_map=self.room_map 150 | ) 151 | 152 | response.set_cookie('fight_key', fight.key) 153 | 154 | return json_response([1]) 155 | 156 | def room_updates(self, request): 157 | 158 | self.room_event.wait() 159 | 160 | cursor = int(request.POST.get('cursor', False)) 161 | # up to date 162 | if cursor == self.event_cursor: 163 | return json_response([1]) 164 | if cursor == False: 165 | cursor = self.event_cursor 166 | # increment to be at the same level that the last event 167 | cursor += 1 168 | if cursor >= len(self.event_buffer): 169 | cursor = 0 170 | 171 | event_list = [] 172 | # if there is more than just on event 173 | while(cursor != self.event_cursor): 174 | event = self.event_buffer[cursor] 175 | if event: 176 | event_list.append(self.event_buffer[cursor]) 177 | cursor += 1 178 | if cursor >= len(self.event_buffer): 179 | cursor = 0 180 | 181 | event_list.append(self.event_buffer[self.event_cursor]) 182 | event_list.append(['update_cursor', self.event_cursor]) 183 | 184 | return json_response(event_list) 185 | 186 | def effect(self, request): 187 | key = priv_key(request) 188 | player = self.get_player(key) 189 | effect_type = request.POST.get('type') 190 | self.new_event(['effect', [player.public_key, 191 | effect_type]]) 192 | return json_response([1]) 193 | 194 | def change_room(self, request): 195 | key = priv_key(request) 196 | player = self.get_player(key) 197 | direction = request.POST.get('direction') 198 | x = 0; y = 0 199 | pos = player.position 200 | if direction == 'left': 201 | pos[0] = 34 * 16 202 | x = -1 203 | if direction == 'right': 204 | pos[0] = 0 205 | x = +1 206 | if direction == 'top': 207 | pos[1] = 28 * 16 208 | y = -1 209 | if direction == 'bottom': 210 | pos[1] = 0 211 | y = +1 212 | player.position = pos 213 | old_map = Map.objects.get(pk=self.pk) 214 | room_map, created = Map.objects.get_or_create(x=old_map.x+x, 215 | y=old_map.y+y) 216 | self.new_event(['player_leave_room', player.pub()]) 217 | new_room = get_room(room_map.id) 218 | new_room.players.append(player) 219 | new_room.new_event(['new_player', player.pub()]) 220 | self.remove_player(key) 221 | # send all the other player 222 | event_list = [] 223 | for player in new_room.players: 224 | event_list.append(['new_player', player.pub()]) 225 | response = json_response({'change_room':room_map.serialized(), 226 | "events":event_list}) 227 | response.set_cookie('room_id', new_room.pk) 228 | return response 229 | 230 | rooms = {} 231 | def get_room(room_id): 232 | if rooms.has_key(room_id): 233 | room = rooms[room_id] 234 | else: 235 | room = ChatRoom(room_id) 236 | rooms[room_id] = room 237 | return room 238 | 239 | def room_dispacher(method): 240 | def _method(request): 241 | room_id = int(request.COOKIES.get('room_id', 1)) 242 | if rooms.has_key(room_id): 243 | room = rooms[room_id] 244 | else: 245 | room = ChatRoom(room_id) 246 | rooms[room_id] = room 247 | return getattr(room, method)(request) 248 | return _method 249 | 250 | # dispatch to rooms 251 | main = room_dispacher('main') 252 | message_new = room_dispacher('message_new') 253 | player_new = room_dispacher('player_new') 254 | player_update_position = room_dispacher('player_update_position') 255 | room_updates = room_dispacher('room_updates') 256 | change_room = room_dispacher('change_room') 257 | save_map = room_dispacher('save_map') 258 | effect = room_dispacher('effect') 259 | fight_new = room_dispacher('fight_new') 260 | 261 | def json_response(value, **kwargs): 262 | kwargs.setdefault('content_type', 'text/javascript; charset=UTF-8') 263 | return HttpResponse(simplejson.dumps(value), **kwargs) 264 | 265 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from gevent import monkey; monkey.patch_all() 3 | from gevent.wsgi import WSGIServer 4 | import sys 5 | import os 6 | import traceback 7 | from django.core.handlers.wsgi import WSGIHandler 8 | from django.core.management import call_command 9 | from django.core.signals import got_request_exception 10 | 11 | sys.path.append('..') 12 | os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' 13 | 14 | def exception_printer(sender, **kwargs): 15 | traceback.print_exc() 16 | 17 | got_request_exception.connect(exception_printer) 18 | 19 | call_command('syncdb') 20 | print 'Serving on 8088...' 21 | WSGIServer(('', 8088), WSGIHandler()).serve_forever() 22 | 23 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | from os.path import dirname, join, abspath 2 | __dir__ = dirname(abspath(__file__)) 3 | 4 | DEBUG = True 5 | TEMPLATE_DEBUG = DEBUG 6 | ADMINS = () 7 | MANAGERS = ADMINS 8 | DATABASE_ENGINE = 'sqlite3' 9 | DATABASE_NAME = 'dev.db' 10 | DATABASE_USER = '' 11 | DATABASE_PASSWORD = '' 12 | DATABASE_HOST = '' 13 | DATABASE_PORT = '' 14 | TIME_ZONE = 'America/Chicago' 15 | LANGUAGE_CODE = 'en-us' 16 | SITE_ID = 1 17 | USE_I18N = True 18 | MEDIA_ROOT = join(__dir__, 'static') 19 | 20 | MEDIA_URL = '/static/' 21 | SECRET_KEY = 'nv8(yg*&1-lon-8i-3jcs0y!01+rem*54051^5xt#^tzujdj!c' 22 | TEMPLATE_LOADERS = ( 23 | 'django.template.loaders.filesystem.load_template_source', 24 | 'django.template.loaders.app_directories.load_template_source', 25 | ) 26 | MIDDLEWARE_CLASSES = ( 27 | 'django.middleware.common.CommonMiddleware', 28 | 'django.contrib.sessions.middleware.SessionMiddleware', 29 | ) 30 | ROOT_URLCONF = 'urls' 31 | TEMPLATE_DIRS = ( 32 | join(__dir__, 'templates') 33 | ) 34 | INSTALLED_APPS = ( 35 | 'django.contrib.contenttypes', 36 | 'django.contrib.sessions', 37 | 'django.contrib.sites', 38 | 'rpg', 39 | ) 40 | -------------------------------------------------------------------------------- /static/1_blue.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/1_blue.gif -------------------------------------------------------------------------------- /static/characters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /static/common.js: -------------------------------------------------------------------------------- 1 | 2 | // evil 3 | Array.prototype.remove = function(from, to) { 4 | var rest = this.slice((to || from) + 1 || this.length); 5 | this.length = from < 0 ? this.length + from : from; 6 | return this.push.apply(this, rest); 7 | }; 8 | 9 | if (!window.console) window.console = {}; 10 | if (!window.console.log) window.console.log = function() {}; 11 | 12 | window.rpg = new Function(); 13 | 14 | rpg.other_players = []; 15 | 16 | rpg.norm_vector = function norm_vector(vect) { 17 | return Math.sqrt(vect[0]*vect[0]+vect[1]*vect[1]); 18 | }; 19 | 20 | rpg.normalize_vector = function normalize_vector(vect) { 21 | var norm = Math.sqrt(vect[0]*vect[0]+vect[1]*vect[1]); 22 | if(norm==0) 23 | return false 24 | vect[0] = vect[0] / norm; 25 | vect[1] = vect[1] / norm; 26 | return vect; 27 | }; 28 | 29 | rpg.get_player = function get_player(key) { 30 | for(var i=0; i < rpg.other_players.length; i++) { 31 | if(rpg.other_players[i] && rpg.other_players[i].public_key == key) 32 | return rpg.other_players[i] 33 | } 34 | return false; 35 | } 36 | 37 | rpg.postJSON = function(url, args, callback) { 38 | $.ajax({ 39 | url: url, 40 | data: $.param(args), 41 | dataType: "text", 42 | type: "POST", 43 | success: function(response) { 44 | callback(response); 45 | //console.log("SUCCESS:", response) 46 | }, 47 | error: function(response) { 48 | //console.log("ERROR:", response) 49 | } 50 | }); 51 | }; 52 | 53 | 54 | rpg.event_cursor = false; 55 | // polling update 56 | rpg.updater = { 57 | errorSleepTime: 500, 58 | cursor: null, 59 | 60 | poll: function() { 61 | var args = {}; 62 | if(rpg.event_cursor) 63 | args["cursor"] = rpg.event_cursor 64 | $.ajax({ 65 | url: "/a/room/updates", 66 | type: "POST", 67 | dataType: "text", 68 | data: $.param(args), 69 | success: rpg.updater.onSuccess, 70 | error: rpg.updater.onError 71 | }); 72 | }, 73 | 74 | onSuccess: function(response) { 75 | var json = $.evalJSON(response); 76 | for(var i=0; i '); 181 | map.append(dom_bloc); 182 | dom_line.push(dom_bloc); 183 | line.push(false); 184 | }; 185 | this.dom_blocs.push(dom_line); 186 | this.blocs.push(line); 187 | }; 188 | //map.append($('
')); 189 | this.load_new_map(blocs_init); 190 | }; 191 | 192 | Grid.prototype.get_bloc = function(indexes) { 193 | return this.blocs[indexes[1]][indexes[0]]; 194 | }; 195 | 196 | Grid.prototype.paint_bloc = function(dom_bloc) { 197 | //var bloc = $(e.target); 198 | if(dom_bloc.hasClass('bloc')) { 199 | var b_string = dom_bloc.attr('id').split('-'); 200 | var tile_pos_css = (-this.choosen_bloc[0]*17-1)+'px ' + (-this.choosen_bloc[1]*17-1)+'px'; 201 | this.blocs[parseInt(b_string[1])][parseInt(b_string[2])] = this.choosen_bloc; 202 | dom_bloc.css('background-position', tile_pos_css); 203 | }; 204 | }; 205 | 206 | Grid.prototype.is_bloc_walkable = function(bloc) { 207 | for(var i=0; i < this.forbidden.length; i++) { 208 | if(this.forbidden[i][0] == bloc[0] 209 | && this.forbidden[i][1] == bloc[1]) 210 | return false; 211 | }; 212 | return true; 213 | }; 214 | 215 | Grid.prototype.bloc_from_player_pos = function(pos) { 216 | if(this.is_loading_room) 217 | return; 218 | var bloc_indexes = [ 219 | Math.floor((pos[0]) / 16), 220 | Math.floor((pos[1]) / 16) 221 | ]; 222 | // check if the player is leaving the map 223 | var direction = false; 224 | if(bloc_indexes[0] < 0) { 225 | direction = "left"; 226 | } 227 | if(bloc_indexes[0] > (rpg.grid.width-1)) { 228 | direction = "right"; 229 | }; 230 | if(bloc_indexes[1] < 0) { 231 | direction = "top"; 232 | } 233 | if(bloc_indexes[1] > (rpg.grid.height-1)) { 234 | direction = "bottom"; 235 | } 236 | // load another map 237 | if(direction) { 238 | this.is_loading_room = true; 239 | rpg.postJSON("/a/change_room", {'direction':direction}, function change_room(response) { 240 | var others_player_index = rpg.other_players.length - 1; 241 | while(others_player_index >= 0) { 242 | if(rpg.other_players[0]) { 243 | rpg.other_players[0].remove(); 244 | }; 245 | rpg.other_players.remove(0); 246 | others_player_index = others_player_index - 1; 247 | }; 248 | rpg.other_players = []; 249 | json = $.evalJSON(response); 250 | var new_room = json["change_room"]; 251 | var map_content = new_room["content"]; 252 | if(map_content) 253 | map_content = $.evalJSON(map_content); 254 | rpg.grid.load_new_map(map_content); 255 | if(direction == "left") 256 | rpg.me.position[0] = (rpg.grid.width-1) * 16; 257 | if(direction == "right") 258 | rpg.me.position[0] = 0; 259 | if(direction == "top") 260 | rpg.me.position[1] = (rpg.grid.height-2) * 16; 261 | if(direction == "bottom") 262 | rpg.me.position[1] = 0; 263 | rpg.me.target_position = rpg.me.position; 264 | rpg.me.move(); 265 | for(var i=0; i \ 309 | '+this.pname+'\ 310 | \ 311 | '); 312 | this.cycle = 0; 313 | this.start_cycle = 0; 314 | rpg.map.append(this.element); 315 | this.message_element = this.element.find('.message') 316 | this.message_timeout = false; 317 | this.move(this.position); 318 | }; 319 | 320 | Player.prototype.say = function(message) { 321 | clearTimeout(this.message_timeout); 322 | var el = this.message_element; 323 | var chat_log_item = $('
  • '); 324 | chat_log_item.html('' + this.pname + ': ' + message); 325 | $('#chat-log').append(chat_log_item) 326 | $('#chat-log').scrollTop(1000) 327 | this.message_element.html(message); 328 | this.message_element.slideDown("slow"); 329 | var _hide_message = function(){el.slideUp("slow");} 330 | this.message_timeout = setTimeout(_hide_message, 12000); 331 | }; 332 | 333 | // make the walking animation works 334 | Player.prototype.anim = function() { 335 | if(!this.walking) { 336 | this.cycle = 1; 337 | }; 338 | var pos = this.start_cycle + 24 * this.cycle; 339 | this.element.css('background-position', -pos+'px'); 340 | if(!this.walking) { 341 | return; 342 | } 343 | this.cycle += 1; 344 | if(this.cycle > 2) 345 | this.cycle = 0; 346 | }; 347 | 348 | Player.prototype.move = function(pos) { 349 | if(!pos) 350 | pos = this.position; 351 | /*$('#indic')[0].style.left = (pos[0])+'px'; 352 | $('#indic')[0].style.top = (pos[1])+'px';*/ 353 | this.element[0].style.left = (pos[0] - 12)+'px'; 354 | this.element[0].style.top = (pos[1] - 32)+'px'; 355 | }; 356 | 357 | Player.prototype.init_position = function() { 358 | this.move(); 359 | }; 360 | 361 | Player.prototype.remove = function() { 362 | this.element.remove(); 363 | }; 364 | 365 | Player.prototype.update_target_position = function() { 366 | var vect = rpg.keyboard_vector(); 367 | if(vect) { 368 | var now = new Date().getTime(); 369 | if(this.last_time) { 370 | var time_elapsed = now - this.last_time; 371 | } else { 372 | var time_elapsed = 20.0; 373 | } 374 | this.last_time = now; 375 | var factor = (time_elapsed / 1000.0) * this.speed; 376 | 377 | var next_pos = [ 378 | this.target_position[0] + parseInt(vect[0]*factor), 379 | this.target_position[1] + parseInt(vect[1]*factor) 380 | ]; 381 | 382 | var bloc = rpg.grid.bloc_from_player_pos(next_pos); 383 | if(bloc && rpg.grid.is_bloc_walkable(bloc)) { 384 | this.target_position = next_pos; 385 | }; 386 | }; 387 | }; 388 | 389 | Player.prototype.set_start_cycle = function(vect) { 390 | // set the cycle animation according to the direction 391 | if(vect[1] > 0) { 392 | this.start_cycle = 24 * 9; 393 | } 394 | if(vect[1] < 0) { 395 | this.start_cycle = 24 * 3; 396 | } 397 | if(vect[0] > 0) { 398 | this.start_cycle = 24 * 6; 399 | }; 400 | if(vect[0] < 0) { 401 | this.start_cycle = 0; 402 | }; 403 | } 404 | 405 | Player.prototype.move_to_target = function() { 406 | var vect = [ 407 | this.target_position[0] - this.position[0], 408 | this.target_position[1] - this.position[1] 409 | ]; 410 | var norm = rpg.norm_vector(vect); 411 | if (norm > 0) { 412 | this.position[0] = this.target_position[0]; 413 | this.position[1] = this.target_position[1]; 414 | this.move(); 415 | this.walking = true; 416 | this.set_start_cycle(vect); 417 | } else { 418 | this.walking = false; 419 | this.last_time = false; 420 | }; 421 | /*} else { 422 | this.walking = true; 423 | var d = new Date().getTime(); 424 | if(this.last_time) { 425 | var time_elapsed = Math.min(60.0, Math.max(20.0, d - this.last_time)); 426 | } else { 427 | var time_elapsed = 20.0; 428 | } 429 | var factor = (time_elapsed / 1000.0) * this.speed; 430 | this.last_time = d; 431 | this.set_start_cycle(vect); 432 | vect[0] = vect[0] * factor; 433 | vect[1] = vect[1] * factor; 434 | console.log(factor) 435 | if(factor > 0) { 436 | this.position[0] += parseInt(vect[0]); 437 | this.position[1] += parseInt(vect[1]); 438 | this.move(); 439 | } 440 | return;*/ 441 | }; 442 | 443 | Player.prototype.send_position = function () { 444 | if(this.last_sent_position[0] != this.target_position[0] 445 | || this.last_sent_position[1] != this.target_position[1]) 446 | { 447 | var pos = $.toJSON(this.target_position) 448 | this.last_sent_position[0] = this.target_position[0]; 449 | this.last_sent_position[1] = this.target_position[1]; 450 | rpg.postJSON("/a/player/update_position", { 451 | 'body':pos 452 | }, 453 | function(response) {} 454 | ); 455 | }; 456 | }; 457 | 458 | rpg.Player = Player 459 | 460 | -------------------------------------------------------------------------------- /static/effects.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function Animation(key, x, y) { 4 | var id = 'player-effect-'+key; 5 | var canvas = document.getElementById(id); 6 | if(canvas==undefined) { 7 | canvas = document.createElement("canvas"); 8 | canvas.id = id; 9 | var map = document.getElementById('map'); 10 | map.appendChild(canvas); 11 | } 12 | 13 | canvas.style.left = (x-45) + 'px'; 14 | canvas.style.top = (y-120) + 'px'; 15 | this.ctx = document.getElementById(canvas.id).getContext('2d'); 16 | this.ctx.canvas.width = 100; 17 | this.ctx.canvas.height = 100; 18 | this.ctx.translate(50, 50); 19 | this.animation_step = 0; 20 | this.animation_timeout = false; 21 | }; 22 | 23 | Animation.prototype.anim = function () { 24 | if(this.animation_step > 0) 25 | return; 26 | var that = this; 27 | var a = function() { 28 | that._anim(); 29 | } 30 | clearTimeout(this.animation_timeout); 31 | this.animation_timeout = setInterval(a, 20); 32 | }; 33 | 34 | Animation.prototype._anim = function () { 35 | if(this.animation_step > 60) { 36 | clearTimeout(this.animation_timeout); 37 | this.animation_step = 0; 38 | this.ctx.clearRect(-60, -60, 100, 100); 39 | return; 40 | } 41 | var alpha = (60 - this.animation_step) / 60; 42 | this.ctx.clearRect(-60, -60, 100, 100); 43 | this.ctx.fillStyle = "rgba(200,0,0, "+alpha+")"; 44 | this.ctx.save(); 45 | this.ctx.translate(-20, 0); 46 | this.ctx.rotate(this.animation_step/5); 47 | this.ctx.fillRect(-10, -10, 20, 20); 48 | this.ctx.restore(); 49 | this.ctx.save(); 50 | this.ctx.rotate(Math.PI * 2/3); 51 | this.ctx.translate(-20, 0); 52 | this.ctx.rotate(this.animation_step/5); 53 | this.ctx.fillRect(-10, -10, 20, 20); 54 | this.ctx.restore(); 55 | this.ctx.save(); 56 | this.ctx.rotate(2 * Math.PI * 2/3); 57 | this.ctx.translate(-20, 0); 58 | this.ctx.rotate(this.animation_step/5); 59 | this.ctx.fillRect(-10, -10, 20, 20); 60 | this.ctx.restore(); 61 | 62 | this.ctx.rotate(0.1); 63 | this.animation_step++; 64 | }; 65 | -------------------------------------------------------------------------------- /static/face.html: -------------------------------------------------------------------------------- 1 |
    Your browser does not support the <CANVAS> element !
    2 |
    Author: Pierre Lindenbaum ( plindenbaum@yahoo.fr ) http://plindenbaum.blogspot.com
    3 | -------------------------------------------------------------------------------- /static/face.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 27 | 34 | 41 | 48 | 55 | 62 | 69 | 76 | 77 | 95 | 97 | 98 | 100 | image/svg+xml 101 | 103 | 104 | 105 | 106 | 107 | 112 | 122 | 132 | 142 | 152 | 162 | 167 | 172 | 177 | 182 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /static/game.css: -------------------------------------------------------------------------------- 1 | 2 | #main { 3 | width:770px; 4 | margin:0 auto; 5 | } 6 | 7 | canvas { 8 | position:absolute; 9 | } 10 | 11 | body { 12 | font-size:12px; 13 | font-family:verdana, arial, sans-serif; 14 | background:#333; 15 | } 16 | 17 | #map { 18 | position:relative; 19 | width:560px; 20 | height:480px; 21 | border:1px #eee solid; 22 | } 23 | 24 | #room_data { 25 | color:#fff; 26 | } 27 | 28 | #input { 29 | width:552px; 30 | padding:5px; 31 | background:#666; 32 | } 33 | 34 | #right-container { 35 | width:188px; 36 | float:right; 37 | color:#fff; 38 | } 39 | 40 | #chat-log { 41 | border:1px #444 solid; 42 | padding:10px; 43 | list-style:none; 44 | height:270px; 45 | overflow:auto; 46 | background:#222; 47 | } 48 | 49 | #chat-log li { 50 | padding:0; 51 | margin:0; 52 | color:#eee; 53 | } 54 | 55 | #chat-log li span{ 56 | color:#aaa; 57 | } 58 | 59 | #grid-serialized { 60 | width:600px; 61 | height:100px; 62 | } 63 | 64 | .bloc { 65 | background:url(tileset.png) top left no-repeat; 66 | position:absolute; 67 | background-position:-18px -18px; 68 | width:16px; 69 | height:16px; 70 | } 71 | 72 | #select { 73 | position:absolute; 74 | width:16px; 75 | height:16px; 76 | border:1px red solid; 77 | left:-100px; 78 | } 79 | 80 | .player { 81 | position:absolute; 82 | background:url(walk2.png) top left no-repeat; 83 | width:24px; 84 | height:32px; 85 | /*border:1px red solid;*/ 86 | } 87 | 88 | #indic { 89 | position:absolute; 90 | width:16px; 91 | height:16px; 92 | background:black; 93 | z-index:1000; 94 | } 95 | 96 | .player .text { 97 | color:#fff; 98 | background:#333; 99 | padding:2px 6px; 100 | margin-left:28px; 101 | margin-top:-20px; 102 | position:absolute; 103 | opacity:0.6; 104 | } 105 | 106 | .player .name { 107 | float:left; 108 | font-weight:bold; 109 | } 110 | 111 | .player .message { 112 | float:left; 113 | } 114 | -------------------------------------------------------------------------------- /static/game.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | var map = $('#map'); 4 | rpg.map = map; 5 | var tileset = $('#tileset'); 6 | var mouseDown = false; 7 | 8 | if(map_content) 9 | map_content = $.evalJSON(map_content); 10 | 11 | rpg.grid = new rpg.Grid( 12 | map, 35, 30, map_content 13 | ); 14 | 15 | tileset.click(function(e) { 16 | var tile_pos = tileset.position(); 17 | rpg.grid.choosen_bloc = [ 18 | Math.floor((e.clientX-tile_pos.left) / 17), 19 | Math.floor((e.clientY-tile_pos.top) / 17) 20 | ]; 21 | var tile_pos_css = (-rpg.grid.choosen_bloc[0]*17-1)+'px ' + (-rpg.grid.choosen_bloc[1]*17-1)+'px'; 22 | $('#select').css('left', rpg.grid.choosen_bloc[0]*17 + tile_pos.left+'px'); 23 | $('#select').css('top', rpg.grid.choosen_bloc[1]*17 + tile_pos.top+'px'); 24 | }); 25 | 26 | map.click(function(e) { 27 | rpg.grid.paint_bloc($(e.target)); 28 | }); 29 | 30 | map.mousedown(function(e) { 31 | mouseDown = true; 32 | }); 33 | 34 | map.mouseup(function(e) { 35 | mouseDown = false; 36 | //$('#grid-serialized').val($.toJSON(grid)); 37 | }); 38 | 39 | map.mousemove(function(e) { 40 | if(mouseDown) { 41 | rpg.grid.paint_bloc($(e.target)); 42 | return false; 43 | }; 44 | }); 45 | 46 | 47 | // Start of the mundane things 48 | 49 | $("#messageform").submit(function(e) { 50 | e.preventDefault(); 51 | var message = $('#message'); 52 | message.focus(); 53 | rpg.postJSON("/a/message/new", {'body':message.val()}, function(response) { 54 | rpg.me.say(message.val()); 55 | $('#message').val(''); 56 | }); 57 | return false; 58 | }); 59 | 60 | var me = false; 61 | rpg.other_players = []; 62 | 63 | function bootstrap() { 64 | 65 | rpg.me = new rpg.Player(window.player_position, window.private_key, window.player_name); 66 | rpg.me.init_position(); 67 | // start polling events 68 | rpg.updater.poll(); 69 | 70 | // animation 71 | 72 | var _players_move = function() { 73 | rpg.me.update_target_position(); 74 | rpg.me.move_to_target(); 75 | for(var i=0; i >> jQuery.quoteString("apple") 147 | "apple" 148 | 149 | >>> jQuery.quoteString('"Where are we going?", she asked.') 150 | "\"Where are we going?\", she asked." 151 | **/ 152 | $.quoteString = function(string) 153 | { 154 | if (string.match(_escapeable)) 155 | { 156 | return '"' + string.replace(_escapeable, function (a) 157 | { 158 | var c = _meta[a]; 159 | if (typeof c === 'string') return c; 160 | c = a.charCodeAt(); 161 | return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); 162 | }) + '"'; 163 | } 164 | return '"' + string + '"'; 165 | }; 166 | 167 | var _escapeable = /["\\\x00-\x1f\x7f-\x9f]/g; 168 | 169 | var _meta = { 170 | '\b': '\\b', 171 | '\t': '\\t', 172 | '\n': '\\n', 173 | '\f': '\\f', 174 | '\r': '\\r', 175 | '"' : '\\"', 176 | '\\': '\\\\' 177 | }; 178 | })(jQuery); 179 | -------------------------------------------------------------------------------- /static/jquery.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery JavaScript Library v1.3.2 3 | * http://jquery.com/ 4 | * 5 | * Copyright (c) 2009 John Resig 6 | * Dual licensed under the MIT and GPL licenses. 7 | * http://docs.jquery.com/License 8 | * 9 | * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) 10 | * Revision: 6246 11 | */ 12 | (function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
    ","
    "]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); 13 | /* 14 | * Sizzle CSS Selector Engine - v0.9.3 15 | * Copyright 2009, The Dojo Foundation 16 | * Released under the MIT, BSD, and GPL Licenses. 17 | * More information: http://sizzlejs.com/ 18 | */ 19 | (function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

    ";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
    ";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
    ").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
    ';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); -------------------------------------------------------------------------------- /static/jscolor/arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/jscolor/arrow.gif -------------------------------------------------------------------------------- /static/jscolor/cross.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/jscolor/cross.gif -------------------------------------------------------------------------------- /static/jscolor/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | jscolor demo 4 | 5 | 6 | 7 | 8 | 9 | Click here: 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /static/jscolor/hs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/jscolor/hs.png -------------------------------------------------------------------------------- /static/jscolor/hv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/jscolor/hv.png -------------------------------------------------------------------------------- /static/jscolor/jscolor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jscolor, JavaScript Color Picker 3 | * 4 | * @version 1.3.0 5 | * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html 6 | * @author Honza Odvarko http://odvarko.cz 7 | * @created 2008-06-15 8 | * @updated 2009-10-16 9 | * @link http://jscolor.com 10 | */ 11 | 12 | 13 | var jscolor = { 14 | 15 | 16 | dir : '', // location of jscolor directory (leave empty to autodetect) 17 | bindClass : 'color', // class name 18 | binding : true, // automatic binding via 19 | preloading : true, // use image preloading? 20 | 21 | 22 | install : function() { 23 | jscolor.addEvent(window, 'load', jscolor.init); 24 | }, 25 | 26 | 27 | init : function() { 28 | if(jscolor.binding) { 29 | jscolor.bind(); 30 | } 31 | if(jscolor.preloading) { 32 | jscolor.preload(); 33 | } 34 | }, 35 | 36 | 37 | getDir : function() { 38 | if(!jscolor.dir) { 39 | var detected = jscolor.detectDir(); 40 | jscolor.dir = detected!==false ? detected : 'jscolor/'; 41 | } 42 | return jscolor.dir; 43 | }, 44 | 45 | 46 | detectDir : function() { 47 | var base = location.href; 48 | 49 | var e = document.getElementsByTagName('base'); 50 | for(var i=0; i vs[a] ? 383 | (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) : 384 | tp[a], 385 | -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ? 386 | (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) : 387 | (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c) 388 | ]; 389 | drawPicker(pp[a], pp[b]); 390 | } 391 | }; 392 | 393 | 394 | this.importColor = function() { 395 | if(!valueElement) { 396 | this.exportColor(); 397 | } else { 398 | if(!this.adjust) { 399 | if(!this.fromString(valueElement.value, leaveValue)) { 400 | styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; 401 | styleElement.style.color = styleElement.jscStyle.color; 402 | this.exportColor(leaveValue | leaveStyle); 403 | } 404 | } else if(!this.required && /^\s*$/.test(valueElement.value)) { 405 | valueElement.value = ''; 406 | styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; 407 | styleElement.style.color = styleElement.jscStyle.color; 408 | this.exportColor(leaveValue | leaveStyle); 409 | 410 | } else if(this.fromString(valueElement.value)) { 411 | // OK 412 | } else { 413 | this.exportColor(); 414 | } 415 | } 416 | }; 417 | 418 | 419 | this.exportColor = function(flags) { 420 | if(!(flags & leaveValue) && valueElement) { 421 | var value = this.toString(); 422 | if(this.caps) { value = value.toUpperCase(); } 423 | if(this.hash) { value = '#'+value; } 424 | valueElement.value = value; 425 | } 426 | if(!(flags & leaveStyle) && styleElement) { 427 | styleElement.style.backgroundColor = 428 | '#'+this.toString(); 429 | styleElement.style.color = 430 | 0.213 * this.rgb[0] + 431 | 0.715 * this.rgb[1] + 432 | 0.072 * this.rgb[2] 433 | < 0.5 ? '#FFF' : '#000'; 434 | } 435 | if(!(flags & leavePad) && isPickerOwner()) { 436 | redrawPad(); 437 | } 438 | if(!(flags & leaveSld) && isPickerOwner()) { 439 | redrawSld(); 440 | } 441 | }; 442 | 443 | 444 | this.fromHSV = function(h, s, v, flags) { // null = don't change 445 | h<0 && (h=0) || h>6 && (h=6); 446 | s<0 && (s=0) || s>1 && (s=1); 447 | v<0 && (v=0) || v>1 && (v=1); 448 | this.rgb = HSV_RGB( 449 | h===null ? this.hsv[0] : (this.hsv[0]=h), 450 | s===null ? this.hsv[1] : (this.hsv[1]=s), 451 | v===null ? this.hsv[2] : (this.hsv[2]=v) 452 | ); 453 | this.exportColor(flags); 454 | }; 455 | 456 | 457 | this.fromRGB = function(r, g, b, flags) { // null = don't change 458 | r<0 && (r=0) || r>1 && (r=1); 459 | g<0 && (g=0) || g>1 && (g=1); 460 | b<0 && (b=0) || b>1 && (b=1); 461 | var hsv = RGB_HSV( 462 | r===null ? this.rgb[0] : (this.rgb[0]=r), 463 | g===null ? this.rgb[1] : (this.rgb[1]=g), 464 | b===null ? this.rgb[2] : (this.rgb[2]=b) 465 | ); 466 | if(hsv[0] !== null) { 467 | this.hsv[0] = hsv[0]; 468 | } 469 | if(hsv[2] !== 0) { 470 | this.hsv[1] = hsv[1]; 471 | } 472 | this.hsv[2] = hsv[2]; 473 | this.exportColor(flags); 474 | }; 475 | 476 | 477 | this.fromString = function(hex, flags) { 478 | var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i); 479 | if(!m) { 480 | return false; 481 | } else { 482 | if(m[1].length === 6) { // 6-char notation 483 | this.fromRGB( 484 | parseInt(m[1].substr(0,2),16) / 255, 485 | parseInt(m[1].substr(2,2),16) / 255, 486 | parseInt(m[1].substr(4,2),16) / 255, 487 | flags 488 | ); 489 | } else { // 3-char notation 490 | this.fromRGB( 491 | parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255, 492 | parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255, 493 | parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255, 494 | flags 495 | ); 496 | } 497 | return true; 498 | } 499 | }; 500 | 501 | 502 | this.toString = function() { 503 | return ( 504 | Math.round(255*this.rgb[0]) + ', ' + 505 | Math.round(255*this.rgb[1]) + ', ' + 506 | Math.round(255*this.rgb[2]) 507 | ); 508 | }; 509 | 510 | 511 | function RGB_HSV(r, g, b) { 512 | var n = Math.min(Math.min(r,g),b); 513 | var v = Math.max(Math.max(r,g),b); 514 | var m = v - n; 515 | if(m === 0) { return [ null, 0, v ]; } 516 | var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m); 517 | return [ h===6?0:h, m/v, v ]; 518 | } 519 | 520 | 521 | function HSV_RGB(h, s, v) { 522 | if(h === null) { return [ v, v, v ]; } 523 | var i = Math.floor(h); 524 | var f = i%2 ? h-i : 1-(h-i); 525 | var m = v * (1 - s); 526 | var n = v * (1 - s*f); 527 | switch(i) { 528 | case 6: 529 | case 0: return [v,n,m]; 530 | case 1: return [n,v,m]; 531 | case 2: return [m,v,n]; 532 | case 3: return [m,n,v]; 533 | case 4: return [n,m,v]; 534 | case 5: return [v,m,n]; 535 | } 536 | } 537 | 538 | 539 | function removePicker() { 540 | delete jscolor.picker.owner; 541 | document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB); 542 | } 543 | 544 | 545 | function drawPicker(x, y) { 546 | if(!jscolor.picker) { 547 | jscolor.picker = { 548 | box : document.createElement('div'), 549 | boxB : document.createElement('div'), 550 | pad : document.createElement('div'), 551 | padB : document.createElement('div'), 552 | padM : document.createElement('div'), 553 | sld : document.createElement('div'), 554 | sldB : document.createElement('div'), 555 | sldM : document.createElement('div') 556 | }; 557 | for(var i=0,segSize=4; i 8) { 156 | _s.defaultOptions = _s._mergeObjects(_s.defaultOptions, _s.flash9Options); 157 | _s.features.buffering = true; 158 | } 159 | if (_s.flashVersion > 8 && _s.useMovieStar) { 160 | // flash 9+ support for movieStar formats as well as MP3 161 | _s.defaultOptions = _s._mergeObjects(_s.defaultOptions, _s.movieStarOptions); 162 | _s.filePatterns.flash9 = new RegExp('\\.(mp3|'+_s.netStreamTypes.join('|')+')(\\?.*)?$', 'i'); 163 | _s.features.movieStar = true; 164 | } else { 165 | _s.useMovieStar = false; 166 | _s.features.movieStar = false; 167 | } 168 | _s.filePattern = _s.filePatterns[(_s.flashVersion != 8?'flash9':'flash8')]; 169 | _s.movieURL = (_s.flashVersion == 8?'soundmanager2.swf':'soundmanager2_flash9.swf'); 170 | _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_s.flashVersion > 8); 171 | }; 172 | 173 | this._overHTTP = (document.location?document.location.protocol.match(/http/i):null); 174 | this._waitingforEI = false; 175 | this._initPending = false; 176 | this._tryInitOnFocus = (this.isSafari && typeof document.hasFocus == 'undefined'); 177 | this._isFocused = (typeof document.hasFocus != 'undefined'?document.hasFocus():null); 178 | this._okToDisable = !this._tryInitOnFocus; 179 | 180 | this.useAltURL = !this._overHTTP; // use altURL if not "online" 181 | var flashCPLink = 'http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html'; 182 | 183 | this.strings = { 184 | notReady: 'Not loaded yet - wait for soundManager.onload() before calling sound-related methods', 185 | appXHTML: _sm+'_createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.', 186 | swf404: _sm+': Verify that %s is a valid path.', 187 | tryDebug: 'Try '+_sm+'.debugFlash = true for more security details (output goes to SWF.)', 188 | checkSWF: 'See SWF output for more debug info.', 189 | localFail: _sm+': Non-HTTP page ('+document.location.protocol+' URL?) Review Flash player security settings for this special case:\n'+flashCPLink+'\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/', 190 | waitFocus: _sm+': Special case: Waiting for focus-related event..', 191 | waitImpatient: _sm+': Getting impatient, still waiting for Flash%s...', 192 | waitForever: _sm+': Waiting indefinitely for Flash...', 193 | needFunction: _sm+'.onready(): Function object expected', 194 | badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', 195 | fl9Vid: 'flash 9 required for video. Exiting.', 196 | noMS: 'MovieStar mode not enabled. Exiting.', 197 | spcWmode: _sm+'._createMovie(): Removing wmode, preventing win32 below-the-fold SWF loading issue', 198 | currentObj: '--- '+_sm+'._debug(): Current sound objects ---', 199 | waitEI: _sm+'._initMovie(): Waiting for ExternalInterface call from Flash..', 200 | waitOnload: _sm+': Waiting for window.onload()', 201 | docLoaded: _sm+': Document already loaded', 202 | onload: _sm+'.initComplete(): calling soundManager.onload()', 203 | onloadOK: _sm+'.onload() complete', 204 | init: '-- '+_sm+'.init() --', 205 | didInit: _sm+'.init(): Already called?', 206 | flashJS: _sm+': Attempting to call Flash from JS..', 207 | noPolling: _sm+': Polling (whileloading()/whileplaying() support) is disabled.', 208 | secNote: 'Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html', 209 | badRemove: 'Warning: Failed to remove flash movie.', 210 | peakWave: 'Warning: peak/waveform/eqData features unsupported for non-MP3 formats', 211 | shutdown: _sm+'.disable(): Shutting down', 212 | queue: _sm+'.onready(): Queueing handler', 213 | smFail: _sm+': Failed to initialise.', 214 | smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', 215 | manURL: 'SMSound.load(): Using manually-assigned URL', 216 | onURL: _sm+'.load(): current URL already assigned.', 217 | badFV: 'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.' 218 | }; 219 | 220 | this._str = function() { // o [,items to replace] 221 | var params = Array.prototype.slice.call(arguments); // real array, please 222 | var o = params.shift(); // first arg 223 | var str = _s.strings && _s.strings[o]?_s.strings[o]:''; 224 | if (str && params && params.length) { 225 | for (var i=0, j=params.length; i 8 && _s.useMovieStar) { 273 | if (_tO.isMovieStar === null) { 274 | _tO.isMovieStar = (_tO.url.match(_s.netStreamPattern)?true:false); 275 | } 276 | if (_tO.isMovieStar) { 277 | _s._wD(_cs+'using MovieStar handling'); 278 | } 279 | if (_tO.isMovieStar && (_tO.usePeakData || _tO.useWaveformData || _tO.useEQData)) { 280 | _s._wDS('peakWave'); 281 | _tO.usePeakData = false; 282 | _tO.useWaveformData = false; 283 | _tO.useEQData = false; 284 | } 285 | } 286 | _s.sounds[_tO.id] = new SMSound(_tO); 287 | _s.soundIDs[_s.soundIDs.length] = _tO.id; 288 | // AS2: 289 | if (_s.flashVersion == 8) { 290 | _s.o._createSound(_tO.id, _tO.onjustbeforefinishtime); 291 | } else { 292 | _s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.useVideo:false), (_tO.isMovieStar?_tO.bufferTime:false)); 293 | } 294 | if (_tO.autoLoad || _tO.autoPlay) { 295 | // TODO: does removing timeout here cause problems? 296 | if (_s.sounds[_tO.id]) { 297 | _s.sounds[_tO.id].load(_tO); 298 | } 299 | } 300 | if (_tO.autoPlay) { 301 | _s.sounds[_tO.id].play(); 302 | } 303 | return _s.sounds[_tO.id]; 304 | }; 305 | 306 | this.createVideo = function(oOptions) { 307 | var fN = 'soundManager.createVideo(): '; 308 | if (arguments.length == 2) { 309 | oOptions = { 310 | 'id': arguments[0], 311 | 'url': arguments[1] 312 | }; 313 | } 314 | if (_s.flashVersion >= 9) { 315 | oOptions.isMovieStar = true; 316 | oOptions.useVideo = true; 317 | } else { 318 | _s._wD(fN+_s._str('f9Vid'), 2); 319 | return false; 320 | } 321 | if (!_s.useMovieStar) { 322 | _s._wD(fN+_s._str('noMS'), 2); 323 | } 324 | return _s.createSound(oOptions); 325 | }; 326 | 327 | this.destroySound = function(sID, bFromSound) { 328 | // explicitly destroy a sound before normal page unload, etc. 329 | if (!_s._idCheck(sID)) { 330 | return false; 331 | } 332 | for (var i=0; i<_s.soundIDs.length; i++) { 333 | if (_s.soundIDs[i] == sID) { 334 | _s.soundIDs.splice(i, 1); 335 | continue; 336 | } 337 | } 338 | // conservative option: avoid crash with flash 8 339 | // calling destroySound() within a sound onload() might crash firefox, certain flavours of winXP+flash 8?? 340 | // if (_s.flashVersion != 8) { 341 | _s.sounds[sID].unload(); 342 | // } 343 | if (!bFromSound) { 344 | // ignore if being called from SMSound instance 345 | _s.sounds[sID].destruct(); 346 | } 347 | delete _s.sounds[sID]; 348 | }; 349 | 350 | this.destroyVideo = this.destroySound; 351 | 352 | this.load = function(sID, oOptions) { 353 | if (!_s._idCheck(sID)) { 354 | return false; 355 | } 356 | _s.sounds[sID].load(oOptions); 357 | }; 358 | 359 | this.unload = function(sID) { 360 | if (!_s._idCheck(sID)) { 361 | return false; 362 | } 363 | _s.sounds[sID].unload(); 364 | }; 365 | 366 | this.play = function(sID, oOptions) { 367 | var fN = 'soundManager.play(): '; 368 | if (!_s._didInit) { 369 | throw _s._complain(fN+_s._str('notReady'), arguments.callee.caller); 370 | } 371 | if (!_s._idCheck(sID)) { 372 | if (typeof oOptions != 'Object') { 373 | oOptions = { 374 | url: oOptions 375 | }; // overloading use case: play('mySound','/path/to/some.mp3'); 376 | } 377 | if (oOptions && oOptions.url) { 378 | // overloading use case, creation+playing of sound: .play('someID',{url:'/path/to.mp3'}); 379 | _s._wD(fN+'attempting to create "'+sID+'"', 1); 380 | oOptions.id = sID; 381 | _s.createSound(oOptions); 382 | } else { 383 | return false; 384 | } 385 | } 386 | _s.sounds[sID].play(oOptions); 387 | }; 388 | 389 | this.start = this.play; // just for convenience 390 | 391 | this.setPosition = function(sID, nMsecOffset) { 392 | if (!_s._idCheck(sID)) { 393 | return false; 394 | } 395 | _s.sounds[sID].setPosition(nMsecOffset); 396 | }; 397 | 398 | this.stop = function(sID) { 399 | if (!_s._idCheck(sID)) { 400 | return false; 401 | } 402 | _s._wD('soundManager.stop('+sID+')', 1); 403 | _s.sounds[sID].stop(); 404 | }; 405 | 406 | this.stopAll = function() { 407 | _s._wD('soundManager.stopAll()', 1); 408 | for (var oSound in _s.sounds) { 409 | if (_s.sounds[oSound] instanceof SMSound) { 410 | _s.sounds[oSound].stop(); // apply only to sound objects 411 | } 412 | } 413 | }; 414 | 415 | this.pause = function(sID) { 416 | if (!_s._idCheck(sID)) { 417 | return false; 418 | } 419 | _s.sounds[sID].pause(); 420 | }; 421 | 422 | this.pauseAll = function() { 423 | for (var i=_s.soundIDs.length; i--;) { 424 | _s.sounds[_s.soundIDs[i]].pause(); 425 | } 426 | }; 427 | 428 | this.resume = function(sID) { 429 | if (!_s._idCheck(sID)) { 430 | return false; 431 | } 432 | _s.sounds[sID].resume(); 433 | }; 434 | 435 | this.resumeAll = function() { 436 | for (var i=_s.soundIDs.length; i--;) { 437 | _s.sounds[_s.soundIDs[i]].resume(); 438 | } 439 | }; 440 | 441 | this.togglePause = function(sID) { 442 | if (!_s._idCheck(sID)) { 443 | return false; 444 | } 445 | _s.sounds[sID].togglePause(); 446 | }; 447 | 448 | this.setPan = function(sID, nPan) { 449 | if (!_s._idCheck(sID)) { 450 | return false; 451 | } 452 | _s.sounds[sID].setPan(nPan); 453 | }; 454 | 455 | this.setVolume = function(sID, nVol) { 456 | if (!_s._idCheck(sID)) { 457 | return false; 458 | } 459 | _s.sounds[sID].setVolume(nVol); 460 | }; 461 | 462 | this.mute = function(sID) { 463 | var fN = 'soundManager.mute(): '; 464 | if (typeof sID != 'string') { 465 | sID = null; 466 | } 467 | if (!sID) { 468 | _s._wD(fN+'Muting all sounds'); 469 | for (var i=_s.soundIDs.length; i--;) { 470 | _s.sounds[_s.soundIDs[i]].mute(); 471 | } 472 | _s.muted = true; 473 | } else { 474 | if (!_s._idCheck(sID)) { 475 | return false; 476 | } 477 | _s._wD(fN+'Muting "'+sID+'"'); 478 | _s.sounds[sID].mute(); 479 | } 480 | }; 481 | 482 | this.muteAll = function() { 483 | _s.mute(); 484 | }; 485 | 486 | this.unmute = function(sID) { 487 | var fN = 'soundManager.unmute(): '; 488 | if (typeof sID != 'string') { 489 | sID = null; 490 | } 491 | if (!sID) { 492 | _s._wD(fN+'Unmuting all sounds'); 493 | for (var i=_s.soundIDs.length; i--;) { 494 | _s.sounds[_s.soundIDs[i]].unmute(); 495 | } 496 | _s.muted = false; 497 | } else { 498 | if (!_s._idCheck(sID)) { 499 | return false; 500 | } 501 | _s._wD(fN+'Unmuting "'+sID+'"'); 502 | _s.sounds[sID].unmute(); 503 | } 504 | }; 505 | 506 | this.unmuteAll = function() { 507 | _s.unmute(); 508 | }; 509 | 510 | this.toggleMute = function(sID) { 511 | if (!_s._idCheck(sID)) { 512 | return false; 513 | } 514 | _s.sounds[sID].toggleMute(); 515 | }; 516 | 517 | this.getMemoryUse = function() { 518 | if (_s.flashVersion == 8) { 519 | // not supported in Flash 8 520 | return 0; 521 | } 522 | if (_s.o) { 523 | return parseInt(_s.o._getMemoryUse(), 10); 524 | } 525 | }; 526 | 527 | this.disable = function(bNoDisable) { 528 | // destroy all functions 529 | if (typeof bNoDisable == 'undefined') { 530 | bNoDisable = false; 531 | } 532 | if (_s._disabled) { 533 | return false; 534 | } 535 | _s._disabled = true; 536 | _s._wDS('shutdown', 1); 537 | for (var i=_s.soundIDs.length; i--;) { 538 | _s._disableObject(_s.sounds[_s.soundIDs[i]]); 539 | } 540 | _s.initComplete(bNoDisable); // fire "complete", despite fail 541 | // _s._disableObject(_s); // taken out to allow reboot() 542 | }; 543 | 544 | this.canPlayURL = function(sURL) { 545 | return (sURL?(sURL.match(_s.filePattern)?true:false):null); 546 | }; 547 | 548 | this.getSoundById = function(sID, suppressDebug) { 549 | if (!sID) { 550 | throw new Error('SoundManager.getSoundById(): sID is null/undefined'); 551 | } 552 | var result = _s.sounds[sID]; 553 | if (!result && !suppressDebug) { 554 | _s._wD('"'+sID+'" is an invalid sound ID.', 2); 555 | // soundManager._wD('trace: '+arguments.callee.caller); 556 | } 557 | return result; 558 | }; 559 | 560 | this.onready = function(oMethod, oScope) { 561 | // queue a callback, with optional scope 562 | // a status object will be passed to your handler 563 | /* 564 | soundManager.onready(function(oStatus) { 565 | alert('SM2 init success: '+oStatus.success); 566 | }); 567 | */ 568 | if (oMethod && oMethod instanceof Function) { 569 | if (_s._didInit) { 570 | _s._wDS('queue'); 571 | } 572 | if (!oScope) { 573 | oScope = window; 574 | } 575 | _s._addOnReady(oMethod, oScope); 576 | _s._processOnReady(); 577 | return true; 578 | } else { 579 | throw _s._str('needFunction'); 580 | } 581 | }; 582 | 583 | this.oninitmovie = function() { 584 | // called after SWF has been appended to the DOM via JS (or retrieved from HTML) 585 | // this is a stub for your own scripts. 586 | }; 587 | 588 | this.onload = function() { 589 | // window.onload() equivalent for SM2, ready to create sounds etc. 590 | // this is a stub for your own scripts. 591 | soundManager._wD('soundManager.onload()', 1); 592 | }; 593 | 594 | this.onerror = function() { 595 | // stub for user handler, called when SM2 fails to load/init 596 | }; 597 | 598 | // --- "private" methods --- 599 | this._idCheck = this.getSoundById; 600 | 601 | this._complain = function(sMsg, oCaller) { 602 | // Try to create meaningful custom errors, w/stack trace to the "offending" line 603 | var sPre = 'Error: '; 604 | if (!oCaller) { 605 | return new Error(sPre+sMsg); 606 | } 607 | var e = new Error(''); // make a mistake. 608 | var stackMsg = null; 609 | if (e.stack) { 610 | // potentially dangerous: Try to return a meaningful stacktrace where provided (Mozilla) 611 | try { 612 | var splitChar = '@'; 613 | var stackTmp = e.stack.split(splitChar); 614 | stackMsg = stackTmp[4]; // try to return only the relevant bit, skipping internal SM2 shiz 615 | } catch(ee) { 616 | // oops. 617 | stackMsg = e.stack; 618 | } 619 | } 620 | if (typeof console != 'undefined' && typeof console.trace != 'undefined') { 621 | console.trace(); 622 | } 623 | var errorDesc = sPre+sMsg+'. \nCaller: '+oCaller.toString()+(e.stack?' \nTop of stacktrace: '+stackMsg:(e.message?' \nMessage: '+e.message:'')); 624 | // See JS error/debug/console output for real error source, stack trace / message detail where possible. 625 | return new Error(errorDesc); 626 | }; 627 | 628 | var _doNothing = function() { 629 | return false; 630 | }; 631 | 632 | _doNothing._protected = true; 633 | 634 | this._disableObject = function(o) { 635 | for (var oProp in o) { 636 | if (typeof o[oProp] == 'function' && typeof o[oProp]._protected == 'undefined') { 637 | o[oProp] = _doNothing; 638 | } 639 | } 640 | oProp = null; 641 | }; 642 | 643 | this._failSafely = function(bNoDisable) { 644 | // general failure exception handler 645 | if (typeof bNoDisable == 'undefined') { 646 | bNoDisable = false; 647 | } 648 | if (!_s._disabled || bNoDisable) { 649 | _s._wDS('smFail', 2); 650 | _s.disable(bNoDisable); 651 | } 652 | }; 653 | 654 | this._normalizeMovieURL = function(smURL) { 655 | var urlParams = null; 656 | if (smURL) { 657 | if (smURL.match(/\.swf(\?.*)?$/i)) { 658 | urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?')+4); 659 | if (urlParams) { 660 | return smURL; // assume user knows what they're doing 661 | } 662 | } else if (smURL.lastIndexOf('/') != smURL.length - 1) { 663 | smURL = smURL+'/'; 664 | } 665 | } 666 | return (smURL && smURL.lastIndexOf('/') != -1?smURL.substr(0, smURL.lastIndexOf('/')+1):'./')+_s.movieURL; 667 | }; 668 | 669 | this._getDocument = function() { 670 | return (document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName('div')[0])); 671 | }; 672 | 673 | this._getDocument._protected = true; 674 | 675 | this._setPolling = function(bPolling, bHighPerformance) { 676 | if (!_s.o || !_s.allowPolling) { 677 | return false; 678 | } 679 | _s.o._setPolling(bPolling, bHighPerformance); 680 | }; 681 | 682 | this._createMovie = function(smID, smURL) { 683 | var specialCase = null; 684 | var remoteURL = (smURL?smURL:_s.url); 685 | var localURL = (_s.altURL?_s.altURL:remoteURL); 686 | if (_s.debugURLParam.test(window.location.href.toString())) { 687 | _s.debugMode = true; // allow force of debug mode via URL 688 | } 689 | if (_s._didAppend && _s._appendSuccess) { 690 | return false; // ignore if already succeeded 691 | } 692 | _s._didAppend = true; 693 | 694 | // safety check for legacy (change to Flash 9 URL) 695 | _s._setVersionInfo(); 696 | _s.url = _s._normalizeMovieURL(_s._overHTTP?remoteURL:localURL); 697 | smURL = _s.url; 698 | 699 | if (_s.useHighPerformance && _s.useMovieStar && _s.defaultOptions.useVideo === true) { 700 | specialCase = 'soundManager note: disabling highPerformance, not applicable with movieStar mode+useVideo'; 701 | _s.useHighPerformance = false; 702 | } 703 | 704 | _s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode); 705 | 706 | 707 | if (_s.wmode !== null && _s.flashLoadTimeout !== 0 && (!_s.useHighPerformance || _s.debugFlash) && !_s.isIE && navigator.platform.match(/win32/i)) { 708 | _s.specialWmodeCase = true; 709 | // extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here 710 | // does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout 711 | _s._wDS('spcWmode'); 712 | _s.wmode = null; 713 | } 714 | 715 | if (_s.flashVersion == 8) { 716 | _s.allowFullScreen = false; 717 | } 718 | 719 | var oEmbed = { 720 | name: smID, 721 | id: smID, 722 | src: smURL, 723 | width: '100%', 724 | height: '100%', 725 | quality: 'high', 726 | allowScriptAccess: _s.allowScriptAccess, 727 | bgcolor: _s.bgColor, 728 | pluginspage: 'http://www.macromedia.com/go/getflashplayer', 729 | type: 'application/x-shockwave-flash', 730 | wmode: _s.wmode, 731 | allowfullscreen: (_s.allowFullScreen?'true':'false') 732 | }; 733 | 734 | if (_s.debugFlash) { 735 | oEmbed.FlashVars = 'debug=1'; 736 | } 737 | 738 | if (!_s.wmode) { 739 | delete oEmbed.wmode; // don't write empty attribute 740 | } 741 | 742 | var oMovie = null; 743 | var tmp = null; 744 | var movieHTML = null; 745 | var oEl = null; 746 | 747 | if (_s.isIE) { 748 | // IE is "special". 749 | oMovie = document.createElement('div'); 750 | movieHTML = ''+(_s.wmode?' ':'')+''+(_s.debugFlash?'':'')+''; 751 | } else { 752 | oMovie = document.createElement('embed'); 753 | for (tmp in oEmbed) { 754 | if (oEmbed.hasOwnProperty(tmp)) { 755 | oMovie.setAttribute(tmp, oEmbed[tmp]); 756 | } 757 | } 758 | } 759 | 760 | var oD = null; 761 | var oToggle = null; 762 | 763 | if (_s.debugMode) { 764 | 765 | oD = document.createElement('div'); 766 | oD.id = _s.debugID+'-toggle'; 767 | oToggle = { 768 | position: 'fixed', 769 | bottom: '0px', 770 | right: '0px', 771 | width: '1.2em', 772 | height: '1.2em', 773 | lineHeight: '1.2em', 774 | margin: '2px', 775 | textAlign: 'center', 776 | border: '1px solid #999', 777 | cursor: 'pointer', 778 | background: '#fff', 779 | color: '#333', 780 | zIndex: 10001 781 | }; 782 | 783 | oD.appendChild(document.createTextNode('-')); 784 | oD.onclick = _s._toggleDebug; 785 | oD.title = 'Toggle SM2 debug console'; 786 | 787 | if (navigator.userAgent.match(/msie 6/i)) { 788 | oD.style.position = 'absolute'; 789 | oD.style.cursor = 'hand'; 790 | } 791 | 792 | for (tmp in oToggle) { 793 | if (oToggle.hasOwnProperty(tmp)) { 794 | oD.style[tmp] = oToggle[tmp]; 795 | } 796 | } 797 | 798 | } 799 | 800 | var oTarget = _s._getDocument(); 801 | 802 | if (oTarget) { 803 | 804 | _s.oMC = _$('sm2-container')?_$('sm2-container'):document.createElement('div'); 805 | 806 | var extraClass = (_s.debugMode?' sm2-debug':'')+(_s.debugFlash?' flash-debug':''); 807 | 808 | if (!_s.oMC.id) { 809 | _s.oMC.id = 'sm2-container'; 810 | _s.oMC.className = 'movieContainer'+extraClass; 811 | // "hide" flash movie 812 | var s = null; 813 | oEl = null; 814 | if (_s.useHighPerformance) { 815 | s = { 816 | position: 'fixed', 817 | width: '8px', 818 | height: '8px', 819 | // must be at least 6px for flash to run fast. odd? yes. 820 | bottom: '0px', 821 | left: '0px', 822 | overflow: 'hidden' 823 | // zIndex:-1 // sit behind everything else - potentially dangerous/buggy? 824 | }; 825 | } else { 826 | s = { 827 | position: 'absolute', 828 | width: '8px', 829 | height: '8px', 830 | top: '-9999px', 831 | left: '-9999px' 832 | }; 833 | } 834 | var x = null; 835 | if (!_s.debugFlash) { 836 | for (x in s) { 837 | if (s.hasOwnProperty(x)) { 838 | _s.oMC.style[x] = s[x]; 839 | } 840 | } 841 | } 842 | try { 843 | if (!_s.isIE) { 844 | _s.oMC.appendChild(oMovie); 845 | } 846 | oTarget.appendChild(_s.oMC); 847 | if (_s.isIE) { 848 | oEl = _s.oMC.appendChild(document.createElement('div')); 849 | oEl.className = 'sm2-object-box'; 850 | oEl.innerHTML = movieHTML; 851 | } 852 | _s._appendSuccess = true; 853 | } catch(e) { 854 | throw new Error(_s._str('appXHTML')); 855 | } 856 | } else { 857 | // it's already in the document. 858 | if (_s.debugMode || _s.debugFlash) { 859 | _s.oMC.className += extraClass; 860 | } 861 | _s.oMC.appendChild(oMovie); 862 | if (_s.isIE) { 863 | oEl = _s.oMC.appendChild(document.createElement('div')); 864 | oEl.className = 'sm2-object-box'; 865 | oEl.innerHTML = movieHTML; 866 | } 867 | _s._appendSuccess = true; 868 | } 869 | 870 | if (_s.debugMode && !_$(_s.debugID) && ((!_s._hasConsole || !_s.useConsole) || (_s.useConsole && _s._hasConsole && !_s.consoleOnly))) { 871 | var oDebug = document.createElement('div'); 872 | oDebug.id = _s.debugID; 873 | oDebug.style.display = (_s.debugMode?'block':'none'); 874 | if (_s.debugMode && !_$(oD.id)) { 875 | try { 876 | oTarget.appendChild(oD); 877 | } catch(e2) { 878 | throw new Error(_s._str('appXHTML')); 879 | } 880 | oTarget.appendChild(oDebug); 881 | } 882 | } 883 | oTarget = null; 884 | } 885 | 886 | if (specialCase) { 887 | _s._wD(specialCase); 888 | } 889 | 890 | _s._wD('-- SoundManager 2 '+_s.version+(_s.useMovieStar?', MovieStar mode':'')+(_s.useHighPerformance?', high performance mode, ':', ')+((_s.useFastPolling?'fast':'normal')+' polling')+(_s.wmode?', wmode: '+_s.wmode:'')+(_s.debugFlash?', flash debug mode':'')+' --', 1); 891 | _s._wD('soundManager._createMovie(): Trying to load '+smURL+(!_s._overHTTP && _s.altURL?' (alternate URL)':''), 1); 892 | }; 893 | 894 | this._writeDebug = function(sText, sType, bTimestamp) { // aliased to this._wD() 895 | if (!_s.debugMode) { 896 | return false; 897 | } 898 | if (typeof bTimestamp != 'undefined' && bTimestamp) { 899 | sText = sText+' | '+new Date().getTime(); 900 | } 901 | if (_s._hasConsole && _s.useConsole) { 902 | var sMethod = _s._debugLevels[sType]; 903 | if (typeof console[sMethod] != 'undefined') { 904 | console[sMethod](sText); 905 | } else { 906 | console.log(sText); 907 | } 908 | if (_s.useConsoleOnly) { 909 | return true; 910 | } 911 | } 912 | var sDID = 'soundmanager-debug'; 913 | var o = null; 914 | try { 915 | o = _$(sDID); 916 | if (!o) { 917 | return false; 918 | } 919 | var oItem = document.createElement('div'); 920 | if (++_s._wdCount % 2 === 0) { 921 | oItem.className = 'sm2-alt'; 922 | } 923 | // sText = sText.replace(/\n/g,'
    '); 924 | if (typeof sType == 'undefined') { 925 | sType = 0; 926 | } else { 927 | sType = parseInt(sType, 10); 928 | } 929 | oItem.appendChild(document.createTextNode(sText)); 930 | if (sType) { 931 | if (sType >= 2) { 932 | oItem.style.fontWeight = 'bold'; 933 | } 934 | if (sType == 3) { 935 | oItem.style.color = '#ff3333'; 936 | } 937 | } 938 | // o.appendChild(oItem); // top-to-bottom 939 | o.insertBefore(oItem, o.firstChild); // bottom-to-top 940 | } catch(e) { 941 | // oh well 942 | } 943 | o = null; 944 | }; 945 | this._writeDebug._protected = true; 946 | this._wdCount = 0; 947 | this._wdCount._protected = true; 948 | this._wD = this._writeDebug; 949 | 950 | this._wDS = function(o,errorLevel) { 951 | if (!o) { 952 | return ''; 953 | } else { 954 | return _s._wD(_s._str(o),errorLevel); 955 | } 956 | }; 957 | this._wDS._protected = true; 958 | 959 | this._wDAlert = function(sText) { 960 | alert(sText); 961 | }; 962 | 963 | if (window.location.href.indexOf('debug=alert')+1 && _s.debugMode) { 964 | _s._wD = _s._wDAlert; 965 | } 966 | 967 | this._toggleDebug = function() { 968 | var o = _$(_s.debugID); 969 | var oT = _$(_s.debugID+'-toggle'); 970 | if (!o) { 971 | return false; 972 | } 973 | if (_s._debugOpen) { 974 | // minimize 975 | oT.innerHTML = '+'; 976 | o.style.display = 'none'; 977 | } else { 978 | oT.innerHTML = '-'; 979 | o.style.display = 'block'; 980 | } 981 | _s._debugOpen = !_s._debugOpen; 982 | }; 983 | 984 | this._toggleDebug._protected = true; 985 | 986 | this._debug = function() { 987 | _s._wDS('currentObj', 1); 988 | for (var i=0, j = _s.soundIDs.length; i 0) { 1057 | _s._wDS('waitEI'); 1058 | } 1059 | } 1060 | if (typeof _s.oninitmovie == 'function') { 1061 | setTimeout(_s.oninitmovie, 1); 1062 | } 1063 | }; 1064 | 1065 | this.waitForExternalInterface = function() { 1066 | if (_s._waitingForEI) { 1067 | return false; 1068 | } 1069 | _s._waitingForEI = true; 1070 | if (_s._tryInitOnFocus && !_s._isFocused) { 1071 | _s._wDS('waitFocus'); 1072 | return false; 1073 | } 1074 | if (_s.flashLoadTimeout > 0) { 1075 | if (!_s._didInit) { 1076 | var p = _s.getMoviePercent(); 1077 | _s._wD(_s._str('waitImpatient',(p == 100?' (SWF loaded)':(p > 0?' (SWF '+p+'% loaded)':'')))); 1078 | } 1079 | setTimeout(function() { 1080 | var p = _s.getMoviePercent(); 1081 | if (!_s._didInit) { 1082 | _s._wD(_sm+': No Flash response within reasonable time after document load.\nLikely causes: '+(p === null || p === 0?'Loading '+_s.movieURL+' may have failed (and/or Flash '+_s.flashVersion+'+ not present?), ':'')+'Flash blocked or JS-Flash security error.'+(_s.debugFlash?' '+_s._str('checkSWF'): ''), 2); 1083 | if (!_s._overHTTP) { 1084 | _s._wDS('localFail', 2); 1085 | if (!_s.debugFlash) { 1086 | _s._wDS('tryDebug', 2); 1087 | } 1088 | } 1089 | if (p === 0) { 1090 | // 404, or blocked from loading? 1091 | _s._wD(_s._str('swf404',_s.url)); 1092 | } 1093 | _s._debugTS('flashtojs', false, ': Timed out'+(_s._overHTTP)?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); 1094 | } 1095 | // if still not initialized and no other options, give up 1096 | if (!_s._didInit && _s._okToDisable) { 1097 | _s._failSafely(true); // don't disable, for reboot() 1098 | } 1099 | }, 1100 | _s.flashLoadTimeout); 1101 | } else if (!_s._didInit) { 1102 | _s._wDS('waitForever'); 1103 | } 1104 | }; 1105 | 1106 | this.getMoviePercent = function() { 1107 | return (_s.o && typeof _s.o.PercentLoaded != 'undefined'?_s.o.PercentLoaded():null); 1108 | }; 1109 | 1110 | this.handleFocus = function() { 1111 | if (_s._isFocused || !_s._tryInitOnFocus) { 1112 | return true; 1113 | } 1114 | _s._okToDisable = true; 1115 | _s._isFocused = true; 1116 | _s._wD('soundManager.handleFocus()'); 1117 | if (_s._tryInitOnFocus) { 1118 | // giant Safari 3.1 hack - assume window in focus if mouse is moving, since document.hasFocus() not currently implemented. 1119 | window.removeEventListener('mousemove', _s.handleFocus, false); 1120 | } 1121 | // allow init to restart 1122 | _s._waitingForEI = false; 1123 | setTimeout(_s.waitForExternalInterface, 500); 1124 | // detach event 1125 | if (window.removeEventListener) { 1126 | window.removeEventListener('focus', _s.handleFocus, false); 1127 | } else if (window.detachEvent) { 1128 | window.detachEvent('onfocus', _s.handleFocus); 1129 | } 1130 | }; 1131 | 1132 | this.initComplete = function(bNoDisable) { 1133 | if (_s._didInit) { 1134 | return false; 1135 | } 1136 | _s._didInit = true; 1137 | _s._wD('-- SoundManager 2 '+(_s._disabled?'failed to load':'loaded')+' ('+(_s._disabled?'security/load error':'OK')+') --', 1); 1138 | if (_s._disabled || bNoDisable) { 1139 | // _s._wD('soundManager.initComplete(): calling soundManager.onerror()',1); 1140 | _s._processOnReady(); 1141 | _s._debugTS('onload', false); 1142 | _s.onerror.apply(window); 1143 | return false; 1144 | } else { 1145 | _s._debugTS('onload', true); 1146 | } 1147 | if (_s.waitForWindowLoad && !_s._windowLoaded) { 1148 | _s._wDS('waitOnload'); 1149 | if (window.addEventListener) { 1150 | window.addEventListener('load', _s._initUserOnload, false); 1151 | } else if (window.attachEvent) { 1152 | window.attachEvent('onload', _s._initUserOnload); 1153 | } 1154 | return false; 1155 | } else { 1156 | if (_s.waitForWindowLoad && _s._windowLoaded) { 1157 | _s._wDS('docLoaded'); 1158 | } 1159 | _s._initUserOnload(); 1160 | } 1161 | }; 1162 | 1163 | this._addOnReady = function(oMethod, oScope) { 1164 | _s._onready.push({ 1165 | 'method': oMethod, 1166 | 'scope': (oScope || null), 1167 | 'fired': false 1168 | }); 1169 | }; 1170 | 1171 | this._processOnReady = function() { 1172 | if (!_s._didInit) { 1173 | // not ready yet. 1174 | return false; 1175 | } 1176 | var status = { 1177 | success: (!_s._disabled) 1178 | }; 1179 | var queue = []; 1180 | for (var i=0, j = _s._onready.length; i 1?'s':'')); 1187 | for (i = 0, j = queue.length; i 8) { 1550 | _t.instanceCount++; 1551 | } 1552 | _t.position = (typeof _t._iO.position != 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); 1553 | if (_t._iO.onplay) { 1554 | _t._iO.onplay.apply(_t); 1555 | } 1556 | _t.setVolume(_t._iO.volume, true); // restrict volume to instance options only 1557 | _t.setPan(_t._iO.pan, true); 1558 | _s.o._start(_t.sID, _t._iO.loop || 1, (_s.flashVersion == 9?_t.position:_t.position / 1000)); 1559 | } 1560 | }; 1561 | 1562 | this.start = this.play; // just for convenience 1563 | this.stop = function(bAll) { 1564 | if (_t.playState == 1) { 1565 | _t.playState = 0; 1566 | _t.paused = false; 1567 | // if (_s.defaultOptions.onstop) _s.defaultOptions.onstop.apply(_s); 1568 | if (_t._iO.onstop) { 1569 | _t._iO.onstop.apply(_t); 1570 | } 1571 | _s.o._stop(_t.sID, bAll); 1572 | _t.instanceCount = 0; 1573 | _t._iO = {}; 1574 | // _t.instanceOptions = _t._iO; 1575 | } 1576 | }; 1577 | 1578 | this.setPosition = function(nMsecOffset, bNoDebug) { 1579 | if (typeof nMsecOffset == 'undefined') { 1580 | nMsecOffset = 0; 1581 | } 1582 | var offset = Math.min(_t.duration, Math.max(nMsecOffset, 0)); // position >= 0 and <= current available (loaded) duration 1583 | _t._iO.position = offset; 1584 | if (!bNoDebug) { 1585 | // _s._wD('SMSound.setPosition('+nMsecOffset+')'+(nMsecOffset != offset?', corrected value: '+offset:'')); 1586 | } 1587 | _s.o._setPosition(_t.sID, (_s.flashVersion == 9?_t._iO.position:_t._iO.position / 1000), (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing) 1588 | }; 1589 | 1590 | this.pause = function() { 1591 | if (_t.paused || _t.playState === 0) { 1592 | return false; 1593 | } 1594 | _s._wD('SMSound.pause()'); 1595 | _t.paused = true; 1596 | _s.o._pause(_t.sID); 1597 | if (_t._iO.onpause) { 1598 | _t._iO.onpause.apply(_t); 1599 | } 1600 | }; 1601 | 1602 | this.resume = function() { 1603 | if (!_t.paused || _t.playState === 0) { 1604 | return false; 1605 | } 1606 | _s._wD('SMSound.resume()'); 1607 | _t.paused = false; 1608 | _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume) 1609 | if (_t._iO.onresume) { 1610 | _t._iO.onresume.apply(_t); 1611 | } 1612 | }; 1613 | 1614 | this.togglePause = function() { 1615 | _s._wD('SMSound.togglePause()'); 1616 | if (_t.playState === 0) { 1617 | _t.play({ 1618 | position: (_s.flashVersion == 9?_t.position:_t.position / 1000) 1619 | }); 1620 | return false; 1621 | } 1622 | if (_t.paused) { 1623 | _t.resume(); 1624 | } else { 1625 | _t.pause(); 1626 | } 1627 | }; 1628 | 1629 | this.setPan = function(nPan, bInstanceOnly) { 1630 | if (typeof nPan == 'undefined') { 1631 | nPan = 0; 1632 | } 1633 | if (typeof bInstanceOnly == 'undefined') { 1634 | bInstanceOnly = false; 1635 | } 1636 | _s.o._setPan(_t.sID, nPan); 1637 | _t._iO.pan = nPan; 1638 | if (!bInstanceOnly) { 1639 | _t.pan = nPan; 1640 | } 1641 | }; 1642 | 1643 | this.setVolume = function(nVol, bInstanceOnly) { 1644 | if (typeof nVol == 'undefined') { 1645 | nVol = 100; 1646 | } 1647 | if (typeof bInstanceOnly == 'undefined') { 1648 | bInstanceOnly = false; 1649 | } 1650 | _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol); 1651 | _t._iO.volume = nVol; 1652 | if (!bInstanceOnly) { 1653 | _t.volume = nVol; 1654 | } 1655 | }; 1656 | 1657 | this.mute = function() { 1658 | _t.muted = true; 1659 | _s.o._setVolume(_t.sID, 0); 1660 | }; 1661 | 1662 | this.unmute = function() { 1663 | _t.muted = false; 1664 | var hasIO = typeof _t._iO.volume != 'undefined'; 1665 | _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume); 1666 | }; 1667 | 1668 | this.toggleMute = function() { 1669 | if (_t.muted) { 1670 | _t.unmute(); 1671 | } else { 1672 | _t.mute(); 1673 | } 1674 | }; 1675 | 1676 | // --- "private" methods called by Flash --- 1677 | 1678 | this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration) { 1679 | if (!_t._iO.isMovieStar) { 1680 | _t.bytesLoaded = nBytesLoaded; 1681 | _t.bytesTotal = nBytesTotal; 1682 | _t.duration = Math.floor(nDuration); 1683 | _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); 1684 | if (_t.durationEstimate === undefined) { 1685 | // reported bug? 1686 | _t.durationEstimate = _t.duration; 1687 | } 1688 | if (_t.readyState != 3 && _t._iO.whileloading) { 1689 | _t._iO.whileloading.apply(_t); 1690 | } 1691 | } else { 1692 | _t.bytesLoaded = nBytesLoaded; 1693 | _t.bytesTotal = nBytesTotal; 1694 | _t.duration = Math.floor(nDuration); 1695 | _t.durationEstimate = _t.duration; 1696 | if (_t.readyState != 3 && _t._iO.whileloading) { 1697 | _t._iO.whileloading.apply(_t); 1698 | } 1699 | } 1700 | }; 1701 | 1702 | this._onid3 = function(oID3PropNames, oID3Data) { 1703 | // oID3PropNames: string array (names) 1704 | // ID3Data: string array (data) 1705 | _s._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.'); 1706 | var oData = []; 1707 | for (var i=0, j = oID3PropNames.length; i 0) { 1723 | // can happen at the end of a video where nPosition == 33 for some reason, after finishing.??? 1724 | // can also happen with a normal stop operation. This resets the position to 0. 1725 | // _s._writeDebug('Note: Not playing, but position = '+nPosition); 1726 | nPosition = 0; 1727 | } 1728 | _t.position = nPosition; 1729 | 1730 | if (_s.flashVersion > 8) { 1731 | if (_t._iO.usePeakData && typeof oPeakData != 'undefined' && oPeakData) { 1732 | _t.peakData = { 1733 | left: oPeakData.leftPeak, 1734 | right: oPeakData.rightPeak 1735 | }; 1736 | } 1737 | if (_t._iO.useWaveformData && typeof oWaveformDataLeft != 'undefined' && oWaveformDataLeft) { 1738 | _t.waveformData = { 1739 | left: oWaveformDataLeft.split(','), 1740 | right: oWaveformDataRight.split(',') 1741 | }; 1742 | } 1743 | if (_t._iO.useEQData) { 1744 | if (typeof oEQData != 'undefined' && oEQData.leftEQ) { 1745 | var eqLeft = oEQData.leftEQ.split(','); 1746 | _t.eqData = eqLeft; 1747 | _t.eqData.left = eqLeft; 1748 | if (typeof oEQData.rightEQ != 'undefined' && oEQData.rightEQ) { 1749 | _t.eqData.right = oEQData.rightEQ.split(','); 1750 | } 1751 | } 1752 | } 1753 | } 1754 | 1755 | if (_t.playState == 1) { 1756 | // special case/hack: ensure buffering is false (instant load from cache, thus buffering stuck at 1?) 1757 | if (_t.isBuffering) { 1758 | _t._onbufferchange(0); 1759 | } 1760 | if (_t._iO.whileplaying) { 1761 | _t._iO.whileplaying.apply(_t); // flash may call after actual finish 1762 | } 1763 | if (_t.loaded && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) { 1764 | _s._wD('duration-position <= onbeforefinishtime: '+_t.duration+' - '+_t.position+' <= '+_t._iO.onbeforefinishtime+' ('+(_t.duration - _t.position)+')'); 1765 | _t._onbeforefinish(); 1766 | } 1767 | } 1768 | }; 1769 | 1770 | this._onload = function(bSuccess) { 1771 | var fN = 'SMSound._onload(): '; 1772 | bSuccess = (bSuccess == 1?true:false); 1773 | _s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' loaded.':' failed to load? - '+_t.url), (bSuccess?1:2)); 1774 | if (!bSuccess) { 1775 | if (_s.sandbox.noRemote === true) { 1776 | _s._wD(fN+_s._str('noNet'), 1); 1777 | } 1778 | if (_s.sandbox.noLocal === true) { 1779 | _s._wD(fN+_s._str('noLocal'), 1); 1780 | } 1781 | } 1782 | _t.loaded = bSuccess; 1783 | _t.readyState = bSuccess?3:2; 1784 | if (_t._iO.onload) { 1785 | _t._iO.onload.apply(_t); 1786 | } 1787 | }; 1788 | 1789 | this._onbeforefinish = function() { 1790 | if (!_t.didBeforeFinish) { 1791 | _t.didBeforeFinish = true; 1792 | if (_t._iO.onbeforefinish) { 1793 | _s._wD('SMSound._onbeforefinish(): "'+_t.sID+'"'); 1794 | _t._iO.onbeforefinish.apply(_t); 1795 | } 1796 | } 1797 | }; 1798 | 1799 | this._onjustbeforefinish = function(msOffset) { 1800 | // msOffset: "end of sound" delay actual value (eg. 200 msec, value at event fire time was 187) 1801 | if (!_t.didJustBeforeFinish) { 1802 | _t.didJustBeforeFinish = true; 1803 | if (_t._iO.onjustbeforefinish) { 1804 | _s._wD('SMSound._onjustbeforefinish(): "'+_t.sID+'"'); 1805 | _t._iO.onjustbeforefinish.apply(_t); 1806 | } 1807 | } 1808 | }; 1809 | 1810 | this._onfinish = function() { 1811 | // sound has finished playing 1812 | // TODO: calling user-defined onfinish() should happen after setPosition(0) 1813 | // OR: onfinish() and then setPosition(0) is bad. 1814 | if (_t._iO.onbeforefinishcomplete) { 1815 | _t._iO.onbeforefinishcomplete.apply(_t); 1816 | } 1817 | // reset some state items 1818 | _t.didBeforeFinish = false; 1819 | _t.didJustBeforeFinish = false; 1820 | if (_t.instanceCount) { 1821 | _t.instanceCount--; 1822 | if (!_t.instanceCount) { 1823 | // reset instance options 1824 | // _t.setPosition(0); 1825 | _t.playState = 0; 1826 | _t.paused = false; 1827 | _t.instanceCount = 0; 1828 | _t.instanceOptions = {}; 1829 | } 1830 | if (!_t.instanceCount || _t._iO.multiShotEvents) { 1831 | // fire onfinish for last, or every instance 1832 | if (_t._iO.onfinish) { 1833 | _s._wD('SMSound._onfinish(): "'+_t.sID+'"'); 1834 | _t._iO.onfinish.apply(_t); 1835 | } 1836 | } 1837 | } else { 1838 | if (_t.useVideo) { 1839 | // video has finished 1840 | // may need to reset position for next play call, "rewind" 1841 | // _t.setPosition(0); 1842 | } 1843 | // _t.setPosition(0); 1844 | } 1845 | 1846 | }; 1847 | 1848 | this._onmetadata = function(oMetaData) { 1849 | // movieStar mode only 1850 | var fN = 'SMSound.onmetadata()'; 1851 | _s._wD(fN); 1852 | // Contains a subset of metadata. Note that files may have their own unique metadata. 1853 | // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html 1854 | if (!oMetaData.width && !oMetaData.height) { 1855 | _s._wDS('noWH'); 1856 | oMetaData.width = 320; 1857 | oMetaData.height = 240; 1858 | } 1859 | _t.metadata = oMetaData; // potentially-large object from flash 1860 | _t.width = oMetaData.width; 1861 | _t.height = oMetaData.height; 1862 | if (_t._iO.onmetadata) { 1863 | _s._wD(fN+': "'+_t.sID+'"'); 1864 | _t._iO.onmetadata.apply(_t); 1865 | } 1866 | _s._wD(fN+' complete'); 1867 | }; 1868 | 1869 | this._onbufferchange = function(bIsBuffering) { 1870 | var fN = 'SMSound._onbufferchange()'; 1871 | if (_t.playState === 0) { 1872 | // ignore if not playing 1873 | return false; 1874 | } 1875 | if (bIsBuffering == _t.isBuffering) { 1876 | // ignore initial "false" default, if matching 1877 | _s._wD(fN+': ignoring false default / loaded sound'); 1878 | return false; 1879 | } 1880 | _t.isBuffering = (bIsBuffering == 1?true:false); 1881 | if (_t._iO.onbufferchange) { 1882 | _s._wD(fN+': '+bIsBuffering); 1883 | _t._iO.onbufferchange.apply(_t); 1884 | } 1885 | }; 1886 | 1887 | this._ondataerror = function(sError) { 1888 | // flash 9 wave/eq data handler 1889 | if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish(). 1890 | _s._wD('SMSound._ondataerror(): '+sError); 1891 | if (_t._iO.ondataerror) { 1892 | _t._iO.ondataerror.apply(_t); 1893 | } 1894 | } else { 1895 | // _s._wD('SMSound._ondataerror(): ignoring'); 1896 | } 1897 | }; 1898 | 1899 | }; // SMSound() 1900 | 1901 | this._onfullscreenchange = function(bFullScreen) { 1902 | _s._wD('onfullscreenchange(): '+bFullScreen); 1903 | _s.isFullScreen = (bFullScreen == 1?true:false); 1904 | if (!_s.isFullScreen) { 1905 | // attempt to restore window focus after leaving full-screen 1906 | try { 1907 | window.focus(); 1908 | _s._wD('window.focus()'); 1909 | } catch(e) { 1910 | // oh well 1911 | } 1912 | } 1913 | }; 1914 | 1915 | // register a few event handlers 1916 | if (window.addEventListener) { 1917 | window.addEventListener('focus', _s.handleFocus, false); 1918 | window.addEventListener('load', _s.beginDelayedInit, false); 1919 | window.addEventListener('unload', _s.destruct, false); 1920 | if (_s._tryInitOnFocus) { 1921 | window.addEventListener('mousemove', _s.handleFocus, false); // massive Safari focus hack 1922 | } 1923 | } else if (window.attachEvent) { 1924 | window.attachEvent('onfocus', _s.handleFocus); 1925 | window.attachEvent('onload', _s.beginDelayedInit); 1926 | window.attachEvent('unload', _s.destruct); 1927 | } else { 1928 | // no add/attachevent support - safe to assume no JS -> Flash either. 1929 | _s._debugTS('onload', false); 1930 | soundManager.onerror(); 1931 | soundManager.disable(); 1932 | } 1933 | 1934 | if (document.addEventListener) { 1935 | document.addEventListener('DOMContentLoaded', _s.domContentLoaded, false); 1936 | } 1937 | 1938 | } // SoundManager() 1939 | 1940 | // var SM2_DEFER = true; // un-comment or define in your own script to prevent immediate SoundManager() constructor call+start-up. 1941 | // if deferring, construct later with window.soundManager = new SoundManager(); followed by soundManager.beginDelayedInit(); 1942 | 1943 | if (typeof SM2_DEFER == 'undefined' || !SM2_DEFER) { 1944 | soundManager = new SoundManager(); 1945 | } -------------------------------------------------------------------------------- /static/soundmanager2.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/soundmanager2.swf -------------------------------------------------------------------------------- /static/svg2canvas.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/svg2canvas.jar -------------------------------------------------------------------------------- /static/tileset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/tileset.png -------------------------------------------------------------------------------- /static/walk.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/walk.gif -------------------------------------------------------------------------------- /static/walk2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/walk2.png -------------------------------------------------------------------------------- /static/walk2.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/walk2.xcf -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 |

    Not Found

    2 | -------------------------------------------------------------------------------- /templates/500.html: -------------------------------------------------------------------------------- 1 |

    Internal Server Error

    2 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Rpg Chat Demo 6 | 7 | 8 | 9 |
    10 |

    {{ map.name }} 11 | ({{ map.x }}, {{ map.y }})

    12 |
    13 | 14 |
    15 | 16 | 17 | 18 |
      19 |
      20 | 21 |
      22 |
      23 |
      24 | 25 | 26 |
      27 | 28 | 29 |
      30 |
      31 |
      32 | 41 | 42 | 43 | 44 | 45 | 46 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /templates/message.html: -------------------------------------------------------------------------------- 1 |
      {{ message.from }}: {{ message.body }}
      2 | -------------------------------------------------------------------------------- /urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | from django.conf import settings 3 | 4 | urlpatterns = patterns('rpg.views', 5 | ('^$', 'main'), 6 | ('^a/message/new$', 'message_new'), 7 | ('^a/room/updates$', 'room_updates'), 8 | ('^a/player/new$', 'player_new'), 9 | ('^a/player/update_position$', 'player_update_position'), 10 | ('^a/change_room$', 'change_room'), 11 | ('^a/save_map', 'save_map'), 12 | ('^a/effect', 'effect'), 13 | ('^a/fight/new', 'fight_new'), 14 | 15 | ) 16 | 17 | urlpatterns += patterns('', 18 | ('^static/(?P.*)$', 'django.views.static.serve', 19 | {'document_root': settings.MEDIA_ROOT, 'show_indexes':True}), 20 | ) 21 | 22 | --------------------------------------------------------------------------------