From 34573e7f2ebbd710fffba4d120fc40db6e524344 Mon Sep 17 00:00:00 2001 From: Fergal Moran Date: Mon, 11 Mar 2013 12:25:28 +0000 Subject: [PATCH] Added nag dialog for anonymous users --- dss/settings.py | 12 +- dss/urls.py | 2 +- spa/ajax.py | 47 +- spa/api/v1/ActivityResource.py | 1 - spa/migrations/0001_initial.py | 443 -- spa/migrations/0002_auto.py | 210 - .../0003_auto__add_field_genre_slug.py | 208 - spa/migrations/0004_auto__add_mixdownload.py | 215 - ...rofile_slug__add_field_userprofile_slug.py | 215 - ...ype__add_field_label_content_type__add_.py | 322 -- ...ype__del_field_label_content_type__del_.py | 309 -- .../0008_auto__chg_field_comment_mix.py | 211 - spa/migrations/__init__.py | 0 spa/models/Mix.py | 47 +- spa/models/MixPlay.py | 4 +- spa/models/UserProfile.py | 4 +- spa/models/_Activity.py | 16 +- spa/models/__init__.py | 2 +- .../managers/QueuedActivityModelManager.py | 16 + spa/{realtime => models/managers}/__init__.py | 0 spa/signals.py | 47 + spa/views.py | 10 +- static/bin/sm/soundmanager2.swf | Bin 2888 -> 2934 bytes static/bin/sm/soundmanager2_debug.swf | Bin 3303 -> 3310 bytes static/bin/sm/soundmanager2_flash9.swf | Bin 8927 -> 8696 bytes static/bin/sm/soundmanager2_flash9_debug.swf | Bin 17215 -> 17093 bytes static/bin/sm/soundmanager2_flash_xdomain.zip | Bin 33125 -> 32825 bytes static/js/app/views/mix.js | 1 + static/js/com.podnoms.realtime.js | 38 + static/js/com.podnoms.utils.js | 19 + static/js/libs/sm/soundmanager2-jsmin.js | 190 +- .../js/libs/sm/soundmanager2-nodebug-jsmin.js | 136 +- static/js/libs/sm/soundmanager2-nodebug.js | 2277 +++++----- static/js/libs/sm/soundmanager2.js | 3157 +++++++------- static/js/libs/socket.io.js | 3818 +++++++++++++++++ templates/base.html | 3 + templates/javascript/settings.js | 2 + 37 files changed, 7019 insertions(+), 4963 deletions(-) delete mode 100644 spa/migrations/0001_initial.py delete mode 100644 spa/migrations/0002_auto.py delete mode 100644 spa/migrations/0003_auto__add_field_genre_slug.py delete mode 100644 spa/migrations/0004_auto__add_mixdownload.py delete mode 100644 spa/migrations/0005_auto__del_field_userprofile_profile_slug__add_field_userprofile_slug.py delete mode 100644 spa/migrations/0006_auto__add_field_venue_content_type__add_field_label_content_type__add_.py delete mode 100644 spa/migrations/0007_auto__del_field_venue_content_type__del_field_label_content_type__del_.py delete mode 100644 spa/migrations/0008_auto__chg_field_comment_mix.py delete mode 100644 spa/migrations/__init__.py create mode 100644 spa/models/managers/QueuedActivityModelManager.py rename spa/{realtime => models/managers}/__init__.py (100%) create mode 100644 static/js/com.podnoms.realtime.js create mode 100644 static/js/libs/socket.io.js diff --git a/dss/settings.py b/dss/settings.py index 6403b78..060f443 100644 --- a/dss/settings.py +++ b/dss/settings.py @@ -152,7 +152,6 @@ INSTALLED_APPS = ( 'sorl.thumbnail', 'south', 'avatar', - 'notification', 'spa', 'spa.signals', 'core', @@ -185,11 +184,12 @@ if DEBUG: FACEBOOK_APP_ID = '154504534677009' FACEBOOK_APP_SECRET = localsettings.FACEBOOK_APP_SECRET -BROKER_HOST = "127.0.0.1" -BROKER_PORT = 5672 -BROKER_VHOST = "/" -BROKER_USER = "guest" -BROKER_PASSWORD = "guest" +BROKER_HOST = localsettings.BROKER_HOST +BROKER_PORT = localsettings.BROKER_PORT +BROKER_VHOST = localsettings.BROKER_VHOST +BROKER_USER = localsettings.BROKER_USER +BROKER_PASSWORD = localsettings.BROKER_PASSWORD + CELERYBEAT_SCHEDULE = { "runs-every-30-seconds": { "task": "dss.generate_missing_waveforms_task", diff --git a/dss/urls.py b/dss/urls.py index 0a80bb6..ca802ff 100644 --- a/dss/urls.py +++ b/dss/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import patterns, include, url from django.contrib import admin -from django.http import HttpResponse + from dss import settings admin.autodiscover() diff --git a/spa/ajax.py b/spa/ajax.py index c42ee08..d459dd7 100644 --- a/spa/ajax.py +++ b/spa/ajax.py @@ -1,3 +1,6 @@ +import os +import logging + from django.conf.urls import url from django.contrib.auth.decorators import login_required from django.db.models import get_model @@ -6,7 +9,7 @@ from annoying.decorators import render_to from django.shortcuts import render_to_response from django.utils import simplejson from django.views.decorators.csrf import csrf_exempt -import os + from core.utils import live from dss import localsettings, settings from spa import social @@ -16,9 +19,11 @@ from spa.models.Comment import Comment from spa.models.MixLike import MixLike from core.serialisers import json from core.tasks import create_waveform_task -import logging + + logger = logging.getLogger(__name__) + class AjaxHandler(object): # Get an instance of a logger @@ -32,14 +37,17 @@ class AjaxHandler(object): url(r'^mix/add_comment/$', 'spa.ajax.mix_add_comment', name='mix_add_comment'), url(r'^mix/comments/(?P\d+)/$', 'spa.ajax.mix_comments', name='ajax_mix_comments'), url(r'^header/$', 'spa.ajax.header', name='header'), + url(r'^session_play_count/$', 'spa.ajax.session_play_count'), url(r'^mix_stream_url/(?P\d+)/$', 'spa.ajax.get_mix_stream_url'), url(r'^release_player/(?P\d+)/$', 'spa.ajax.release_player'), url(r'^live_now_playing/$', 'spa.ajax.live_now_playing'), url(r'^like/$', 'spa.ajax.like', name='ajax_mix_like'), url(r'^favourite/$', 'spa.ajax.favourite', name='ajax_mix_favourite'), - url(r'^facebook_post_likes_allowed/$', 'spa.ajax.facebook_post_likes_allowed', name='ajax_facebook_post_likes_allowed'), + url(r'^facebook_post_likes_allowed/$', 'spa.ajax.facebook_post_likes_allowed', + name='ajax_facebook_post_likes_allowed'), url(r'^upload_image/(?P\d+)/$', 'spa.ajax.upload_image', name='ajax_upload_image'), - url(r'^upload_release_image/(?P\d+)/$', 'spa.ajax.upload_release_image', name='ajax_upload_release_image'), + url(r'^upload_release_image/(?P\d+)/$', 'spa.ajax.upload_release_image', + name='ajax_upload_release_image'), url(r'^upload_avatar_image/$', 'spa.ajax.upload_avatar_image', name='ajax_upload_avatar_image'), url(r'^upload_mix_file_handler/$', 'spa.ajax.upload_mix_file_handler', name='ajax_upload_mix_file_handler'), url(r'^lookup/(?P\w+)/$', 'spa.ajax.lookup', name='ajax_lookup'), @@ -69,8 +77,26 @@ def header(request): return HttpResponse(render_to_response('inc/header.html')) +def session_play_count(request): + if 'play_count' in request.session: + result = simplejson.dumps({ + 'play_count': request.session['play_count'] + }) + else: + result = simplejson.dumps({ + 'play_count': '0' + }) + return HttpResponse(result, mimetype='application/json') + + def get_mix_stream_url(request, mix_id): try: + if not request.user.is_authenticated(): + if 'play_count' in request.session: + request.session['play_count'] += 1 + else: + request.session['play_count'] = 1 + mix = Mix.objects.get(pk=mix_id) data = { 'stream_url': mix.get_stream_path(), @@ -94,10 +120,12 @@ def live_now_playing(request): localsettings.JS_SETTINGS['LIVE_STREAM_MOUNT']) }), mimetype="application/json") + @render_to('inc/release_player.html') def release_player(request, release_id): return HttpResponse('Hello Sailor') + def mix_add_comment(request): if request.POST: comment = Comment() @@ -111,11 +139,13 @@ def mix_add_comment(request): else: return HttpResponse(_get_json('Error posting', 'description')) + @render_to('inc/comment_list.html') def mix_comments(request, mix_id): return { "results": Comment.objects.filter(mix_id=mix_id), - } + } + @login_required() def like(request): @@ -139,6 +169,7 @@ def like(request): mix.save() return HttpResponse(response) + @login_required() def favourite(request): if request.is_ajax(): @@ -155,6 +186,7 @@ def favourite(request): mix.save() return HttpResponse(response) + @login_required() def facebook_post_likes_allowed(request): profile = request.user.get_profile(); @@ -166,6 +198,7 @@ def facebook_post_likes_allowed(request): return HttpResponse(_get_json(False), mimetype="application/json") + @csrf_exempt def upload_release_image(request, release_id): try: @@ -179,6 +212,7 @@ def upload_release_image(request, release_id): logger.exception("Error uploading avatar") return HttpResponse(_get_json("Failed")) + @csrf_exempt def upload_image(request, mix_id): try: @@ -192,6 +226,7 @@ def upload_image(request, mix_id): logger.exception("Error uploading avatar") return HttpResponse(_get_json("Failed")) + @csrf_exempt def upload_avatar_image(request): try: @@ -205,6 +240,7 @@ def upload_avatar_image(request): logger.exception("Error uploading avatar") return HttpResponse(_get_json("Failed")) + @csrf_exempt def upload_mix_file_handler(request): try: @@ -225,6 +261,7 @@ def upload_mix_file_handler(request): logger.exception("Error uploading mix") return HttpResponse(_get_json("Failed"), mimetype='application/json') + @csrf_exempt def lookup(request, source): query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else '' diff --git a/spa/api/v1/ActivityResource.py b/spa/api/v1/ActivityResource.py index 798569f..c9566e2 100644 --- a/spa/api/v1/ActivityResource.py +++ b/spa/api/v1/ActivityResource.py @@ -7,7 +7,6 @@ from spa.models._Activity import _Activity class ActivityResource(BackboneCompatibleResource): class Meta: - #queryset = _Activity.objects.filter(pk=3442).order_by('-date') queryset = _Activity.objects.all().order_by('-date') resource_name = 'activity' authorization = Authorization() diff --git a/spa/migrations/0001_initial.py b/spa/migrations/0001_initial.py deleted file mode 100644 index f9106e9..0000000 --- a/spa/migrations/0001_initial.py +++ /dev/null @@ -1,443 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'UserProfile' - db.create_table('spa_userprofile', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True)), - ('avatar_type', self.gf('django.db.models.fields.CharField')(default='social', max_length=15)), - ('avatar_image', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)), - ('display_name', self.gf('django.db.models.fields.CharField')(max_length=35, blank=True)), - ('description', self.gf('django.db.models.fields.CharField')(max_length=2048, blank=True)), - ('profile_slug', self.gf('django.db.models.fields.CharField')(default=None, max_length=35, null=True, blank=True)), - ('activity_sharing', self.gf('django.db.models.fields.IntegerField')(default=0)), - ('activity_sharing_networks', self.gf('django.db.models.fields.IntegerField')(default=0)), - )) - db.send_create_signal('spa', ['UserProfile']) - - # Adding model '_Activity' - db.create_table('spa__activity', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)), - ('uid', self.gf('django.db.models.fields.CharField')(max_length=50, null=True, blank=True)), - )) - db.send_create_signal('spa', ['_Activity']) - - # Adding model 'ChatMessage' - db.create_table('spa_chatmessage', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('message', self.gf('django.db.models.fields.TextField')()), - ('timestamp', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='chat_messages', null=True, to=orm['spa.UserProfile'])), - )) - db.send_create_signal('spa', ['ChatMessage']) - - # Adding model '_Lookup' - db.create_table('spa__lookup', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('description', self.gf('django.db.models.fields.CharField')(max_length=100)), - )) - db.send_create_signal('spa', ['_Lookup']) - - # Adding model 'Recurrence' - db.create_table('spa_recurrence', ( - ('_lookup_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['spa._Lookup'], unique=True, primary_key=True)), - )) - db.send_create_signal('spa', ['Recurrence']) - - # Adding model 'Genre' - db.create_table('spa_genre', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('description', self.gf('django.db.models.fields.CharField')(max_length=100)), - )) - db.send_create_signal('spa', ['Genre']) - - # Adding model 'MixPlay' - db.create_table('spa_mixplay', ( - ('_activity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['spa._Activity'], unique=True, primary_key=True)), - ('mix', self.gf('django.db.models.fields.related.ForeignKey')(related_name='plays', to=orm['spa.Mix'])), - )) - db.send_create_signal('spa', ['MixPlay']) - - # Adding model 'Mix' - db.create_table('spa_mix', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('title', self.gf('django.db.models.fields.CharField')(max_length=50)), - ('description', self.gf('django.db.models.fields.TextField')()), - ('upload_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2012, 10, 23, 0, 0))), - ('mix_image', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)), - ('local_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, blank=True)), - ('download_url', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('stream_url', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)), - ('is_featured', self.gf('django.db.models.fields.BooleanField')(default=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.UserProfile'])), - ('waveform_generated', self.gf('django.db.models.fields.BooleanField')(default=False)), - ('uid', self.gf('django.db.models.fields.CharField')(unique=True, max_length=38, blank=True)), - ('download_allowed', self.gf('django.db.models.fields.BooleanField')(default=False)), - )) - db.send_create_signal('spa', ['Mix']) - - # Adding model 'Comment' - db.create_table('spa_comment', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), - ('mix', self.gf('django.db.models.fields.related.ForeignKey')(related_name='comments', to=orm['spa.Mix'])), - ('comment', self.gf('django.db.models.fields.CharField')(max_length=1024)), - ('date_created', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), - ('time_index', self.gf('django.db.models.fields.IntegerField')()), - )) - db.send_create_signal('spa', ['Comment']) - - # Adding model 'Venue' - db.create_table('spa_venue', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), - ('venue_name', self.gf('django.db.models.fields.CharField')(max_length=250)), - ('venue_address', self.gf('django.db.models.fields.CharField')(max_length=1024)), - ('venue_image', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)), - )) - db.send_create_signal('spa', ['Venue']) - - # Adding model 'Event' - db.create_table('spa_event', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('event_venue', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.Venue'])), - ('event_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 10, 23, 0, 0))), - ('event_time', self.gf('django.db.models.fields.TimeField')(default=datetime.datetime(2012, 10, 23, 0, 0))), - ('date_created', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 10, 23, 0, 0))), - ('event_title', self.gf('django.db.models.fields.CharField')(max_length=250)), - ('event_description', self.gf('tinymce.models.HTMLField')()), - ('event_recurrence', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.Recurrence'])), - )) - db.send_create_signal('spa', ['Event']) - - # Adding M2M table for field attendees on 'Event' - db.create_table('spa_event_attendees', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('event', models.ForeignKey(orm['spa.event'], null=False)), - ('user', models.ForeignKey(orm['auth.user'], null=False)) - )) - db.create_unique('spa_event_attendees', ['event_id', 'user_id']) - - # Adding model 'Label' - db.create_table('spa_label', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('name', self.gf('django.db.models.fields.CharField')(max_length=100)), - )) - db.send_create_signal('spa', ['Label']) - - # Adding model 'MixLike' - db.create_table('spa_mixlike', ( - ('_activity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['spa._Activity'], unique=True, primary_key=True)), - ('mix', self.gf('django.db.models.fields.related.ForeignKey')(related_name='likes', to=orm['spa.Mix'])), - )) - db.send_create_signal('spa', ['MixLike']) - - # Adding model 'Tracklist' - db.create_table('spa_tracklist', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('mix', self.gf('django.db.models.fields.related.ForeignKey')(related_name='tracklist', to=orm['spa.Mix'])), - ('index', self.gf('django.db.models.fields.SmallIntegerField')()), - ('timeindex', self.gf('django.db.models.fields.TimeField')(null=True)), - ('description', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('artist', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('title', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('remixer', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('label', self.gf('django.db.models.fields.CharField')(max_length=255)), - )) - db.send_create_signal('spa', ['Tracklist']) - - # Adding model 'PurchaseLink' - db.create_table('spa_purchaselink', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('track', self.gf('django.db.models.fields.related.ForeignKey')(related_name='purchase_link', to=orm['spa.Tracklist'])), - ('url', self.gf('django.db.models.fields.URLField')(max_length=200)), - ('provider', self.gf('django.db.models.fields.CharField')(max_length=255)), - )) - db.send_create_signal('spa', ['PurchaseLink']) - - # Adding model 'Release' - db.create_table('spa_release', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('release_artist', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('release_title', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('release_description', self.gf('django.db.models.fields.TextField')()), - ('release_image', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)), - ('release_label', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.Label'])), - ('release_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 10, 23, 0, 0))), - ('embed_code', self.gf('django.db.models.fields.TextField')(blank=True)), - ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['spa.UserProfile'])), - )) - db.send_create_signal('spa', ['Release']) - - # Adding model 'ReleaseAudio' - db.create_table('spa_releaseaudio', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('local_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)), - ('release', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='release_audio', null=True, to=orm['spa.Release'])), - ('description', self.gf('django.db.models.fields.TextField')()), - )) - db.send_create_signal('spa', ['ReleaseAudio']) - - # Adding model 'MixFavourite' - db.create_table('spa_mixfavourite', ( - ('_activity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['spa._Activity'], unique=True, primary_key=True)), - ('mix', self.gf('django.db.models.fields.related.ForeignKey')(related_name='favourites', to=orm['spa.Mix'])), - )) - db.send_create_signal('spa', ['MixFavourite']) - - - def backwards(self, orm): - # Deleting model 'UserProfile' - db.delete_table('spa_userprofile') - - # Deleting model '_Activity' - db.delete_table('spa__activity') - - # Deleting model 'ChatMessage' - db.delete_table('spa_chatmessage') - - # Deleting model '_Lookup' - db.delete_table('spa__lookup') - - # Deleting model 'Recurrence' - db.delete_table('spa_recurrence') - - # Deleting model 'Genre' - db.delete_table('spa_genre') - - # Deleting model 'MixPlay' - db.delete_table('spa_mixplay') - - # Deleting model 'Mix' - db.delete_table('spa_mix') - - # Deleting model 'Comment' - db.delete_table('spa_comment') - - # Deleting model 'Venue' - db.delete_table('spa_venue') - - # Deleting model 'Event' - db.delete_table('spa_event') - - # Removing M2M table for field attendees on 'Event' - db.delete_table('spa_event_attendees') - - # Deleting model 'Label' - db.delete_table('spa_label') - - # Deleting model 'MixLike' - db.delete_table('spa_mixlike') - - # Deleting model 'Tracklist' - db.delete_table('spa_tracklist') - - # Deleting model 'PurchaseLink' - db.delete_table('spa_purchaselink') - - # Deleting model 'Release' - db.delete_table('spa_release') - - # Deleting model 'ReleaseAudio' - db.delete_table('spa_releaseaudio') - - # Deleting model 'MixFavourite' - db.delete_table('spa_mixfavourite') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'profile_slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0002_auto.py b/spa/migrations/0002_auto.py deleted file mode 100644 index 08be8d3..0000000 --- a/spa/migrations/0002_auto.py +++ /dev/null @@ -1,210 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding M2M table for field genres on 'Mix' - db.create_table('spa_mix_genres', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('mix', models.ForeignKey(orm['spa.mix'], null=False)), - ('genre', models.ForeignKey(orm['spa.genre'], null=False)) - )) - db.create_unique('spa_mix_genres', ['mix_id', 'genre_id']) - - - def backwards(self, orm): - # Removing M2M table for field genres on 'Mix' - db.delete_table('spa_mix_genres') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 23, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'profile_slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0003_auto__add_field_genre_slug.py b/spa/migrations/0003_auto__add_field_genre_slug.py deleted file mode 100644 index b4a9c20..0000000 --- a/spa/migrations/0003_auto__add_field_genre_slug.py +++ /dev/null @@ -1,208 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'Genre.slug' - db.add_column('spa_genre', 'slug', - self.gf('django.db.models.fields.CharField')(max_length=100, null=True), - keep_default=False) - - - def backwards(self, orm): - # Deleting field 'Genre.slug' - db.delete_column('spa_genre', 'slug') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 24, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 24, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 10, 24, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 10, 24, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 24, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'profile_slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0004_auto__add_mixdownload.py b/spa/migrations/0004_auto__add_mixdownload.py deleted file mode 100644 index 6a55b34..0000000 --- a/spa/migrations/0004_auto__add_mixdownload.py +++ /dev/null @@ -1,215 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'MixDownload' - db.create_table('spa_mixdownload', ( - ('_activity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['spa._Activity'], unique=True, primary_key=True)), - ('mix', self.gf('django.db.models.fields.related.ForeignKey')(related_name='downloads', to=orm['spa.Mix'])), - )) - db.send_create_signal('spa', ['MixDownload']) - - - def backwards(self, orm): - # Deleting model 'MixDownload' - db.delete_table('spa_mixdownload') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixdownload': { - 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'profile_slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0005_auto__del_field_userprofile_profile_slug__add_field_userprofile_slug.py b/spa/migrations/0005_auto__del_field_userprofile_profile_slug__add_field_userprofile_slug.py deleted file mode 100644 index de07d3f..0000000 --- a/spa/migrations/0005_auto__del_field_userprofile_profile_slug__add_field_userprofile_slug.py +++ /dev/null @@ -1,215 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Deleting field 'UserProfile.profile_slug' - db.rename_column('spa_userprofile', 'profile_slug', 'slug') - - def backwards(self, orm): - # Adding field 'UserProfile.profile_slug' - db.add_column('spa_userprofile', 'profile_slug', - self.gf('django.db.models.fields.CharField')(default=None, max_length=35, null=True, blank=True), - keep_default=False) - - # Deleting field 'UserProfile.slug' - db.delete_column('spa_userprofile', 'slug') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixdownload': { - 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 10, 27, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0006_auto__add_field_venue_content_type__add_field_label_content_type__add_.py b/spa/migrations/0006_auto__add_field_venue_content_type__add_field_label_content_type__add_.py deleted file mode 100644 index c2627c0..0000000 --- a/spa/migrations/0006_auto__add_field_venue_content_type__add_field_label_content_type__add_.py +++ /dev/null @@ -1,322 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'Venue.content_type' - db.add_column('spa_venue', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Label.content_type' - db.add_column('spa_label', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'ChatMessage.content_type' - db.add_column('spa_chatmessage', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Release.content_type' - db.add_column('spa_release', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field '_Lookup.content_type' - db.add_column('spa__lookup', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'ReleaseAudio.content_type' - db.add_column('spa_releaseaudio', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Comment.content_type' - db.add_column('spa_comment', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field '_Activity.content_type' - db.add_column('spa__activity', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Mix.content_type' - db.add_column('spa_mix', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Tracklist.content_type' - db.add_column('spa_tracklist', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Genre.content_type' - db.add_column('spa_genre', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'UserProfile.content_type' - db.add_column('spa_userprofile', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'PurchaseLink.content_type' - db.add_column('spa_purchaselink', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - - def backwards(self, orm): - # Deleting field 'Venue.content_type' - db.delete_column('spa_venue', 'content_type_id') - - # Deleting field 'Label.content_type' - db.delete_column('spa_label', 'content_type_id') - - # Deleting field 'ChatMessage.content_type' - db.delete_column('spa_chatmessage', 'content_type_id') - - # Deleting field 'Release.content_type' - db.delete_column('spa_release', 'content_type_id') - - # Deleting field '_Lookup.content_type' - db.delete_column('spa__lookup', 'content_type_id') - - # Deleting field 'ReleaseAudio.content_type' - db.delete_column('spa_releaseaudio', 'content_type_id') - - # Deleting field 'Comment.content_type' - db.delete_column('spa_comment', 'content_type_id') - - # Deleting field '_Activity.content_type' - db.delete_column('spa__activity', 'content_type_id') - - # Deleting field 'Mix.content_type' - db.delete_column('spa_mix', 'content_type_id') - - # Deleting field 'Tracklist.content_type' - db.delete_column('spa_tracklist', 'content_type_id') - - # Deleting field 'Genre.content_type' - db.delete_column('spa_genre', 'content_type_id') - - # Deleting field 'UserProfile.content_type' - db.delete_column('spa_userprofile', 'content_type_id') - - # Deleting field 'PurchaseLink.content_type' - db.delete_column('spa_purchaselink', 'content_type_id') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 3, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 3, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 12, 3, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 3, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixdownload': { - 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 3, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0007_auto__del_field_venue_content_type__del_field_label_content_type__del_.py b/spa/migrations/0007_auto__del_field_venue_content_type__del_field_label_content_type__del_.py deleted file mode 100644 index fc9626e..0000000 --- a/spa/migrations/0007_auto__del_field_venue_content_type__del_field_label_content_type__del_.py +++ /dev/null @@ -1,309 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Deleting field 'Venue.content_type' - db.delete_column('spa_venue', 'content_type_id') - - # Deleting field 'Label.content_type' - db.delete_column('spa_label', 'content_type_id') - - # Deleting field 'ChatMessage.content_type' - db.delete_column('spa_chatmessage', 'content_type_id') - - # Deleting field 'Release.content_type' - db.delete_column('spa_release', 'content_type_id') - - # Deleting field '_Lookup.content_type' - db.delete_column('spa__lookup', 'content_type_id') - - # Deleting field 'ReleaseAudio.content_type' - db.delete_column('spa_releaseaudio', 'content_type_id') - - # Deleting field 'Comment.content_type' - db.delete_column('spa_comment', 'content_type_id') - - # Deleting field '_Activity.content_type' - db.delete_column('spa__activity', 'content_type_id') - - # Deleting field 'Mix.content_type' - db.delete_column('spa_mix', 'content_type_id') - - # Deleting field 'Tracklist.content_type' - db.delete_column('spa_tracklist', 'content_type_id') - - # Deleting field 'Genre.content_type' - db.delete_column('spa_genre', 'content_type_id') - - # Deleting field 'UserProfile.content_type' - db.delete_column('spa_userprofile', 'content_type_id') - - # Deleting field 'PurchaseLink.content_type' - db.delete_column('spa_purchaselink', 'content_type_id') - - - def backwards(self, orm): - # Adding field 'Venue.content_type' - db.add_column('spa_venue', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Label.content_type' - db.add_column('spa_label', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'ChatMessage.content_type' - db.add_column('spa_chatmessage', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Release.content_type' - db.add_column('spa_release', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field '_Lookup.content_type' - db.add_column('spa__lookup', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'ReleaseAudio.content_type' - db.add_column('spa_releaseaudio', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Comment.content_type' - db.add_column('spa_comment', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field '_Activity.content_type' - db.add_column('spa__activity', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Mix.content_type' - db.add_column('spa_mix', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Tracklist.content_type' - db.add_column('spa_tracklist', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'Genre.content_type' - db.add_column('spa_genre', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'UserProfile.content_type' - db.add_column('spa_userprofile', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - # Adding field 'PurchaseLink.content_type' - db.add_column('spa_purchaselink', 'content_type', - self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True), - keep_default=False) - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixdownload': { - 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/0008_auto__chg_field_comment_mix.py b/spa/migrations/0008_auto__chg_field_comment_mix.py deleted file mode 100644 index 28e941e..0000000 --- a/spa/migrations/0008_auto__chg_field_comment_mix.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Changing field 'Comment.mix' - db.alter_column('spa_comment', 'mix_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, to=orm['spa.Mix'])) - - def backwards(self, orm): - - # Changing field 'Comment.mix' - db.alter_column('spa_comment', 'mix_id', self.gf('django.db.models.fields.related.ForeignKey')(default='', to=orm['spa.Mix'])) - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa._activity': { - 'Meta': {'object_name': '_Activity'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}) - }, - 'spa._lookup': { - 'Meta': {'object_name': '_Lookup'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.chatmessage': { - 'Meta': {'object_name': 'ChatMessage'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.TextField', [], {}), - 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"}) - }, - 'spa.comment': { - 'Meta': {'object_name': 'Comment'}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['spa.Mix']"}), - 'time_index': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'spa.event': { - 'Meta': {'object_name': 'Event'}, - 'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 2, 21, 0, 0)'}), - 'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 2, 21, 0, 0)'}), - 'event_description': ('tinymce.models.HTMLField', [], {}), - 'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}), - 'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2013, 2, 21, 0, 0)'}), - 'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) - }, - 'spa.genre': { - 'Meta': {'object_name': 'Genre'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'spa.label': { - 'Meta': {'object_name': 'Label'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'spa.mix': { - 'Meta': {'object_name': 'Mix'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), - 'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}), - 'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 2, 21, 0, 0)'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}), - 'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'spa.mixdownload': { - 'Meta': {'object_name': 'MixDownload', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'downloads'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixfavourite': { - 'Meta': {'object_name': 'MixFavourite', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'favourites'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixlike': { - 'Meta': {'object_name': 'MixLike', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'likes'", 'to': "orm['spa.Mix']"}) - }, - 'spa.mixplay': { - 'Meta': {'object_name': 'MixPlay', '_ormbases': ['spa._Activity']}, - '_activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Activity']", 'unique': 'True', 'primary_key': 'True'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'plays'", 'to': "orm['spa.Mix']"}) - }, - 'spa.purchaselink': { - 'Meta': {'object_name': 'PurchaseLink'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) - }, - 'spa.recurrence': { - 'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']}, - '_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'}) - }, - 'spa.release': { - 'Meta': {'object_name': 'Release'}, - 'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 2, 21, 0, 0)'}), - 'release_description': ('django.db.models.fields.TextField', [], {}), - 'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}), - 'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}) - }, - 'spa.releaseaudio': { - 'Meta': {'object_name': 'ReleaseAudio'}, - 'description': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - 'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"}) - }, - 'spa.tracklist': { - 'Meta': {'object_name': 'Tracklist'}, - 'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.SmallIntegerField', [], {}), - 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}), - 'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'spa.userprofile': { - 'Meta': {'object_name': 'UserProfile'}, - 'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}), - 'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), - 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '35', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'spa.venue': { - 'Meta': {'object_name': 'Venue'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), - 'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), - 'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'}) - } - } - - complete_apps = ['spa'] \ No newline at end of file diff --git a/spa/migrations/__init__.py b/spa/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/spa/models/Mix.py b/spa/models/Mix.py index 6b4a429..ab68294 100644 --- a/spa/models/Mix.py +++ b/spa/models/Mix.py @@ -1,12 +1,13 @@ import os import rfc822 -from core.utils import url from datetime import datetime + from sorl.thumbnail import get_thumbnail from django.contrib.sites.models import Site -from sorl.thumbnail.helpers import ThumbnailError from django.db import models from django.db.models import Count + +from core.utils import url from spa.models.Genre import Genre from spa.models.MixPlay import MixPlay from spa.models.MixDownload import MixDownload @@ -15,11 +16,13 @@ from spa.models.UserProfile import UserProfile from spa.models._BaseModel import _BaseModel from core.utils.file import generate_save_file_name + def mix_file_name(instance, filename): return generate_save_file_name(instance.uid, 'mixes', filename) + def mix_image_name(instance, filename): - ret = generate_save_file_name(instance.uid, 'mix-images', filename) + ret = generate_save_file_name(instance.uid, 'mix-images', filename) return ret @@ -72,7 +75,8 @@ class Mix(_BaseModel): return os.path.join(settings.MEDIA_ROOT, "waveforms/", "%s.%s" % (self.uid, "png")) def get_waveform_url(self): - waveform_root = localsettings.WAVEFORM_URL if hasattr(localsettings, 'WAVEFORM_URL') else "%s/waveforms/" % settings.MEDIA_URL + waveform_root = localsettings.WAVEFORM_URL if hasattr(localsettings, + 'WAVEFORM_URL') else "%s/waveforms/" % settings.MEDIA_URL ret = "%s/%s.%s" % (waveform_root, self.uid, "png") return url.urlclean(ret) @@ -97,25 +101,26 @@ class Mix(_BaseModel): return '/audio/stream/%d' % self.id def get_date_as_rfc822(self): - return rfc822.formatdate(rfc822.mktime_tz(rfc822.parsedate_tz(self.upload_date.strftime("%a, %d %b %Y %H:%M:%S")))) + return rfc822.formatdate( + rfc822.mktime_tz(rfc822.parsedate_tz(self.upload_date.strftime("%a, %d %b %Y %H:%M:%S")))) @classmethod def get_for_username(cls, user): - queryset = Mix.objects\ - .filter(user__slug__exact=user)\ - .filter(waveform_generated=True)\ - .order_by( '-id') + queryset = Mix.objects \ + .filter(user__slug__exact=user) \ + .filter(waveform_generated=True) \ + .order_by('-id') return queryset @classmethod def get_listing(cls, listing_type, user=None): queryset = None - candidates = Mix.objects\ - .filter(waveform_generated=True)\ + candidates = Mix.objects \ + .filter(waveform_generated=True) \ .filter(is_featured=True) if listing_type == 'latest': - queryset = candidates.order_by( '-id') + queryset = candidates.order_by('-id') elif listing_type == 'toprated': queryset = candidates.annotate(karma=Count('likes')).order_by('-karma') elif listing_type == 'mostactive': @@ -123,12 +128,12 @@ class Mix(_BaseModel): elif listing_type == 'mostplayed': queryset = candidates.annotate(karma=Count('plays')).order_by('-karma') elif listing_type == 'recommended': - queryset = candidates.order_by( '-id') + queryset = candidates.order_by('-id') elif listing_type == 'favourites': queryset = candidates.filter(favourites__user=user).order_by('favourites__date') else: #check if we have a valid genre - queryset = candidates.filter(genres__slug__exact = listing_type) + queryset = candidates.filter(genres__slug__exact=listing_type) return queryset @classmethod @@ -139,30 +144,30 @@ class Mix(_BaseModel): "inline_play": False, "heading": "Some mixes from " + mixes[0].user.user.get_full_name() or mixes[0].user.user.username, "latest_mix_list": mixes, - } + } return { "heading": "No mixes found for this user", "latest_mix_list": None, - } + } def add_download(self, user): try: - self.downloads.add(MixDownload(user = user if user.is_authenticated() else None)) + self.downloads.add(MixDownload(user=user if user.is_authenticated() else None)) except Exception, e: self.logger.exception("Error adding mix download") def add_play(self, user): try: - self.plays.add(MixPlay(user = user if user.is_authenticated() else None)) + self.plays.add(MixPlay(user=user if user.is_authenticated() else None)) except Exception, e: - self.logger.exception("Error getting mix stream url") + self.logger.exception("Unable to add mix play") def is_liked(self, user): if user is None: return False if user.is_authenticated(): - return self.likes.filter(user=user).count() <> 0 + return self.likes.filter(user=user).count() != 0 return False @@ -170,6 +175,6 @@ class Mix(_BaseModel): if user is None: return False if user.is_authenticated(): - return self.favourites.filter(user=user).count() <> 0 + return self.favourites.filter(user=user).count() != 0 else: return False diff --git a/spa/models/MixPlay.py b/spa/models/MixPlay.py index 906d287..8e92fe5 100644 --- a/spa/models/MixPlay.py +++ b/spa/models/MixPlay.py @@ -1,6 +1,7 @@ from django.db import models from spa.models._Activity import _Activity + class MixPlay(_Activity): mix = models.ForeignKey('spa.Mix', related_name='plays') @@ -14,4 +15,5 @@ class MixPlay(_Activity): return self.mix.title def get_object_url(self): - return self.mix.get_absolute_url() \ No newline at end of file + return self.mix.get_absolute_url() + diff --git a/spa/models/UserProfile.py b/spa/models/UserProfile.py index 97d6b87..78731a0 100644 --- a/spa/models/UserProfile.py +++ b/spa/models/UserProfile.py @@ -49,7 +49,7 @@ class UserProfile(_BaseModel): Save Photo after ensuring it is not blank. Resize as needed. """ - if not self.id and not self.source: + if not self.id: return if self.slug == '': @@ -147,5 +147,3 @@ class UserProfile(_BaseModel): @classmethod def get_default_avatar_image(cls): return urlparse.urljoin(settings.STATIC_URL, "img/default-avatar-32.png") - - diff --git a/spa/models/_Activity.py b/spa/models/_Activity.py index 3e694d4..4c6d717 100644 --- a/spa/models/_Activity.py +++ b/spa/models/_Activity.py @@ -1,9 +1,13 @@ -from django.contrib.auth.models import User -from django.contrib.contenttypes.models import ContentType -from django.db import models import abc + +from django.contrib.auth.models import User +from django.db import models + from model_utils.managers import InheritanceManager + from spa.models._BaseModel import _BaseModel +from spa.models.managers.QueuedActivityModelManager import QueuedActivityModelManager + class _Activity(_BaseModel): user = models.ForeignKey(User, null=True) @@ -11,6 +15,11 @@ class _Activity(_BaseModel): date = models.DateTimeField(auto_now=True) objects = InheritanceManager() + message_manager = QueuedActivityModelManager() + + class Meta: + app_label = 'spa' + @abc.abstractmethod def get_verb_passed(self): return @@ -34,3 +43,4 @@ class _Activity(_BaseModel): @abc.abstractmethod def get_object_url(self): return + diff --git a/spa/models/__init__.py b/spa/models/__init__.py index aa5b904..41fb651 100644 --- a/spa/models/__init__.py +++ b/spa/models/__init__.py @@ -1,6 +1,5 @@ from _BaseModel import _BaseModel from UserProfile import UserProfile -from _Activity import _Activity from ChatMessage import ChatMessage from Recurrence import Recurrence from Comment import Comment @@ -8,6 +7,7 @@ from Venue import Venue from Event import Event from Label import Label from Mix import Mix +from _Activity import _Activity from MixLike import MixLike from MixPlay import MixPlay from MixFavourite import MixFavourite diff --git a/spa/models/managers/QueuedActivityModelManager.py b/spa/models/managers/QueuedActivityModelManager.py new file mode 100644 index 0000000..816d912 --- /dev/null +++ b/spa/models/managers/QueuedActivityModelManager.py @@ -0,0 +1,16 @@ +from django.db import models + + +class QueuedActivityModelManager(models.Manager): + def contribute_to_class(self, model, name): + super(QueuedActivityModelManager, self).contribute_to_class(model, name) + + self._bind_flush_signal(model) + + def _bind_flush_signal(self, model): + models.signals.post_save.connect(send_activity_to_queue, model) + + +def send_activity_to_queue(sender, **kwargs): + instance = kwargs.pop('instance', False) + print instance \ No newline at end of file diff --git a/spa/realtime/__init__.py b/spa/models/managers/__init__.py similarity index 100% rename from spa/realtime/__init__.py rename to spa/models/managers/__init__.py diff --git a/spa/signals.py b/spa/signals.py index f7e67bc..24669d0 100644 --- a/spa/signals.py +++ b/spa/signals.py @@ -1,9 +1,18 @@ +from celery.task import task from django.core.exceptions import ObjectDoesNotExist +from django.db.models.signals import post_save from django.dispatch import Signal +from kombu import Connection +from kombu.entity import Exchange + +from dss import localsettings +from spa.models import _Activity from spa.models.Mix import Mix +import pika waveform_generated = Signal() + def waveform_generated_callback(sender, **kwargs): print "Updating model with waveform" try: @@ -19,3 +28,41 @@ def waveform_generated_callback(sender, **kwargs): waveform_generated.connect(waveform_generated_callback) + +@task +def async_send_activity_to_message_queue(instance): + # do something with the instance. + pass + + +def send_activity_to_message_queue(sender, *args, **kwargs): + try: + + connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) + channel = connection.channel() + channel.queue_bind(queue='activity', exchange='amq.topic') + channel.basic_publish(exchange='amq.topic', + routing_key='hello', + body='Hello World!') + connection.close() + + """ + activity_exchange = Exchange('activity', 'direct', durable=True) + broker = "amqp://%s:%s@%s:%s//" % (localsettings.BROKER_USER, + localsettings.BROKER_PASSWORD, + localsettings.BROKER_HOST, + localsettings.BROKER_PORT) + if issubclass(sender, _Activity): + with Connection(broker) as conn: + with conn.Producer(serializer='json') as producer: + producer.publish( + {'name': 'Hello', 'size': 1301013}, + exchange=activity_exchange, routing_key='video' + ) + print "Message sent successfully" + """ + except Exception, ex: + print "Error reporting activity to message queue: %s" % ex.message + + +post_save.connect(send_activity_to_message_queue, sender=None) diff --git a/spa/views.py b/spa/views.py index 439a94e..7ea1f87 100644 --- a/spa/views.py +++ b/spa/views.py @@ -1,16 +1,20 @@ +import logging + from django.shortcuts import render_to_response, redirect from django.template.context import RequestContext + from core.utils.string import lreplace, rreplace from spa.social import social_redirect -import logging + logger = logging.getLogger('spa') + def _app(request): return social_redirect(request) + def app(request): - logger.debug("App request hit") if 'HTTP_USER_AGENT' in request.META: if request.META['HTTP_USER_AGENT'].startswith('facebookexternalhit'): logger.debug("Redirecting facebook hit") @@ -20,6 +24,7 @@ def app(request): "inc/app.html", context_instance=RequestContext(request)) + def default(request): logger.debug("Default request hit") if 'HTTP_USER_AGENT' in request.META: @@ -30,5 +35,6 @@ def default(request): backbone_url = "http://%s/#%s" % (request.get_host(), rreplace(lreplace(request.path, '/', ''), '/', '')) return redirect(backbone_url) + def upload(request): return render_to_response("inc/upload.html", context_instance=RequestContext(request)) diff --git a/static/bin/sm/soundmanager2.swf b/static/bin/sm/soundmanager2.swf index 8334e7f5ac462a4608ab3abfe92603696a93056b..b62fa6e4d7bb99d8fe678e9d1f7eb09dd27874cb 100644 GIT binary patch literal 2934 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 diff --git a/static/bin/sm/soundmanager2_debug.swf b/static/bin/sm/soundmanager2_debug.swf index 4e30adbc85d0393b12062fdfb196de5814aefeee..3539251c4e67d2251d895d2ac41f93e38eb5d058 100644 GIT binary patch literal 3310 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 diff --git a/static/bin/sm/soundmanager2_flash9.swf b/static/bin/sm/soundmanager2_flash9.swf index 34d4da214509acaddb022213e15c525b54130e23..707a558f06784b2e10615696a4c40bf5bcf4f318 100644 GIT binary patch literal 8696 zcmV+ssHd||A6^}2QIx_j1iuUWGSF;*3i z=1TgJRk`AYof{;9UZa>Oq{mC?d@e$LJ)SR@uIlV`s3sFNqT}U4Mv_b>x{ZvHHFBk5 z_v)_INGO?DZ{`bGy|h6eAJ3!{I+5!>vZ|QMCk`FfCyZ5QMlYtW?5-oyno_!yF*a;U z=Ho`BKVuw;ToTz-UoWw36hcnc8QstzrcSH768UWRcp;xGCy*x-Ny){HONhjHIi5)u zQ$}G!Id>?RKWuMNA0?bb!O%S$z5 z&+4@{7c_Wf_Z($ABY1urSa0a(t}EFVJ~K0Oz1M{YtRg7t!`CzU_xAZO{_ah9;1%ys zzMM<$&~vz7Va>>`h}e$Ysi!b3))Tu7IW_7w{Gf?VU@ z7OQt$>0C)EW6^vTr-7YDX{e-^%0-D8+=P~xsIP3Yxk;vr;~D*^Iy8>E7-GUG6j4{f zeQUbbU9NYLN_$rKtoAzNBYLrEInwU#r^S(VD;DaRO#bl5kz_urr*k8YvQczr1XhOP zdeImh+LF(e3i(V1)lh8U)Njw)!m4tn=-yN)=tpfdd!p#GnJt&nnWDEhouKp73rF3h zbk-=i_fQ!aN9wq9Urvu_jHEwl#LLxAvs~WWFrsGideTTXp>hkT40{`GT*o8bo-UR= zS)*7){)$@3I8y3Q8=0inW`X+Jp6Z~S9x5Hp7+yIhZ(4IQogC70$$0+A4x5ZGp_j)} zrGCAnXS{V@{3Au9w5eRm@4^%C9;O43<1Hgd%P8dZ%(fiXrk*hN7{yZ42p$%3FOixP zDI;-cJBqQZkRL1HMqxQ3?Vvi;B!{X!Up`0p(gsw!?at@6^{x#Uj4_njD8zDG^4al> zQ8I$b{4CRxyza^u)1-R$2&qqulyg-3N91)ivRcR=l|A=Jv6LTIvD6DCb!1#G z7Y!jP={Yae`|_D`*6`WH<@q&@j2WdJMmAqKy0>UJ2cI>PY27VJ@?zFDjV&oXmoqZ{ zp@xnZJ?3uX&1GakvsdPfl6UX!?ap9Wt|Y;Y0$C*LIXraMke?hVdCgutFm3bEk|8a! zxp7#IsK%SA?XxR6bvS}KH z{&FVc&gApsMK9{8v`^2VZUk~dsFF$BMM-7xM1toMP3TOv*bE{EJXh4DcfoVd@?t3< zb-1UX=ZYk&A4%YJQBHf~a!>uUXg`V`%2jc;N=XaB ztWnZQJf|N>=+dQEr_o|&=^6XBp54;$w2^$y)}luCDw*{)Ts^I3h^lRx0Sc-|Yw~#V zxy}1~^Etzx&k?@Ee=_fQVt+DUcdou-BntUrah2_SBZlqlltMmV@=A|a*p@T% zUg_uXk{5~|$FZh;j_vO-a^+w{dmC=n)EHYL5D^YtU!siHJ4-0VWln}r&kiU|tm)~w ztUF##XD}uxde5lARC}~_z9P&zcFZJf$vu#J; z?hsDOE_rSvhkBC-0fs1M*U&~jrzS?{&kB3%?XcHAd$8B8?Vv!qKwTPzrL&PFmpWdD z3ByKg`!ht&YYhGCC9^cIm(cPH3Rj7u^6EOvzZ#b#_pQ zT_e!aNgWE}XF^@%Mu+NjeCc9;x=<{U<{+u!RX}uK9Q|2Q`n#l8w)f;QEU6hIH&#mV z8#+Us!(AhXQ+N-_V$dVIC6<#4rH>ee1$x1D_Qh>EJ(0l3lEyRg+ZTPiq@z$|_KZ96 z!b>FcGFTu_wi80a$_~Aha+~Oh3Z9H%mdI~vg)~M=YR#*8m@c|>T|*d2Jf*yyS_N&2 znCa;T9d?*nk#eqPG3z60PG(&i@@e4hHzMaSS@LVs??c$kTys)b&-x!=kafeY# z<&(agakv&DuszFlVc&LLTDrK)W>Zb+#hu1szg^iU=SRGnzt@u0mX9Pe(2t{Umr;yx zwxeK8)y{4b&ua%Pns8#59CoFXYc*SLY`HKom}h&dS+~n?W7rNgFcjOnvv*`mY{#zc zeS7+pqG23TDCR>^#O>_YQ=Rl|i;eW{-W}U5;`X^}@u~+_bCP9yfFumXx6Fn2irXCCuiq<7vMuiYXkpJTFL^6HlU zkgt#Mh&N!%MS-5I*-KK`Dpv5BIqs=u08P~fCbi>5g>ai41=+fzkzn#@PS2(jI~;03 zj7Q^T%uvUXUZI@TkpE;qx+5fx0x9H}0>xQ5%)&V`SM%afecTq}!a0a!tk}nQF`m!1 z92#9ZIsYsLVph^pAGAGUS6_C#bacU4!<4RhP)2FsXRqqdP+Z+KbYSNe`+BvtK#SVa zyeQBTX^FO6v&hqOt(z@`mOG*4!{B)cS{?y6zF1oWt;J*^++ zia+FoK(i8_H-ACPLI9r^_#$5*=vmyl@EI-u|G5Mx0^EWN0UiOG;9kLf0{jA+1Ox;R z3LX-!uz-0276@1)w}2rb_6XQ3-1`LV7jT_`0|KrWaD#vw z1q=(gNx+DJQ31MuxPXL!q`(XVOaWs8QUcNf4hlFVAR{0vASWO%U|eW#7ElmcQ9wzE zvVaKzhXouFa8$rs1iV$i+XTE_z&ixIQ@}A0-kU+dB*HBSw;~)zco)LE5#EFFUWE4{ z+=g&F!ut_E0K#{HfDeN3--X?~5k7=)0^wc|P4^*u1lu1)co0P3B-Rgu2%f_FQG}0y z;E!SbIKmSMPa-^pB%elj2HLRqDO~j#tUrq*pGSBe;S1RRB4}R%(7ufD5<(KRVbBhN z_A-DFUqghyK=?Ysmk_>;@D0#jLBy})JiLVPEreGA^ZWm z{|(yppxpr4ji4O{?I>t(0WFJ@e?<5bBHSc=Gguwt!gn*mB*HBSw;~h-{FaWHYh$3L zKpRCN--Va#-3agDTAYrYYsXOwx6;nR2ju>EPS-GvM9CUP%wJPE8{;+luAlON7NmK=an$z52wxWYUDE^xURCj>x8 z!(5;B%6v;RMDK(8WjO5ni}Vt9QL?Bs40xE3So0TG-KHUVcf&(ormqkFdxe{Sb!yK zVQe8=#Moli%2=DX1L>DkmH!!USn0GZW-x^^4wZNJ#0T#RzSm-if&6fk4cLlKd>wqm- z53J=)z!qK!Y|&M~7HcD-vUhB$b=fzewbb{yDn zv?CS;97QAd2A@HU{VQMVF(7iRE$gx@bAI#=IGI{t?PIAHYk2YCVwPG&oeQktj=>I= zy2#qbEHgZ@GK?2?g=Nm02;*suz6-D!dp7`*XpY{4B$~1H9x&ev=KCPE%z)wBVDL6z z$8LixVDEN_-j8cSC!-I*NnCSs@OFS>w?md2kl~&B`w=Mv<_D{V0Ei+neUuK!Bs_j9`+*ECEw#;?a_7=-rUv00o%$3v*;RUvOrh2Yt zD^IWNxi||;JSg&TTl@TWHrU4L7*I~v=sjS52sT3O1dv8tu`(OLaQZ9$8-6c*7+m)O z!(4!U1Q@>^*sXX&+t9so&1;`I`Y_GA(CV?wMN{Vea7;ZjO$Rnzi5;QCcY{mwHqrEw zW^_!QTRZS}sfywaz5rwqr=>+a0L04_ofjT(^m#x^$FtlrJ5Q_(d-3?`Y@#o~(~aFv zV>gU;XmzAI>A*VXU(6T^_y7z(fX7cXQ5|GxFTzQZtpB5c78Qy;2(D0Ao+(X!PEK+h z<)I~{u?lJIjMUiZ@@ACfrsW-}<(*rXcw8M@;hH-!^^uBs2o>XECs8k)J&bC>O$7(d zD^S|b)Djfl$(`ooQzY1;HITo=~UEM*v4F<|!zishE#KF`-nMD<<5Qxgh!#I9V|thm+B-!pVe+?8nvVxDt0G>&i6V6V%0uxPlEI zHl{1)6JS0`Izlf^ooW3^n7t?zBzaNVgm4T*48Vf>FpnbvndVi!!S{sem=X$|)A4MJ z0n4)sWpj}%7t69$mTk@vR_JO?(}}jTtRhRdELB+wS$e3%r;=TH$qGc)M^#_eFUd6- z(3uTT5u_r7w(%77KMiam+iXBbHcX@QsF+X3e_~~`$2JWxkta9V@5LFl zhW8v?^mFk@k#vCl{ow#vtZa{(p8$JYw6jmF42NuvMQsufGR$noMrlI-1dtX`0U6an zdJF=MD60Ng4MlNKPR&M9^iwqyw}bNJY!o+|O%=uCpnMYMHKKU*Pu5VtT-rg`)X})w z&Yr8?Sz^Nd^vba2blVwWIz2b_!Wo-vhrSd|64)oyQev>Tbu>-J!LP2sXp2%?5^iBG|E;VxP>`XV$8p6dS$K$-4n z!yr}*A9=V+FBZN`I!dqH@Uzk+kuj`J$qVUBd~WuHHzbX<@zRD=dqmQ8g%?PDQd{+F zjzFqo(+y@^J8?AhXX=&$=AQpY3t#xg7TzI!$^3BpEDF+Z&b0?}progX1_@#l;eNSN zb9Vat?2Dr5pO-tKSIc-ElrPLi@#ybfl8@%bGr7L8bHj=7I-Av4k%hXdmkO$v z%3gsl21XJP^E?CnUj&AM123GMzV`pJOQ~TO{(sqJyQADM!Mynm%Ebx&OH#c-+1u%$ zeR(e0PW{Ug4TDZ*!Ne?1!##vK$NyLqJ{%*7PEplzl01*?%dU@BAUZ8g|4ojU!BYr# zSBdscHbkgHlaqD|Kv_vc+ck-26@;_*{(&93up1=TWsBL)E;`2hUjiOI4gFsMI3B|6 zD{@?hZHc+KifQA)T)f2+FI1zr^PCi09n31lo#&v~R=-5#4gzG6(eKib7JZc}?_NGB zkteZ(d}bC)x`g(ZG~XKiE2`RRXsBVedJDqystSC*8c@GVF|&Wxxjqm2SK%xTzTR+p z4%*p4WWe=1{#K;lI~^zn@ya_5aa-a}%}NUdDV-WnaU55Z_;a0rFA)b$rZv z**EYx>t(OtgVxKwiCLnTeG4D8UiNLwu@v?leAp`NyZE#f>{Wc+_Ob8b^Om#k0}HsA zh0k0Uo5F{#i&gNc>tfTu!Y=j$eDb>3YxwAOvD5hMb+I$}@a60;@#(9uzrx2aXRqV) zm$Sdd2QX(p#3wMvjW8XLT0QOTHOp+l$WS~TLd)0i3AG3ZD1*m;v2J)7rYZ}5HZy}+ ztj~qX{&`kUJ?c)$EEHpIJCmBhr?iT6v-sMuvsxlYsj5w@V*Uu4@fBU^(0>edDz#je za$w4UDgB+Sr@y3iWiC2x3eKiY3Z~chIq7xe*upai2?djDx5LIhhJ#edv|Fv1KY_`F z2;nPTi;K8=K4QvL7$1GpG#Pgj!`NFR)aKV`W<0{9&Sl`&a5An;%Qr+Vdsdy4LamIt z&A&nXwXwfN4q@Jrx5-30pm47*HTp7yuVHMs8yg)Rv2GXD`VF$&gWHVCT}FS3oBR&Q zdq4=CInsa4ArFY!DHn9=*M}C!EamJ)1JJzYGP!LKEzo~${gtIsUM@3qJRWK1^j@>y z!F3<((F4zZ3N|Z3Yx*@byamx^ z%N!aNJ4*Dau3%Wl`cU{1*&jp5=$Q&7ZkQ%kWU^sjyK?z7Ayi_2kFR|^rfvw`BiHmg zw0dLz0Fq`kL6W8;^GMC!tR3`E<8BoPshV0rT#1$6=m70)tf|-~;LJk9EIqPl3)*_3 zk%s|(Cp-zy%4gHd@Ctm#en5pe_j)~}KZB{*JLoYyFX;6KKcdJ7mB%>}kNxuTp7nN$ zE0j;h-IPhjRZ1G;A}gZ*Ly=^@o6e_`5M~`E<>wyf)zV36TE=7Q9rG8143(7Hi9x~a z?PLPtF?Z{agVS+W^Hi8bt<^AM`ajk?yY!#eJJ;&}RPP+pe^l>e^nb2*a{9m2I|pRS z=5+GuWADo}ajGQQoak%WGe^f0rK`enoMG{Rf5>7yC~P zD+>EHh7}k44TcpL`x%B6mHigOii`aY!-`<@gQ^y|#npHx3zk*j$(ANcd3o0^CbxZfX^hC9F=ma$?vH!vlR=ZMl zD(DD0XnK;?j}cbIG#Ze31F~biE9pxK*=-!_5xU@5la*3U21+&ACe>t?RFg$gO~yzy z*&)?8>VJ^+u>Rk&CX=)(wjIV5w8CjDiL^;{O(JR%MU%*xw6{qFO`>N00XnfHLbkCv zO7GDB2L@ahZ0x1uG~Na8lkVXpJP)6-9mRrRNb}x-o^x2WrYiFLOkBkfrNzB*U)&#W ziU$VOz%exubSP4~Nb#D26%ECM`u)gnP>;leQ~K_Bu%ZvegLpzzER6@_0X-iNMqkFq zS~Q993N;SKJ@p%pnHUbeO2yZ)*emo=^jIw}Rcrb&{8{s9XJ?#TBB9V1G!1*xh&weu zAeo%Tfc-}_A#}+vyHK_TKb)DFYdD9(y^ayQk)@e>co}U&9MnW#yU2G$N_3fk*95ur}1o1zl$)1X*!1b?M$e%q9*3I9a|}C zb?V2s44bo@GX>CQC!kKtfQl(W+&x{1EB$5HL_&RoPkVEsT5UY8Zsq;E_etA4n3F;; zR@|EZ1(@|!*O734^9?9OhrS<$4X=?B(i>qK`KW#0LWZh>`)TS%`9-)hb_7DLwj$;^ zD|*crKw?X!kWNW4MA}i_&76hssW&|>KORiWC|<$X-6#wSsW`$Y18_fHtViv$Yvq`m zwAQ4cx3SYiQ{xno+x`s3EfV8A0Iyda?uqp<>@86gum2DQ@H0L2h;7N=3(m95*2vS< zpDWIr2zMf};WqO4@`HP-6%m}T?dMTEz;3L}LW^n7*4pnJ=ba!kp}FIjSTKGoXY^~} zan87pyUquY-_u9m#m#r~{`YYDwQ4B`@GM8~@m@YEdPd*Jdq!_VxEi8op-m8kQQQA7!>XogLKKY1xkCm8v(n zi?=7EcXM(n?a<&z_D7-zBGGR_#C9qE)TlMQd2lmJCFr-Esniy$lG<%er-snerec_T zrFL0yHFd2uJTN^t0I7bfGqnd{DZ*ZaeF)cC5o9fr%35)eI%LJQRL+WfQwOZLKNYv) zO{w9yhcs!$J*kWp52W%ITGO?p(OgZ(!xPRA2RB(VrlgYAusLY5lwp~MrGEgA#u#lf zKZy0XeNwpynk>>V;#%wu4k3H_Uew?PZbkS%s#Mc#vfB6*9z6FdIOn1?9+2UD8<3-CqNn(D zt4a@#5N3hVN1YyomSgW@PLGoZi$3P`T;$*AD`>kyUnJTUkE?BBW=0A8Y32uin(@xe zY@C_F{s1hz3rA#q7rETdycS3`@NOcSC1zvl%9j7M& zmTt$mwwO!8G5GOy+=W`yb(~;oCc@M1GI?q5K}RypiONjylPmlH`s# zBzF?Y9eF#3k&AvkW$ z+)sYVvV*sUZz}04bseeg4|Ov+)au|5#U4fP)~VlALkP%iZ>rD66-xeOKSw)H*t$Vbf7SU|2tdsgJcztNmF^84<6*l4!%aRho!u>p2w#2Cv3KBnx_$@(gUbPJ1beu(ZsK^ zdO~>KT4*&D=-H;wOP`K@hF2UfUG=>neJ^-;+v_tk@Y>AG>(Z##5La!D-z_cYr^4E2 z%eBC(TVCSEEuX+J-g$b;4hYfD@~2le)9)$OfzQnyc$7aKzLZpI_x0?#!qAi*gQn^M zXrM~tdoX_^so^>_ub?z9`c20U@wpS>2+eK5>=Q{}H-~ifGob;jO6~J=S^UD>fiEJ@ zm(YI*k)z)r0<&i(YuUw36Z9^(>@*(t-cQCdXa6tplbxi=bMA%QOq{NeIXubdttN7# z75zy*hs^6#6Ux~i-5V*(U$89ucP;z(66$;z#fcH+0~7Xd09Nf8f@2qbcHzU%Qmz;3 zlsayXNHf3AR_Qs^*}_y5Ag<;(W`Woln)Tt6z0>byanBbw7VT%Jd&I7J87e1;BbD3mIcK&G`l} zc4Z-Duie$t*LpOY$raZkc2!5ZR2p5|)pg{^k~iJ;avWR8lu)pG|7Txmh#gnDsA*WW9Ej-=CHM{cZYme#ifj9$y(Q6&b6+( zB-XmBd*v!62DM(k0oHBzMqNHcs7b zf#uLy z!ZA;2Bx@BsyQvI~B6l3QH)kd?Rw|gX66FdKk==XhTD+OOnX*z1sN(`ELk(k$nrPB( zBgK+0YZZ$qU(qO8M@xMpRwm_FA`ouut~AQm1Epgb%P-sHQj4TUQUhi#mB=66uGj>U zW_dVW>N87b#$S^qc(7=dHk3>GooE675i)>mZ#sy)tU}JrY|Y`*Hj~zFt5|9{h{hu6 zB~c`qwvvap;WTy@^1}rjC@Nc|A5@weWK#tT*bkKg|QBtUL3?5mLS9AgNCrEa&JMJSf+zB}YafQPe{In8Z8>i>3Ui7fZ8H z@*W&D%SB5_PG-(e&%OCfIco(Jb7{YZgTq#7yOqrsj_oO0uHmy*YQ*$Nmb{o%uCXa? z=5kghI8cZ9F=XztUR_2J4AnDdmHc~lZF3u=vL{X4Dv(E_o}&Y^nt~KTDQxzj!HkW^ zN|yANve2)U@#R?26~*H}rF3o=fJajq#OAV$(QjU&Uke8H;XKGXFnS)r*#B(HdG zW7)Q?LSH$P@nrJ((V`!9RN8B1P&Wc4AyO%%id0frJelOVWCI41O-ewNfai*aj4o*R zEH9QqQir<>X0Awc4I&GCU6il=2{|UM(FPi=8kLNqRlu;ar;uq>UYf^^=vW_4J)Eo1 zY>_i9G-j=mNz-%jP|}nkz4978W}2Q6S9pR5_bH zwqwS$J-BGClIT=n(cMLg$8e!$eU-%-kO8aUn1v|Zv&zJl% z;uW^$?7UybIb7t0qR$PiBLUa^ZF_6gw%0bju}3}Cra-ztU0Q`D z(}|>%CN76DOA)rb0+U7c8Nga8EWI~N==lX5J=F>n)sC_I*r*lE|s8rLCt3`S&+r1Iuf_)To%iQPQcBZ}LtQaYb2ljR$-o5 zP@6z;YtBq2amN`!+XYns*e3bwv}5~5-F?JQL*?Zrg0iaMgahi^%~IN9V}vUBGL~JU zcxn_za0jK@oNDChq{Y}dfIEz@lvgQNqvD7eplOj4M5)$V&Q(2WZL2pY( zcJjU5^TV2kiNPEdt){Imf$yk`51*J> zj23k~2#f|*KNV&}1MxjOdJb-iZ{NACcXzK|w5-EAWdi;j#;v$*qo4Y4esY5g$q2T+ zj4@&$oi9OABvjh$tMvD6jUVjYwJW|$B$VNeL?v{4b8@b#fm9PtY?{8A1aM#5WvL9s zlg#9c801H#eMjJsAfYzkZYcN1KyG`nA|5WgB8ns*=&=bmI|=1v^pQ(&3|Gy7jK+Zy zEg_Y(G|pJv4buWaWLDT{diiMM9g`c9HfrX)$;=3{^zZ21eQ;p+hTVGxgqth)^SSNr z&KRjnl-5db^W!WwseLk7u#y&zxS^aH$u}rVxh!0aQjT)Liq`h{R+WV;)kkp0@MJJ_ zW%Oh|Wkr+;T66hQt4-r9t?wiioLahgTDs8bRyzmEGAb;dwSuX>Baitr@>}%seK$$Y z=XlvCW%bDT%Gb8?R)0v%ixLM~9e$dHQn9a+Of*y~%8Q9C;_61JjanL0$8u(NB)Q#X z)QDT#Xc?2;QDjvpXAKlR)rS$Rq>~kOie;hVv~+0xjOkWV>~O7J$$!BNLULck@r;e8 z*_uOt8%fQbr8`V;nre+Ih<5g7M@z@%&1$C1&xdoA?moL$Uxv2m4Fd;uY*GtuQ4=(I znj#BAO|4C_rfU|6rfWTHJ~Z6{P45HWz0h<&c$kMZhngRS=EtDz(oR< z3%FQ#R|x17-Yx;%0#*uGC1ACHO9Wgh;4%T13%EkS8Ubqsyh^~80=J#*ezg>@az?^Pr!Zw2LxOv z;CcZ!2pAM_qkw|~h6I=b5(1I}QUVheumubYNDCMd7@gp-fQ*2wfSiE5fKg$*T0lV< zMFAxt$^ym&91(C-z%c=@5%5|8e<$E|0$wlRCIQDm_-_UQ;|Om+xCP+^!W$88MR*g! zn-SiE@K%J|5Z;FHb`XK{1-t`9@STXh3*kKoClTHYqT&4rcVhh>gb#oSox^-vHwUWbk$D2hSmV3*iMY z4&meP5gddGgh?IDnFU7vcM0e2WJC5yC$q{1^cT2>dg`zaSvPz`r8= z1mWKheu{uX1pXc2KM?*C;b#axNB9N8FA@F=;a3R124f724lsU0;{6Vc-_uBcK=>oV ze(32qdD6Zm)| z!mS8zLU=R6TM!BYeov<6#xNLZFotlVw_*F+5Z;d6-+^#DHxfA19oY0vMBl}Y6R4S6 zNWynx+k3bOp2YU|auNDA7$GkB`?%2Fk8mf#UHIw)2=^kK;>LYkGalf$zCXwfQ!@s! z_7FE7#@3HuYv4)Vq8TZyd<;2bFbI4C;Ti1uDTGgRG$D5Q4Awu(jk~eaJ;drcj+Vja zS20lVHS)d=WXS;D|it1b3gu6qgTCAudzuo;T$}IE(E!c zy5syA!$`$7&Bc)Nj9&m5CkIER8gDV~n zHX5j-6=AH-g$R~S5XCY4{yA7*2y?M)fq7W6CdTHo1&l3Z&5X4KgNr2DVp*Oi%O$dG zWy}){E@jLc44zMYE?}%J7`%|NcGe*&mdWxWVA^tE`o+LJF<{;mz(gl7Ul%Z=8<>A3 zu)r!{!PUSTE&NmmbD?Ss!DY*%rpOvVO*{VcSU7?Nr-AwYU^=r!23P5DY#R0~A>^j-ydRg8e%RyP*D9eLL!nGl~qBdniLY7I!HnJ48 zT8!Cjn6Y#)IKtQ=c9&1Q!5VTgLvy+}qYrU((a_K>5I+HIFxDQA0k(2o^EW<%6#JIH*lj`U@s_OS zIQHDw?QkkR&)Lh;P0rxL{)H^PfROW@!S?=kmcG#0${ag7wmj-#>>|gWGZsZ_4ZRVt z8ow0)Swv#*MivpQy$S3$gZ&mrFSTIstS5@l0j(ugN-sjj?Rq9te_GOj&X2)Jvsc&)Yt1I=bj=jE8ztpi~mHK6ly`oa@ zckB(7`bNiIQ>kxq?6sBpYR6tq^)N1Ar+cFNI=1}m^6rbXu-J!F9&Blw+s67^IGF+G zsSUjw?DxQWh@S+~h!!ui&A7e(ivNzk7v2Zj`+;H3!0yD5c^j}>aD}!o4Y=V~HrKgs z_~$#_j=f;Qz6*|fUOGbtJ2M$SO2+qqX80TE_2LMIz>Y2LxVpT$?r(e=$Ro~5kGLC1 zmI<;K8aVb8Ag2>q?${kCmq-0*ezHyMX*gYvehkql`k~XF?jVD;&%Ky2oZ#Kie>a++ zc%nMU(LN5RXl8x)0D4q7{sGX!QE5|p`K)}&v6Y7xlg1`VV=qaK4K0h{Ty9*}o?h0m zWwB3d-vZa%fhm$y%)O`>jh#ZhaCRT61qT%z48OqHcBB{M7i$ zsms!XFHU5=?)0TE-VchBQQk;Z)X(GsXrl=>h>6Wjr`-dTO}Lyo#5O)rhKUvin0|KTN8=khCjtdSyNg z=U}J&u1<@nxXrNqm+%{@H}6MKZ#p}Tdh@bJP;Y+rD29ALdkllVpFNIYpEJYn^*6pL zN}5aR-BLqM7A(uom(>NbTqw(CS+=<9nl`ZPlEF?ckNA|vz)sX7d&laKJtw2M&u*@_ z4cNPsX&NMQIJ$&0SsRWhQia$bMZ5c|*i%(6Ana+71|RfG{J{9~h%Vh=yw8tsyj8l7 z!G%8+_ZLYAi0_Mr$egl1WPcn~yJ%xiERTkj#G?8VjUQ!7upxS3ejG>(b6o2a(Ss1G zC-IsOR!MZ1fYw)m-S8Ud!d{x%#{b9N{JOk%& zhi5^#d?pzEgzE=E`;+xCq+JVOl!2R5g+sK zzpuhC9=%M)Xullrv(hC|Fnl~97o_{*x#=(bVd<>(i#F_4Et0PmohS84b#KscC**Z~ zy3UQO7Dq>aq~B!D=J;kgaWFP9Ry@DLZNVl+xAX%`2WMgMg*<%zY zGnBy1Q!j$!W7QoCdyJ1ohd_*|r~Pe#`$QR77x?yM{-s4Obg1NSXP zGa%u42Kt@{h8qViIQjb8zh#tC-6;HT8D*QR+%LeKxpm6L7v>kFdK)FS!zKITOtKy3 z7bO{PI+=N6(?HwRIudNTEwjvyEMNocDbRcS>d?j92{F}i-^KOh&(bjK}|+%k{vo!d_I_tS)vp12= z+8^}iJzw@v`gD8ny}`SJRQrAKFTtA|sMdnX6nNNIF{Q$z-`7Ci2RtH^sz+r~g{hU- z&%TZcs-JxW&(nVP0-mUS?3;L|_OWl_soKl_9?#XilzugE<^T(6YywZ%8k@v3w#Lrj zDO+RT1{T%Wi+I}B*jYSpYwRUFack@!@XXEGcktBhW8cMdH)r3&lQ(DI$FnzQ|A?n= z&ip!_1Y%Bi8+*~Qn{a0+o(-et8+dwKfDLqbz`uAGJP#9-^L{clg$Z;(!*j+Wr@OZ6 zPRMK)_uMunHG`*kFY?XeK}V*|XNlb;5-DDj_75O}2l&Z$^M_F5GFi!qCoyJEVp=_k z>9p(blNjkq>-tP`8Wh|?8+4DqaS~=^_N~X~Q|d_%UFMOVm&@w+GDRkzn25Y2v+5tg zcv26?P$3p1^fTwl&TdkThtg^`{v)b-Xm;4TO4lOaoSO3KK5bfJqH_M<%DPPN<(cPY z@^Ydb((Ql3zN_Ou#;HO3qwu86(>?Wh`ah#j&1e6DE;XP1E4mbCAzcfEa&)90It@`& z@n9EL+S}t@8a>VHWw{&08j?~C{RAcY6HsUZ+Rmq+OOd!kcIhy$3(u2D(CluTVcunH zNi=jz%^$qBrhO0TRcacoFO^LvQFX$vg-~wyj71lyQ%r}sTeaZq{|(lM==8gp@t@$F zxtz0yh3V+34!IFs_#@wu2f3uDd)8Sap_9F*4Nb=LxJf*kYlspkRij~LdV$E{=oYtm zSe6+xqfU2}OR64Rra&qfl*@8TikioN3gAfp=z{PkT|PaO@Tyw;-@zTSlEhU`i!$8} zR0L`R^Hboa7QEV_k_yrrJzmz_MAjn{S+8q1Z)JQ(?wOZBjSA|h+yka-1`nBGnv|RQ z_u$WPT;4a_$?xY6%9=+R<3G?CKK7p!)Y#9^0X6n>bU+V_a_;y0hJFqc@z>K$!<todyz7ME2uzO6>K)tI&#%~s>sN?uzHWXmCR zS^aJ00>E$o2I6Z%Gc_iMMfXs;ipbnQl?%?+{-_xa&YZ>1KxOK!$t%dxL(fPBp)BvOmaMoIgq@`)}!F ze?lkovH!u1Q)7R|jZ?av&%^$L8>hzpiW{ew&27~EbMDnEacEWmQWi%?ti+<)sh-;d zC$ie$6jYTl1ze#@7gLoByx9S}!`!E0m%EC1b*=OIbe-EvPSzoZPf}f~=s0Ip-Y}gv zhNNznYTRWxO!Ts5P3y_)dscj3cYT9bd|x34mCq~0^?8N3KCckh=N01myh2=`SBUHL z3UPg2Avc&e^C~iEj@J-c4UQ7bT?M*Y1@i7ntpZ)G0$r^FU9AFLtpZ)G0$r^F-CYIt z&AdZC)kta;)Lfw5d;=zLYxmzku68Rt4bRA}brOC7zm_#!x!=#_hJ#M1adIu)%jPwP z4gc+!U<`VkiODkwJ>f}s6Cz*;2GS)C4724Z9Y>_^?_M&t~r1@o+1I1e{TPt-nV!NuyXnshwx z%TrV5bpONAT{Z7L*ZQ%|=rZ=ozFoH}!tE}t8C~=;>u1_3keP_9jaJgXsvf!vF50Z! z4IhMuq}88?v+!M6`y=jpxA0k>aDvmd=o>j@@bl?{eXrAvykDB6U3=&Wh~J75Tuth# zUb;&)pONQq`d)Iz9v&lNe8%5|#38Eo(9z@8Bc^{K>LIYs$}l+)iPJ^Q6;Io`CHOFyh6cAC8}a+7k> zb{Uj4^uQj~U=O=jIhvYs^$J$aU2_c+b!l#JqqEi#KMJnTX=t%U(|GjQpM*+(X~ysY zw^w!eP-Xb|ZODGH!W0YJ?Kz}k8OOA)s!&>d-Djk>byuJIW{gw6hd-&$9ZH2iqcbL{ zP4nQ<4in_&>Zc#N|8c96@waix$y#24;_Z@R5rE(C9qf*GGsG6_x<7b$rUj&o=|zs+ z+dlBA;(1?Hg z*<$%i2XPjy03NS8I4oV*=oQbRPt|?!9PI7yW$7Mg@S6T>Sh}CSd2Vx&?S$-bR8)SU z5}NPkZK>EjoZ@pE)J5fet+4~Gv2Q`EiqFCHkTbZkeC@>%dXqDm-sPN04>$=u z9d{C*^iC(?O<(H_Za&k$8Pa`DM|wBH5`;YndlB|KtteV+I_o4v`mmEQ(m5yLPakj+ z!F0k&G^7U;KGLL<@TD_OB9zWM=yTVSMsrmi501Itgb}}sLs)g+gBm>Fql@4@^*NSfCvefQ@O_wxIfH5J)Sm`( z*s<|1Z|3C_4^qzHq5eb69C7TFW53$Go6AbUyoXDQloVsQJ^ld>PW)!T@ytE-lSqt3 zo86Cuo7BPDp$nT2arYJ=ym7|vf(-8E)q|^JpW>%t4ar^#i?E(7UsMGGU zo@UW*?ya5QRtJRd|ci6zueuClceJtiX|7=qHMhxY#(qpT+w=#DXT#^obaUIF9~=7~;jHfa z5~)PqIeuT>IWDVbxxKx{a))HOeFn=N#B%#9v%E<6c*V!j$}1Lc>DE!V&+!nm5N zou;JmFV=Buc-^#};c#??)CQ{9Y@f4mni}jITvgpjnvfD+<*IIwk~zRV(d=^ux1t7c zC+XkH%`LcX_c`{K_~V?v{6A~BI-QYm=MOSFigE50-4u7!!kI8{AUC0>qcS{FemFpK zRi(k1tkAGug!&Clw51*}pO8Ai7o9U+JXv|sMK9K2PI8Dm|4Nexjs zb*1~^3G<^|TE1!xYC$gDfSOgA%1VxIf0ff6MjtT3E2+R}H-VA+Z0vJ<(v94ecnmTg zgO9g-cWMe=oSOQsbo5muRZIPSz2kl&uU^-$23{HR5)Tgf5N_=qXD8Gq5&Jwpy*xtS z5i1SP&un;%pN?KiDpk0dJ=fMWq4uST+NQL*!s86gT~BJ*k1p3JU5>tGs%<}aGTKV- zHep7JtoP4gUAe)wfK|ACVWx;*oZ0Xtl=%|+w?{ep_7aQz_Is{ zv&C&?Y2;&WCKyP-+*DL#YE59vuHvp+V~bCzFj9rZm|eJ3R3 zD>$7vaXv7nzI{2>vkkUg_{{wK9;N&*+#z)wX_aoiU#avQ>TF`HHtyW|a96c6I?SaM z2v*W+7#<4QxQE*}sq}H!%_fgS1*eNa$9}!K)@PSd$DPwVPR-~z4S&NdM)GwnYgG~G t@|rVWfrkXoLR^p^s~!?I;@^ItQ-OyrPUg_Rw4MF`44@~n{{>fr&Ku&igRTGo diff --git a/static/bin/sm/soundmanager2_flash9_debug.swf b/static/bin/sm/soundmanager2_flash9_debug.swf index ff5d695076ff5b29b8cf20dfdb90453c5726fb79..370ecba6f863a372088acc4affccf1d7e3b5f138 100644 GIT binary patch literal 17093 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 A3jhEB literal 17215 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 SqaNmeKn9MA^#1{xs#k*(3V~q& diff --git a/static/bin/sm/soundmanager2_flash_xdomain.zip b/static/bin/sm/soundmanager2_flash_xdomain.zip index 6d46706fdd2ccb3fa24bea919b19652b7bf0fdac..8851db4dcfac62ea890168b9d416bb677ce2f371 100644 GIT binary patch literal 32825 zcmbT7Q;cXqyQbUTZQHhOyL-27+qP}nwr$(CZDaO-COIc_dFJ9Z@+B(}9S?k;An;JVX>Y7;TJDTab8QEIv zo7>R+Ki_B_T}=Spp+la8RR2OmVFCcSZ8WJ*J8q7k_<{f;HqdOwC)P=rq3Iv4NzzQD zERv=?n~x`8ND&iFxMUCM^E*fof&roe7+>zBpD30r2AX)CNz-+^lw|)vb~|}oG%ucW z_=;@5?f~JFk1NnV3#@IwzIgxaY-)dS^eF?p0rwRnS5eU2?+SyVc%)hN4|N>Y#7iG; zzhtw~>9zj`)6%YfZrMcKYh%GI+ z-=@L09DdZ(WDl$l!_Xr(CxH?@GIiVow~0;hI)nS7eKK>+3}~IvxNMVhi!o1?_giJn zG*Ep5d|No#{_X+L;D3d|cu0Tc>bE{j)Tmbjk$c+W_q#60@5HSTjE4SWYo1>}^fQgs zOiv+7J_nz3>hU;If`txBuEjL;$SbPY6cvE1La#MTPE3LtLF~}H+yEpTXpW^&5Z!a< zks^nF|3@q@s*eS8;LMHmW8uJ>g&+!a@yw&3TkQ-?z}Ls+WxdgKI48XBEIh>+HPgm+ z1@Gyz25qWk>jZ!ZIjzV-g}o8GyvOZghh2r5MPc6?9ww{Go^hl_qVhgge< zm*}ojP&d6LEr#{elzn!(XJ@CfQ`cYSjTD+We8auSg8?hUaOxjEOp3pUG(0ZgqO)6U z(wnD#2ukEGIl+Bd<{K)Hw*^{JC263zxm%ZYt{!m!b&=6QM@eo>R;EGyhfPv687@V;ez1)90bnR`sr$f zQprU;n`(oEMLUSIpmv#Q!bU_%Bsmhc!%`eNuM+rZQB?1OR5~MlL;os0N$Q6a+{#eUt+=BczW#c>=b{9-xaJrzq%$P6 z2L|HAi$Cpyr(&rV3314KbMt1G=Lh>(j4=7Z09hWGkN~X`a3%UCWbNEH%@gn-GD7y!kE@KF9-ZYg}? z?vE1W1v5Esk#%b$$x9Fo4f}M}Edn?xD2K4ZjRfe@g5Yz+!Abx| zvhv8MZ+;m^E1wC4a8ObIt`@G7Eh zch;{Hakv@YC{sG*G;s6Eq_0MWikQ@>P2ZfYp8lQ-yz)Bu&O3zLFE`UEJ}r0cjH19G z(vU#@&L_e6_!UK|tXfTmF=DcTPeP;<5`6>ApX>;E8Yweo2{JMZhXRqcSz=XVf-K`m z+fQuNF!SdR}$qUa=N74Cd2^dr}rnTB&q}3dWCtm?n#+hBhLZzvc}}JAx8O zc4LYqG^vG%N+=@s=Qsyn7LO(ABLl9JsZ-T9(tCt+1bh~-~Z7O#S>&)z{4inmDk~nCCt~@_k#;0Y;yruO8#lJx zq=Y>&_DlUvCkNf7L4gRr8OcZ-8;W+8k{2C3#FwSTi*Uy*QZ~_FGEh=xhHP>cAPrWT z2v(jIHO~-*n%A#E$*5)=IC^F^V>&nqU_K^%GR79{@wR-Iitxp!8*Zx`-;eFLnz%C& zSP@6f7tDF1KGrg3Qe!9cYaqsI=`EA|WB!5k5Gw|EI8UTpjol?th~llRQBTds<#vD# zR7Tp_pF!P1XB;iI|MRGpXI=?5@1B`LwwBaIFv;Y5bruPy)r^T3Y~e-v*zSoXN>-y` zLKD?5#b497T5;9vpqcGopiud9I9Y@fAN|NEqx;A4emh|yh~(%+_1;Ad%$)gREZTvX zZVEAYRdh0bmw*8S>S7MrW5op4HpZ3weMl+Wn$JdA3{%On$kdbJ^}+;&QgSBNB)*ac zXN2;Gd49T*p^I5XC{*Tsn&Eh;-GeaS1ILJlCm+aEa7kF%rohlRfIutiU4LkHn}I{~ z#OD(yz&3$6Y9hhfW}+jO>1^)t&AKMNsVd#bMPr}V-VKenM7R4g(oWU$&8Ddmfv0`( z>(K1W;-_;c+A8t7{B4IGO;_%Gzl751b$Rymo&5AK@gy40ce59StI=f;UGUAD6d|SMv*D}&u z27&G)2rt4zIMUk&f$k?r&m_U_G18k&uve?>-Y50Z=M_i~olp;5Zzx>6sx&t!0@2Ky zp&iWNJV8zI(ZcaCHtHzG&Mofip#Y+d*z@b;L%FbpFUP_1po=5v^vk`BC8MB4^Nj~KH9e*cC70Tp5#|3f`nennKniD+^Z@kc5Em4Zi&dTQI zj~9z_m?x~q{NK<0-6AzwjCg2Y?}#s@H34Q!6}u0Et*J|o^43j+Djg@_#VP&p zS16WC9^(}$CR@g|A7K`E?pooKET-N8bQSB?>b_or+W=$%`t1T`P4!hh!2iDd*#oLF zx;tDR6nYCUOxCa-w%TIT9H3L#)*01cys;oze%}#6(;f{w0)2JNzmj4 zalsnz92>Z4(t&o@EZB)8lUZ=2?KW6fS-w(pb~RLg1ddK@PTwX?7eyy^r3D1kRQqX|uP_=l2Fk(_NU3V4SBvDqpJV58&m3AksUN1{R5=tK11st8y+ zAaM0D1{2on_B}@IG7jzH)n?REaP)xEVi5E<&!B3pKa)^<<`Kq-?4mp9HFCmR)V!)F zgBbKNEpyCdVQWDJT)nKUyuG{ESQ(Hu1{$Uf2CZY?yKPpV0~jW)pXk^8B??A_O{0jG zou_2>qpKlHxk7e`Oy8PYhUVL)L>%t!kpGf)h&YL^UO|`|Ol2`3R1~M9K;hPLXYvs`|D4x_Ya2mtRs=-ak0tcFcm}ILCm|;qx zYbbJa@N4P8&i|naB1J_YzY#Tl$9y`R?Mu!qnI0paJ&4#cU=%d15Ai80@!OIUgaOe@ z0Kt9m%P{^tf=EyCZe${wQ$vdWq{`WRsDsrHaMno6D7#6X=6{o_F(-H^Jg<;yp1g3k zB109Rhu`QK;M@xZ6G6#5>W+K)EYy& z{wfV#5cn`~BsXTUJ*3ACbz94`_P=$J9| z-EO%R7&bQ@xG){K7i+|CAbN`pCW9P7&rYx5b$No$?*R(k9JYS%eN8wKV>g?l;xD+9 zay!-|6l87K#TyVQ)%eb+{-|w$#>lNGCaus+%F?D&v9vih?{(FFu)&6-K81bRhs@*1 zZst;@EoQqAU#51NpxX0|NKG|98Gt0QL^Oeg)X`3V#3-Yet`P4r0CLKhdH-yF+NBk~ zNaE?Ov?F?7By&F~qj>KI7=;VIT!NFHedhJ#QozwjTb=UrWf3XY+`Wl2&jk1=>0gjB z@7)?|g!FnIk|~NkKAh$KAVYu1nri~D*xQGl$f23NVsy*Pnh1T2H#kKw z2H=%7rHHjmDgE9s&wxK{0_RzD*|;C4hzba16K{4SCc8wmJ#K>#W`=SB)H*Yw@vSJkq)x)BmF5c!nf1M8xcr^ zLab#ff=rOwjj2;nU$_9(dE=Gho6Idt<`(M|H<+hK#&U7q%CRyfFN=V=2p5#R?8m7P z{=vvhG3z%}|JJ&}uSp(7fZH3{oEU8XLy@xMo9it@8}=7cR*JzZDnu5yrwCrx@kk}RI()pA#?C<>$&OeaW3(xqBh z)G&!Sd=}MGlC66{89#b5(m`cGH)ycXiu;WZZ_q%UF-nk;TY3U%1TZ&_mQ-=9I@MqC zO`gk3j0Q&sZ%2{v+nFf;P;Mydhv!rbgDY=Wlz4~&V$0L56|YW6#zHC2kW9=h#z~g2 znDA^p@KQz*O#v*|G=^`pp%iz^JbW~fIH-nsV6Q0{+)+w?Xo-PWY;3?N@9A`oa$t|- z(5ijG{BvRS3&wCz5%q^9a3|_JOMtJGbd|$*!NRDg`5obsUa-1tB%rFEQ@Him&^XOA zZ9-**r08Dp({buY60f9oXl(o}dciphaNiAqCF7u}fgB+|dAK?7cAk1yWFMhjHG&Og zLm27jP2Paw)9iV;wTxX1YCay(8QEDRW%p!-01D?B;>m!XU_6}*ly^4*$)|;{$lR2X z!?&6w_%Xgiy#8f{gc;6Z2|sVm3Ox7m*aV47Ti)7Nq-9+rI`h%^gQ1|~1njO;AK7MbP zQKXaHxzro4T>JbO%lHmUIwZC(;8@8(A z1{CEXw?7keV-2diLr?s2@>`A4p;RW_ z$z+_?xJ7s|J)xWfX~S~Gl(74ic1W~n^Oq~!qK7bN%p`qxYjUhE4l=1Uc`H}ov=L;{ z0y$Cckoe0CVxno{@z{+W(=`<3{*gz@%g@U24@HP*i&5AlF z$UoIc&)Gf*_@V>ZB{+yHBDws^pZa7E!1-7{G8gBeUYLJZaJwkXF12Z!Ih3moE#=+u zVC7Vf^$8z;@Wnj9`};#_PZVkLsJ5l1751s>F|X6L>QicQeRy#tU`MyAgPE7c&PO;=A?bdeK+wfq&KCkC$Rfboa@ef7j){Xf0;ma+&-!mgp%Kzp6#l;Gt&o zU|kmW!oB@lJ8ca9L_=wk-j(H5?@aHJ(S+sn{cs!V^s>4@oJO148Y^Cm%tF-taBPID zGp#eYZ#qkqdc2%|VP)-ZQV;U98;SEPew<60PDc?B=bIFDrL@Mcgjr($-x3ASF82CA z5@qvGqUObhd;kdn0KNzS0GR(*67^pvB^>`{QC|eWJO3;Swv6{b7S-+P?uM-z|5nMy z^Ic*p%2ZfSv#E$3izL#JT~EB(ZiRR#6k5H8JNke?rcjiVZZo~+7{+0QrDm6u27-tW zjxI<`2HOrC6coe-k2-*279G}|dAw%qs_ug3lB!)}jP_LNvF#`x^WO7)S~~kYWFZ0 zdGFQkq-Z*3G+6;FlIsp?uSDmXsm!K6EOQT*rQ&5bmBE?nz1 zUU^uF*Z!=ISHFsp$%Db!*cB&!C265Js$TyuBOV*!H^!m(QNmcshex<|A-qGw%vlH+ zgR{nV@|bDoDD=A#hd+0^xFoHOmLT!S_}P6 zyqD-~bn-KUq0p`@hw7yi?sG!DzWl6+iWrflhe~a8dtN_P=PCInM*rhxpN9~itM+)y zU3z-@Wfv{C9*TehUQf(8-)sb$?<*?zU4$#S?hJ|R8OK&_or%%noW{$;*E|)*po9tP zQ&oLNuo{|UBa5F=&pG{n}**W)%;KCb4PD|u1&oY=OBIm7ky3$c5(S=;*gJX+Q zb=q5NbOk1N9&_SM`F2pHknU*Kn!|V-IW(!9Dg|mnUy*7fY>Ma7Xz2yZMt*N=IcIrU zxa1fUm|E;awrY-aS=jS-BW_=#P??d`xk~5RF7h}Q2|~*` zbh$)c=D-!(E~k#09;+eHBj}RW$Oi2+?^kXkNH2O6FHtmY7?=QY8Sx?oQyT8ks)zOPg$uK-tW>JmTy)E4__IgBT);m zM45Eh+nUT-fwP$7O*bjT?hKZhBPmHalNcDk@r{@S*J}>iZWsIt0aW+ z1t0$HcGPS2=q-KVZr4++cuS(DV3=U>dBKZzloT)&#nb{uj!EM}1`m~@GheIv&mj?8#gqAQi-+|xO? zLK9UHK@9e)Z<}!GK^Sy#ktE2ab1xpHvYJeHuYGcK8;2H&Jycud9er^{Z+EE6@BYJP zX%R((5C#!iL#HrunN5;(z(^)kW(tl>y7Kg-wSq%e%7l)Tbnn1$EVU#7p5=D-)^XC) zE-SZ4c1Jp=!mD(In#5c~2J2qjnd;$qyWUc0>k2_;oXXuAFVsCA2q1*qXlX{2`xmM3 z(KNXG*=5Z#muJm#)kPj(JC8PcU}0T6K?9*e5@?KwMtX1^wWkfJNph~X@L8*x%1ctI>` z0H|A!>+_%`D@R<8UjxYpu({pZ}#8tz#hw>t=`*=x^91(zd$@UY56C`b2?6tkcQChRix`z zg?E8GxVtllo^Ca%r!MzXv^s0cNwzSu1#N@m#Sap?GwfQ>2x~dV9d)*yv^3gV#*O7A zPY1Gxb-OiJiH}4&)4P`A7L#HL7-ysNt&`-U?3)U8B^IV^;it{Os50#JQm~y1;)&2G!Ul^o*@Jp70u2bw0MAb26A+acLzZAj@}2;M9_T6YPDHktH!v~g9c|O5+K(x0udo+EF!(k0(yvJA z%n467SDQ?XO{R-E-9iK5*E?P|p-AHyScsX=E!z9X+Xka7zWw6pZHFZejM=sg&)0Ew z9!Z2r(4uX)i9{|db6PyGWxO`f_WRhvj4D@$o#?Zsny}Hd*;&3RKnzsov+~kGKca5sgrsOp?n4EQvk>1@K8hIkt<~qn`;Z4GtH9AM;?IY8uf|J^F4+?kO zAT+UlSh`i!{wt>W&q#A05@z4XO}wFj)j2D%4#Rj40(t6?vzfhl#sq$|&|dL$@K4k> z+HWvue!p5k$bdHe!2q!UGIq6lynsG{GC)89;Gl4js%m}QfY2b+$aUiUm41&P)ChJx ze#Hab(tV%<-uZqmfM}3s@N*P;?S3dgDo|}|WtAXKkjv3|=yD-dc_dx(IkP;JtE z$3Qjkb+UaPfVK#B#eS6_R`7Q!fLNebh;{0HsDRx-A0SWA=vmCLVdCX z20$*5)~$X71TPS4R9l}QS7>(Ce!xIANOs+RSRgRaZ3=y1ehPpcer%I z?EZHM@G`H2UND<*_}mbLc8Hgu0w8kw-{b?M0(YZzKG^$^L1YLyf(dd&+`!grpUgEL zke9OuW2Xo?VsAh%y$~Cz08Mm6T~To$*62+_dEG$xL#y!nbO=2$cO*e{L|(v6stEU& z>~Q~@(EG}Bum;c8LAUr`X!|U4J&|U$1YUUhd}iQrfvX5JelIjySD#oxc!XaN`=bzi z0&ki@y+VC|y!k}lJVCblUg02q!|s@ZdQ^DKCOKH?Xk{RBX}?q5wvF*(~Q6~eF=an zJWeR{$Q-bJYUIZYFW~wpLU5c_)5c2#bgSKRngHi=Ld)LXg9Iu2y~-yveXr0${+ap1 zVeaa?WBZqnow6r@%$SLcq$aFD7o->g1a0b30VOJGg3K^Qh1rZnbOZp3Othm6tmhWq z67q;@a2*F;M!l6k{muU4^x%s@TC6b^bzed=eM=mTffa+LanQH0%LTa(G46VX4qLNAfHfp3OYZD1f z7Ida{bVG_>zUegqmoNxZyX1q3h4OdDhN(&8!#-Mm8l5**Jv0d7p;ZY0?fRJBjFieXG0?zXgIRE1L@%QnNhz+&2l7KTX}xhj~$U~T>MN74Z|jlx?% zs}UPee#Gf{ID&8!t8K6o&wekwq7)2zFD{rJ*sHbcIMAzY!1+%*nKPp&ANFudS=b#w zyDQi+2VlmozrK8g#(iG^%G@skept6jMCDxiPqg&6A$M%{o1OR_^Ne({+rU{HnbeOF z7M-h%yNcGY>LIQ zO(8-1aX511OQ*yD#Hdav$aBimVg(uUm8N2a?2Q{E5LKo|%ffBEM7XF(w^G{iKTz1! z8Sp|A=W7SXgCed*m(SY}U5PFyn0Jtth9lYn{@}5eP@N#@@k($C(#d3-e@mowlOq$m zD{KVW!3e|j1$Z*V5&@>4D0la74me3e2G5+kwG8_muLn1@i>E{yuTxI4op=r7i*?ePzO`{JAujw)ZCA=)Gpu0>x%78hW0xN@1L=fC`gZjt?V~w|F%_G7p znRi#3Dm~<@Z&)|X1WUUgndu1+nb|?ohj9T0V~0u(>@1cv7rMfRqC1vu8Og9#>NMm9 z7CG2B=ZWMgUik!hksr~oy~0b=TCW;Q%)EL%h|(DRB-VOzycdsm^85bY2T-rFip|Ic z^3-Z-l&gjbwTcn3MucOWvKkRJ7yLzzLzM@_SQhYr0g5KC_)+^KVlOW{EvoSJmj$^s z@Zrb`nJq&GW%w|U8~hPdf&0Ue1(`n8Wsb#}xu&I2ZsmrWVc*BYSk1BHI*L9!C(~m; zN~T3fH=-n>y5xdUOd4*ZT61Shee_kP)E%G|+Av`eHj$u<%MIW`Cv<$~FoM~+)$rnG zPD2bNQ-9e6cu+d?>Cfo~_tE|`(`B=@atqeAehZ5i=8Qh^q*B; zO`h*rey%*sOib&8#k+AkG#V^#1WYiw=Ux!`60QyUu;l?U+?s{RV7kPZ1uC|$DrN~I zn99Eof}BXXnLPV{Bn+*)nh2J0qK;1PQ3Q2X3VV`a5iaGAOK^eaRTbr5XACt$ z4Xk_q_Q7he{YkiN7`8G+!#Vt>1CGrJ`KblKhSPsR;h-IC8Pd`kZo1c_-7yG9t5Dc- zmyM`~HAz00ag?{J)FpHP2W%KSb2S%_>=8|NrOQnkOI#D+Wr`%x7W|~ju#NsI&-w$68{l?(n|X_o@FYsSt4etm_{xc8C$5b=p+BN=`3 zo2$|L{5$Xa7pZwer{7E7Sa;A1eplBQ@!D-q^6kvIe(~+fxt{6m?)a+q?!2U(TnjR-sgXj9n zdD5zXOr9G@aB}qyvKa!LJaE*v-o_2Igc90^l_^lYYBqTM$6ZB^=R$Uz8rjf>D>0+L zv?;==@ol57QG-ydyh5hZ;0Ge(9!2|n&KJg+vRNy|L2ts3;yb&lw71CFn3mHTYNkX6 zs$}(*^W6DpZGZ^^5;W1Wb#R0?Bv5IrNwYeQ&wo4!VxLMoGP2Es*I+^k9nX7_8N(H6 za7~kF>4eS1gnOWH#&~bljw|@xxQBjR(~hnbwZdk&#sn^ zC^OO>L9(dLVij_*x@`HuB3v}Li5*rhROY*6_Mo(?@L;ekM9ZzWN zEFFr(CXH0Zs6k)1)8U<&K*`|OuhyHp#0J7!yyo25?0Mt|fq2>?fLKQCBtD~Co$D;O zf146kk)=7H4UwvM9dKh)?QgwQUwUwex`)v`YSXhY5ghOrts7!a@@$Ffp7LAFw;z<_ z&9jH7FWBFD*Lg!Xow>_DKGN}Ul(CM)xSz*|JeSwVs^qy*ofL^tl}XGaA}Yeasf6QR zY}s;T1XG-n6SF)smBon*O;MvuTqks37?c#vNPz+Co8uruhBqsC;H8H(C*}0v8kPD( zPrendF6Vr;t~K+&?K>Przhyh)XTOTKM^C=huCQZC)8|Lex?{4TKT>s8E(Vvzla`V# zZB`qfnJ+UX-KFNYCL5n=ti2`O@f5A{Mvtj`MX@@MXz-e7X_XA^G&$|nl_u#Jrrgb* zR=&vjKfU_Cf1a~fgTypqPS!$Bx?|li6V_*ep+xoH_*)c}pInG}>)uL*psr*CJ5MMZ!d|$Y&n+-<8Rv%@H*;2{Up56de zg}GHwcW6pRIcKTY?kC}9=Q9u%%KG0Cc$H2?XUa1OPBV{$l~@FoVP?!Yci;xYZmM%B z$aQP%ON5R+wZvpa88Atfb<$;{6s1HFMVS$CmUV(hLBBCmBKuM3Ka?^rlt`5Sap#A3)A}V!@Vr4$0fOUo11!=0n*TcyZFQhJ8Oo8SouPs#@fm0eCZ0Q!H6R z`#Pf#J5vkNJY7-U?e5GQh@dV5+RU3U2rNeZBs(-oFRvHaJb;j zIe}>Vk1zAoMYoxs8kq~{UAXPt4C|DS1boGp07Ejhd2n=yD1&#n% zipLgP#unXJ%XUT52AFY#zFkO{)D@5(H)E=in>n8iwL+%VXVQVp8j<8njroU@@NaTz zhLV38ED7^_#!I_76slQqRa+l^wm*xkai=8m(Wq>ue}SexDlWy_dfz>e3xsxK2SQfG zABUXLGfZoz`Jce41Zb47gO)QVjFJ@6rWrDck*X*#|z25tImLni$R$m^; zarM|#O!9}DOf9cnV;*JW(&x79rK!<-gPA^9?$}MYMzv3Y$8OIHZ}(5CyM9?^dsS$T z0dkJdcy=bmL}t%E-Dc0OAzbmh@Cd?wYmB9ibSGjJg#orIvKwhMv6Y5T*)8&ZBB$(j z_3)&gH3n7Tbfy&pp9-g3N*e#>e6^7b$xs>dcu{ZEylsb9{&-4;wS!~30tEb z&c$pFVS}?VDF^v(VM^XGP*&`$K3{_O*ieFTtX-m|swt_d4*@R$2ghHwbuM|qrxsa@ ztb^OvpbDrGQB7ro4evKooZX-*sKk)yTc(?2bVa}*L zcXJzf-`^9J8c9-Gz+?rNNnxa3tb2mnn@2B{IRUT7ZIz=$6G#-n6xE8{9w#uO+l|ER z>Z^wM1(sx)7R{`iVh?de^*}$YW62s238a`CrAGQae(tJbIBpJsgT*!S*kDXdd1w8m zrNsjMwxMN6NQkbFS>wU3T9fhnJom&34wDPg%+_USS))Ua#BF@FKMh9S;67c2A-*Hf z@nljv34I?w`-XrUn?*i>wDBog`5^zsFQC3}6U35;fc4h>CLnIj4~ENi)F1P_QI5^> zT!vfYP|eO9p9?(I0X@}98Ubd^vITZ{l72$YwNXCbM;M@{|0r7woO8JH-a5B`(3>C4 z%8C5K@&>h5J&P3XJg{$;nVKT^=bQf8lVjRRPmg9|TEp`Tb{&K~Pu$b#nvuB@OqD|6 zec;k8q5MXBtZt(DK9x0-M=Q6<@9wj_Z8>}*?pwG}gX9(YC zi>Sye9ejFsNPetN5X;?rFbwsY@`ibSAm(#NRIO3any%gFLVIty%1V>^_3mR#WqoBI zQC>Y$E%!kU<@M+1b6Dyj+8HIgzRiEyC|QlHN(P%znL439toYf|_;$LyBhB3%OEGR_ z2@NbQ!fsN@Cu7$E=R%USu^NSD?%R4T^Z@nr`&op2!8ff5z9N`O3ceyXwVB~WRz?A5 zNWGPn{ovn=p*oezDVI*XDJi+s;OZW!X8uKQcl1nZ zq}?rrXZy%X8vGHRFW(c;jsE$d7{b1?GOZ77ht4kR(e??z7-}ll=1}Iw;nXFS-3;w! zU;BkH{j<9xLGs`^1$X?Kb{tLY>a-+rlSJ$~MbMroe)IN7tV(X9+%-n=N8yfic-*+h z&*OTj*7{Di@Pq=l{0GF+wKRv9!GE5O8m`~o^2FysDg~#D#_O+yZuzCSwQpJGc)kj_ zFZm0(N2~1j2&N#vji;eEYmNK^*(b+_`^1l+->P*5buUa>;olDmo8g^)!Bs?qTgcC3 zJ|2XTpt*sdj$ehDXB{b@p}Hx^^La?`VByxmYH9u-m3{{{GT z)}?z(mB4w~T=x`yoZb`_%ePk>PoaeVy1-;qfam#BM&I^-MHhuw&UXbYbe*x`a1EWx z1`#p0f;P$#dtYNOEYAjk)loLj&KloCJA(Iwaq9~H5(vlm1VT*Zq*ocEvB}PLZZ#~r zZF%xxOlE!e4#~MBkj}QFIWXCG2%g*#=eA~yMXNlKy<;=l%FB?O`a0PbQTz5cTNPE;~<>=($FkEl{bYpeD*$N>uA~F zDD2mgO!Z;e4ym8_dq>9n?z~pApBl%G6=;^r^`m~&ep&tNfxlQ3C=MBN zvOSKN>AZbXH$N9M9%Bj_?`;5cvdrj&R90|oMss!d}QSkdA ziNwcsS!z1*bTsJnM=~_<$H$Bvu@2lS!SHpsu&THEdWZ9+IrqA zwQ;^(856R^&?KcKRUi49imj+&wx~hQ{4&ao8B>_{`iJ`ci`nLev#6X|3I^-Jwc{ih zkz$6h7$J7XDtuH+$P+(%lTL0m8%)V*y$EsyHa7KHSCj>2Qb*IjA7uq460CDmo)oFd z?O=*{sGzcwWedR;ZurDmY(=!-l8}2Pk8apJGB`@u$t)@fFE})MEW^f7#%!nHnA>?{ zdeV$o@G%7gp?jcKHAPh^Truu+i_u~$YNW+`&iAoM%l7r{n92laxz0j)F(Mhd*a(-? zeQa0oc636^+`r59cIS`>Djlg>E3q?w_i!&5H_J4zU_J;vrzV=6~2Tn`|wH34*o7c?#P=y0x8~ zDjNu~Gp|5|7G5eQ+thHYmsYcFe5h8b8;ec z*_jdVWP)WhlMxfjVq@|KjT0lFUJx`Z_J%S{<1oQAYH3(br3Jrm+%2p=-_UAi#F0;Ha0^T0os;Y;Q=TZI7p$ zDk#qtiiHqv(<ZajA453l3T|WsuWuP+caxhnim905MgQYZce#@c<0cN zAEG7miB=m}UodtW637S*P zo?i=D9tyP_hquKR9s-CFVY5S`FL`x*X2p7((gdLO! zLN(yGY$s6w)07?x?Dlt61uWr#&&HLKPvXoBYX-PAxNXeqhq4f9h4$z1kt!bZqTEp- zG7v!01ISWl_cM|Se$<(YxtyC(;;{(1DeJFVy(!m+g~WMi0XY4j%!xs3oGUkGVb19K z%R&5Q_c4EkVw{P~W?X0swSqx71^4qZE72Q{ORblzD&vHC3>5O_jn`;fa;)uKT@0HF zGzGH;1I*Yl9jhZp0%XuJrV4ZZ9b~j^AZ6%HAnhbf{ex zowjY;wr$(CZQEm(F>^?xefy3GCBlPdF-&+6xh(9gZFaU+JzH5ympkm37i}AK zVeYd!RdX)ZgfF}DJ%t2)D-9S_<42z=GP283k>s(KeJ&s`9lhh`yM!8M<2Yu(9C?v| z;zd-(h#;llKPbnOYM?@&I>L7Fpfkc{W;767vC=uYga_b)>!J>}b#)gs3TZHGhg9H1 zXVT0HBF-E$>4X~^UlcH$JtzRL`^a{T=B|#Lq$PbyXAc`0HCk18dZr>m2A!v3Jh{;P zG2H)XN@HQi3yrKLf4DXg;|xlvghx^4Xs<^7`yNlX`O`;Na+bZ`eOS2dRn{QLKIph( zR9sVjZ^VK-Z8h}Qr6$+nHsUg8AvZ1|PH%1VZ_$E>1p9&&1k|}j$&FVIhMX==Tq~BL zZ^|~4^0VgSQw8h*9`Pa?l-vrk81-uds3<>>lJE?7dO&+j*$7O9Z9$DvCRC=E%z5ua z=Ya#PRm!s3&-~j*)DSs4W&(;s;fr3Y6neD>i^F5;qDB*F#?J+*X@|3UawkL4MQU7&{g!^NAp4F^mrdo=>{VhcFo;W+^xvLc=@))sMt z4=yS+-C$7T?)ojuy6ya$1r5y_Y@`B?5eQJ;tsRV!tpk{FB5S1US_Ai(*C-#MhPL*O zW>ef%K*CJ8g+#pao?%9@c5W2+yJX{+30p9fgy1=(Sql2fEw7M8M9J}*SSOPLG=8RJ zi+C{cbc~mMmdsBFykOP)eELlx=<+zutxk%d6eyh+sq$>3g8D95OZ3f_!Z0KM-r88xUG}QU-Q#m^n@$())HxFe7n$ zv?Ys~TNCP_g6e5KBo0c_1-cc-g+8c^n#}|)>{|8HFS3vc8oZmLp`*Mp<^d6L4lI9B z)#F)^uHlehG|(oURK_)+S8Un`37G}q*zwCvrtG6fjVM?qytCPGyzo*71bI~%e8uD- zV{I0up1EW@{yk7H?pQV|oj4ad%WkO2dhR|bZHhh8mQvKZp(P4~Umpb|QMiwn_E+*B5dj zY6~!kmp8>G(Q&QFM`aianPD2!>j|h_q_%U&xPsm9F^9xiJGhecNSChWA@X5%&6?xG z9|Rl}FU7YN^alzdgePMNjEW?&>>q_izCmpXk!;N)nF%T9IUKNF0I)2#|5q%K?0jHw zL#-CZ7eiG;k2OFG=~LniQnZ_yZ9;isRHm(Z>j(qGlFuaa-3@}rSb3>c_uTHvi!5jt zh{N2iRw@G#SregAOh*VV2XA|^`i%n z89Ju*voMk zS&gk~MzGD)HWSI&dOu+r&ja7>O^OW{5v0yepkaXfT`8G!< zCvD&&ih~HH`td}2Z;aLPO%(2w}!vdWIDTh#wSAZCXVt(BEx)yreWQ&dR!8JZH|5Fgi zEu?rD*UEsF&n&%UdHH<2?qG5Of+vi=j46KgM8VR_K2ta7#WNzy zSAq(igm-flAA~}+nr>q%=}W6vC9XyKI*K}s&BaEtzljk-ZWb5Cfy+YL7NFM3ErpepT;^b~hy_oV zQhTgrYN7{NY{wzDTWN?4&jd_9dDmRYbYI1eY%SA@2a8goQTv0uT z$jro#uO>6KzSQOh>}6fwZN!hWGbf$IRXuSR)m4{gY8_NmXKE`3>~&ppimYC;Ih}D- zS<7kts!sa*O1xxap9$84`mU^(V>MQ$XGD$hdttJD> zVpdTeve(F@fA5H>3mbL@YhaAUDVp>qPCu53GYHQYYEmFgJVy z?h$C3dHS2^y$|G3JUz`&FVGW}Y+|d9V7m&X7ugKp#5JAWU?*e)_7QD*li`->wF~8z z_rwo=`5V!>4}gjv;E`Z@jDaHW3v#;8Frn>>a@ya3FZdk?Of~7XUxPuv-v{y$b=u$X z2mFzBnw?>nC=Wm5(=qv4bMg^pW1BoUm$Zo3x z;KR@^paXM2eNYF~nRU7%(+Rt9o32YA>~+m>C#WN=ou8r$pX4Lq%1^@VW{l!AeBb~v z9rwQ`Ph*gF8`1%N@?X~_)H4WX(MGJ>+~5b`5obF3ZgX!ZU>Duw6?*T>``}Al)44AS zWw(fqzrP2W5!~c;X}Q$C|JSyCH)-2n_^VI3;s^4z&rpShHHbg(*;#XmW}d#k5>Yna zVv;Sr$}l}kkrs8v5qughof}m*(Zok1^p9L(#^3d&O`@t;*}fayK0!Mx9zWvE>2#+H zdrjq~m1=wDq-E=j;pN#+ja?~G-R`!Q!4v?gCn+M{t+Db3A^{d0oTMCSm2T$N4yBM@#1QHV%*ZP z`btR?N*n&BFZ}P;8A%&d^86#vp!0K#SUnCN6+<-9D=ZSm8iuyPD*dH%Rtckxg^OTY(Uf%738PJz zsIZG5YDyafvL?(`Sj7`p`4?d404HP5;lK;I(1Zm|Qm&DVY1)#h^kHq&Jh_qj6sw%o z85uML(xj_utJNr=C~8JIa|oht6uI5nI1x=enma6yu@Ah{q_psiJ!=aU2##)*t6L_E z%U>Pe*L0WjM~q5co0)kwFEo!5*P5$H596(=q*>0X#}d~adrc~haZ;I{yv*J{aFSG# znLBv99FmQ3cC+k{`%rHQpHg=?$9Y@3e3M$Rmln=3n)7_CTx^zc&+@EesErHlz(%-f zG*@tS)||}Q-s<46Om#Gecc+ugJl^Vv<4z-+fx6L|%b7|vBXzgi zn;l9rLv_!c%$Y5&a5%Nx@)TLjp2;b5KK&!vl*#QslQWfM2J8M4#;r~=qjmE|>t5)8 z>R?X)D3?@h@;>`;Sdw8sOT!Ow?FnX`d!Ub+I7H)6KfLMPDE;C!?~kpy*q6yZZ5Afx zjuJ*OxTXzG;+oIuJ}yZQmdCk-%z0x zOd>xtgFixu8#X1BSje%J`)N|#nM^try_?E_)f$fZ!1`vZT5GzBTHSssdnq+M{@jKMU0pSL5hr*U9mR?}*OcDFM?6?uYl zx?)1pkEzSJ=u0tM>?M;!yPhiu9k#HCRoO z@VR1J1X)$C_K19@A%-LhbppG5eQn73{?|d{h}k&RSU}qPQc{)Q*<6mM4^m#5W>?H_ z!th26%74uj;IcF)*D!W`AZpShq6|{Hw>La#m&K^}7cnEZBc2KNN}YFjwm0Pt^U9XS z>y4zCn}WGG7P&-~IQAs5aO(T@AwwCqJ~9*SUi*o;gT_GLBr)|EY(yrZifUojO@Y?r zm$c8v94r8jQpoCGypl?v5H;0f?pC zHInX?HM-1}%2{6RuJI`OL%rx1>a<6~;FZSOmQK6rLuc}g$6ZlU-ZSz+jpf%U-S87e zX4dx|_&nkIJXuGwN`jfVMbRQP37HsXT58Vp_xsku{W6bYmX*c<>El(OMsv%r`kB$S zX)18XGsWw4_k5=#uED=Z^J%A5j&m4_^n&=S@@p+HKsHCNYfVk+*KF1QjDL7@4MvIR zl6gOQMggbh!*kMfl=1aSvSW4F{N<=fsat)<&B+iX6-Daaqim=Vf!4C~i#?i*mHXqn zt={j*#&;kKyC+yEM6sCx3eC+S@)Id?P-;#FzZA=;Dsj&vG{vTcH)lMH ze;BMh*v*y7dmWDKJ3#RXz*q#&WZhqbKL}Y1+4d*N)>(spldY^}t<_SE{`T0TY>F#* zvy*#UEzkB*!+cPzFu~OJs8z(gwI$Lfi_5vX$$;|ae7a>8EtSW*sotZ8ww}d3Yda9H zqKtW$3w*XPS1zwbRRqH{hnl9S=Ft$68Eff%UU=DlT4yY$)rGw z6C@J+I3%O&uT!G2?&wBl+51fz=_S-YhcC9g2Pu*sG=A>N`AJ>H%^GZ{zp$;_cm8J^ zNy4`SyZb##Pc=PlwQnFDTDZy%1I9ND+qd!cs7INZZ8$mA(wGk)%4@4iGIK@;VkC<- zc&K&gVh>4Kgpli+2NGT=i7OD&4&{2b~tqIp2f7{DldxAVL*n<>ct>S_;W zLylONt3K5OFp5BMs5spHIJ}vNT5Q6z0@VXCO27aeQQh$${F#WW{sd1N)c04EJt@(h zVKK!D{JDs0CN{>)NR=mZ(Q(ac2@9vLwVcpJ-erW=($gU?a8HA%lcEjM3wQ6Zm5Xm zG1qtLMt3mE0JRhrk1XNxJN`)pz_}9D0EM+AUAS99iUsPS3k&OFMc!Uu#E%Plv_)@x z5;p)C1uL`M886G}YpIS7m)=|_#|*PI^k zNQy`Y&#F;?_F1tnR>P^1Felva7sGDMk3<%1d{MvB=M=EV@-nH*3csu*W3_) z<|ZPli5}EUix)=7ccUq+*kae3(fIS8-{gSOqAAC1&8_ulo`y&D-!=c13-qoLAf?m&6A^iJaWGi3m=`Hrxb` z=qVXN0_vLZQYh(@M!g_({OCu&K*(dYXGXnPh%FqsEZ`weD~o>OqF(2y0DgEb-u@j zJ>bQT$~p4N#m2N7x$4~wDwx18J67!GOo{wUJ?)j}v;Cu<@vPqHsW#=S2j2M$EP5M^ zUA4oo+HI&u@ynn7%pS!$@GEcTE72NR@rF<6x5q*L!g@3#!`JC+taLpWPuO1B8+ePX zP82OKBBMRn%5Vr~_Koc~bhM{mxWX?x1$f#Q8e1>)rlVO+lEZGv-Q4-n}d5s4UClWJ#@7&A0|&9Ms*DYXuhEtD0Qesq;+XOy@~x;;&zp5_9bv^6H( z#x&vF?Sh@u__ug7BRQwPmat5*Ggz`i7D?^XQ+6>&=7CMposqInvNKDvm+TxbyOT}w zmC4d2$pt@YltuEDxgsBN)8F#y9trMkj8zJr(bA{ri6M!MMJk@b(x~W2v0+6&E;b@m zd6f6co6I*5cLY9W;1U{?JAys2baQL^z}~BXd3!YtN)EemFB}=fS!Yi%jQ1FQa<=Ty z{t5@<@n@%J)gSeWrU_-^ni4d+j#C}w-FoCBmAzzpn%h!2yhOcVcx=TznQAk#QAdRH zw?C;S*>A54`=!X}yZnl!q0eXOBNE-9|4QQcr-{jc59~Wax3xtblY+@FT$oxFNBWMI z;1ZhydVWYo7%c>;reLz7A>wTO$ylYL3fvni8n>?~!& zOlIUoPV@Gg7umcz|EQ+|S(%=HTZ7V8tp@shH@9Gz@7;(a{*MRKWn!~#3!N%-$uV&`FtzKGG?0HJY z^WmQbBJ)X?$$_Ou<~VCrdq!D-3~$;u-J?HT3a{2=s?Agt06ia(Zoe=aZ4-IpWr5rxRWP(T{EVlV^@f z{wa&PsxUnC;xUqF0StaA{fmLpY$TC;o_`68OH z_B~6Sl3Ek_s#RvIMgIyO1HSkqCN4a$xME)Y6`uFHN{KrldY>%dirRz~^aR2vUXLdM zqYX&4%M$cE?~>^V9nvY0+SC+ul}k~QiR!E&uSluu^^+kLR@2C5DtANOt-~qt>z`z& zM27{Y_qoACmR(DTZAzRnWZ*|pv%P5tfa9_m9}HYS+*|Q*Pp-j_?=@)67CmvI1F@_w z96roRA8W!^kL_)X8+New$-p#;qMiyeO61y|?(q3$nnDHoy`HLPwMoo3V%mhA35t=} zZWOnZ+b9o>o#Hmd7b=8f$?Lma;frgI8{yvDvIBG`V`?+ro8m=fON+EVSBIj}gF6-A za3c+$a<8ekzY7Cx<#G+8-x0%KWL=IDSXnOM#bY;(!sBovYmV~Yjge52MIx2@YWSOVXt_?n6PF+rQO6tG($J{08 z;XiPMd36RxJbGR!C!*)_3h=Uv*7I;xq^h}`U7%qWHF zmx0)!oEo`BN-c7es!H@a4oCDlIa{Z4>0kNFhk42W(LC}>Q2ET-IGgO2_6*w+LQQ(T zI~Y0>wfPa}ot1VV(}}zI44kb&-c^H72=%(j`yx|Vir1H-*Gie!b;uO!y zS^Z0CcHGkf$|dppdC7KOggYOzn~@&Q)B0!(pxHC5m(ECx?lhP4{2|LBqnRy^i}7&J zY_)7Ko;|~%tXU50*}_!4Ca?E=PZp-X;i}ny? zi5ylXp0hxLZV(UI_+^j{>XEGAU&Oq%9iM0(3;b)w-$5YOjyH}dpYWH_cOvfwtB!=I zVxCN^>GN`h1oN+$q4+eeeAKr zA@J7C&Y1=cKSZEU-q8)(ICot9f9`0!M%~}2hc${H0r72p_xCS^qnr1O;xbNblKx{- z$?*bfR_FLKPVADu!&1$%SUF{0V&4+L_i*A??~lpTHv*Q|mRE4$Ex@%gC#~?3j7aav zZsaR6a&mzocf2-n94hTGCrtFD+TQpF5}dp=a}^li$k(@|(1E z8t@O@QL%hxyu&q?BTo*KlqgHagPcdh0&H_go6k?n(Y&Gb*f}rUc-(i4mS1DIJ4jt9 zG|#H1lF2|RMnC4^?vX~{f=4cyw-5|of(#!a7(Em~a_BbtNVWdV`#z@iwN6xN{EE7H z@@uS-D3l}lTHKVpvEUihVS$3DWj;b1tY?HMgO|a0LWJFn|2fPG#?v9Z!gGNRy-O2> zFF@GAdfJ29zZQJ;Prt`(+QEE!%f|Fhf4<2NSHQfz4~&v>;JxQ_uh5a7*HZuIWA$%i z?Z{PVfZQ|GkuOiD?1;XETsiU@{E9(!mj8eO{U-@|t0Jat6%8AyhF8k?)Nd}k@8d+H z9r;>whe?nb-}eG}19#9Tb8tlC~^nENYcBe(1KFJ8U+6gD?&=ON+Sh;rbr*N0Dv2B1t);RiPR+b(^}_DC*{sE^?WFmHPCI9_tCM!_16&ootIhW7@}7U+ zDcb%V|1n^d$2j{rk{I#>lx;L_wL53DVzn$ExOnUb7#d$Q&k=fdi$A=Cb!~m7nz#Pl z-Z(XM$n#fr`XlI!dHN%f0?k^VQ%e_<86^k!D=o+Y>W;rqp6SwhekIe9tf{wzvsXZo z_Z^J&A@7v8f0b?z1JQoMbUcfHFi{op;)gu2G#Wl%J4{k0fRJ^l5Po_5evOcNFM~;DCfrB+e72Ygd*9IC6!H zHe^hLwI=NXnl!Ayy(YbG>J)5|wboE${B)@NO!A$JB8bz~d+Pz>{E7Q+53fb#povL5Q9G~+sO}#n=Tkn8x zY;v^G%M1$s#>l}PC1MCFy-SMO6sRVaC zy2SchI9ak!NX{63PBTn1J2pMH_+OiDA)1}Wl3mO1NU1}epsZ2t<7h&mx$(OFAM)NN z=;vtBm@U$M7QDjbj@Y+2dh5}p^O=ld(Zudux1!CRlw%T)(pE4MbIBb>n)7Bbgv1TT zsFvslbtR%_F!zNr(A{f`uI(*Nk;~XNk#Wmj=Lmh(M(^{j>yu*@cXMf}Zk~&cbKZSJve6W$^ zj9b;y;5g1=*}8%=nb=xm~Wk z8`KZZuc=*^I=i#|;>IRo}f=Q&jFl~fiwWvuy>+3x!k;cOB~Wmv%vYHO_p8*vz=GUxteZBDm7 zoYXXSsM6W+AJy|n5#-payh4<#q z09gEiIEG$(zx)2i^jzPpowl(3?d$h7Jpurr`b6#cewu)c$p~A=ip9$eG6MpF@z3CY zi^>&BEhB(Quu}OD%n!iI2R99lms&c5x1`AubP0Jf9^0pv|J_X(3JYL@5wzZm*S$`A zxETVFBhgqWHiD%e0VsE05JMMOYhT0jp2 z;58}Kb7*k9Lz>bUDiD9`(ueOfF+D@sGa}h4+_Er(M*vXHwQL5(CNM%U9;D30>Kv|m zm}kHUBZNS~yls$vq3(O;GQ22O;JJ9V>67D-2%%A^`{yNl^cWsPO(X;Zw7p*si%itk zax7p3wi|U&QjM&@;L(~1?GFe)u$u!r5b;2xzr5a9*-+s4Ohuo@DD+2T5Rk~|lRzBz z19}8Mk-bL`t|o& zVdunF8IPiG0%AxKq&TH?YLH|mB0L;Ukn}X8yQ5+nAk`3}D}C9t5~9r%_szp~AgA-jow{z>exB4c4bM4lw<9$XlJEy8VaK$QG07r>H&_*GjJ zP+x>R5qgXhN`}lQNSxkk7lgJ-mXws6BV+>ysJX~|&;V!w`$Nvg3<%&55CK$pRS)F)w=J&aH(4mBydKmdCQY74+z zRv4;L*lS8O2pmn*Uu2no{Zxs1cJOO|0-)a(@aJlI^F&ZVggyMwW4_$Doq=$pc}x)g z!{{VAjDr%TC`dN62!UCNM}mY<{e%>k?(52F--H-1hU6Yk)fg zToB*#%Bm;bLJ{l^z@Avn&q@IyVcbE%m!h*pdian&Hb^aau#L+Sds7g?0>?0-a~MHO zEM6Lb^XLsC1Nmhdzo~Q=S5h_@P4VnC(cvU5~C_JwOWkWHq4UrT{*K?R^BQo!<$N> z09gU>D#|OW6sfHOt$~t}8Om$2iqxhFXPvFAUII6jsV^p{!i{eRnmU2nDfhHB`LGQr zjzda=XzqaRQdW-p#VSeztc2t$2nkZK2Bj-1guDMz0aPpl-4;2?fhH)QEE7oSf)*~T z&M8)zs{>=3%890EsjF)rmgid?!D^#$P*G7=QG+*p?$y@RINe!J1h$sfx~VKLtNnXP zl^)ySyok@otRy2y%SQs z*Vg6*ucr~PC7e&qv;s1qtixk2Oecs5P@flbbsZ{D{h`O8JVtFw;XF?9^q8VWM?s09 zr=aDSZm_DpvZB$L5mbuHm@nQ#?Nn|uR804wbHMb;gqcoa%;Zs19)6CQwL{o?bcU>R%3vRnN4s$jv9KTR3u)y>U=yeAPPPi|8Pp&N0Ze4kgR0 zo$$3Gay}*CQ;<_CC$r1XX%7fE5E{`v9ms}v1`MDG@FUU(bS8yKkUy$2jM@S}cvVZ^ zG=w-llEc8>9)@&5e&;LQAIJ=V_Jm+b1I`(bAArh7PTQ?vensKPHO)l6BYDUZ_=SO@ zKzheL$%T6WobEG#up|j(5`rKOp%bzo2mxVIO|l2+fILC_4{&X8J{LskpVP**;`z>&#RRJ}J(B{40!=Z;Tn@lkUx zs*|VYh&?;7_~}}op)}O-jvkm3;pO3z5?EXF5f+Xq9bkEwlHXOsF?{3B<@$3q{!hF9 zRBH16OKBc0rGL=#Nh2w$e1l$p2Tg@X*fU=&1;9x#bjHM5Bd0O(4HYd=r_f< ze9&HXCXeHhOfmYdhQKUBv3vqE=my0&ncytak&Pf5v{M|xDU?$#!6~#;AOSj*(;otK zXs1YmG$^MGg3bS_qR~pQ2I){sxCH6YOYjr4L->!12Kqk&8c3&b0(U5zgBgc11%$cP=H%`@44VrqR*v8k+79`^|D~Q=4o;3SN>UV zj*Osg5W>wy36;$YKq79oNX#Em2C2dXXO&>0&iD)P7MBrl>rfwj0ogwEs||FMzA^>T zUi1Wmz)lVQFWkoyA4jwLKqkRPtpkxHT-6q6!n6ri=(d~>8jik-6PqM&CHF7E`+Bx3 z$bn*8t^m&kJRw4SFgtO3zzlD!0?%E4e5^1%-LONp` zp0s|w%K19)^uXO=@;$Hsb-!czn*4@RB)~E zJ@&E8aQ$trW`?soqnU8u$`yt2uchiC1NvsPJ@>*Eg;)7jwDX^HHGx-j&1gqd;;wCD z++3SktyIx=f-xklamR_AYtGgC3Bdl~?1ZhATyT+iwU%vbR&s6J>-Sa32{rSsIV(xF z_`fYSDAxG4-%#?iV;W$7(A8>RaiCG+j-MRV5xe(l6ct5MWPaot)`>M*pCVPf8y9wY zCaxsfyw^!JNl7&u*Wen~Nj03;;9C1?=)ZqWUCFd{uRBp?TTfc$8{{NEPMf_xzFog- zG`|BY-U`vc8-wj}dqZ8xXCy0be!`Bjzfk+DshO!~ zsAjjIo6)x@K$eGXOd4(2m@8|l5c{|+IOA#j4|LjcMtm`0rxqGH&%^T*h+k2_J1t&VM> ztD*d{=UGH%?9FE$r#&T^$CAGZ`x}p5K4rc594WMHz#nT{>k^9h;ctp%;D8-OA60%Q zzQiVh2%;78wr4n5r`U=@zkeM1`j+gXL@UT3aVj5PUtXE$&Ggv;by46lYHe zy9CY;0;Ja@bOOBhd2=;*NHutPg$9+yWZqzyqVK13O?MiGfhauQCJn8FUNXr+%JSzgx2wvLJuK_Ix88GWc#k59jNtm1Sm`Yu;`Yk zn=jo@n;b0mc(0`9z0`hs-roA{d@jv-@3-;+kqvg!Z@Am|0TYmGL>5yB5b_`p@8e@Y zdau_xF1Wyd!VY26=c}Z1a)SdYoBFt^k)|YcU+b8s)u7A; zrdy_^b@99e3X|sbUhh~>nh=OU(0w8!Ac87kb2Zn`3O1RGg^s-d^zEv7JPOoZrsj4p z`3yc#<68b|o5zJqv(gPP-$ri$TtHX^-ju`s1>5+oaswL^n?+%+PIaoS#JNl8G-~w3#%-?tC+G2+$Gpuo zJg3Q8VwO9hDa#4$?*Jd??w^cD-Q=dM7v8l6r(--5U70(nHO6ziBR}3D<#68hDT5?X z2*|S*;A-%GpTfF738{7llgLc-M2SDxfNzJpvmf9ej=RWCIFWbqo|3mJAEYbi2y%J*c)>3t`MkP+c^>*= z9Z|o4LV;_;5%3aEBsb64VxEywK1nW3C!a;=Nnqnlm<;xa=DbMW$$30hW;GovID z&}7x{g+?!D+;LP`s37{V4QAd1$U0Ob=6IluWSiNll_LWR5NO5h%;w1xl53(d?^)v+d3BQu@i;M0nw(u<@rs-e@Z&`>WZR*2E0m|Kx@Dr*>xt{Co2)vmcL z$Ktv2qWWQ}gE#yRcI^^ez9#ef$Sex*L`>fu%;29W*1lsva^&TP4&IDq$OrOR0Yna1 z@2FVk_P8p`Xclg`kr}&bzG*bxm2G&Wc!}KerH}Uwa>+B=E@N4n*MMG(_=9O5@5eo^n<$(eRnTd_!5mS59?knTzh7n2(<;fMpTWvZ@kw^B$ z(3^X-iBHWP^A;jK_s8Q37NZ5M1XBIp?i#6t{#p-b*%p-c!rk!iJ}1ZA zewreufaIw__u~%5hk_%a-?aaZ!`t02-~U8FlCqHLM}8~z2k0nK`}6>X-@pqOza5f_ zGp&|cK)Y}E@w_W&T>lumd&*n)yf!Mz`m<7YR(bD}APmGf{vL4307BBkixYG2eCMJ2 z6dZcS8Hh3Y1)5^av*QC#J(lG`>qX&(U>|Zfn1w#tr@f3STp;4{W!gTbeRsDn`+@hu zW}Hp$BBAyBUcP{>kAXSoZu@PcyPOW~Zy zRUL8L@MFZ+W3Tk8j6=n6_c^NuZUI9gwn9MOeZ$5JEH?O;DI4E_(1WG-by@&|h_TZ` z0*xhLejFJ>GK2&uIF$QWYNZb;LnlUtY$*)In>R!yYr9!0VE0LUY{x-89-i8s2SWb9 zl5kfF@P`n$V)qxZgX|S}L=c8ZsVpsM|IN0SOM_n7Gu~F%sk%-XyLk#x@aYV7=rZL( zs?*iSwG*#MvPd^t<)zxYC=+e<`bo$GW(E?P5yfs`Nt#DQZ1_ZZT6sFRxFc>(uFa9& z`?fpRdwaI0&}?}tVR#7duiUQSKdsx^#GWhpeWx`AeWu|J-eh$5&BPN|>|>`pg?E%I ze>W4`-O)3^F-IyN$h_~acmgr(p}5K=BNRq>S8ZJIo9>$AOn@dW3$)`}ir#iAyLpD@ zSGc~l?XHmXHVD->MfL(**Blg&uO*+)FZ@@L2$q60AP@@h|93q7KLd^bT8abzv-^Jq z(*OU3)&EcE|1B`{{{aR7C=Q%}{=b0!Z-0*eN$|gg$^16~9OnNG!GA}~{7;7e&0FNZ e84S7q?-~B*OhCc@g9Y+$4Fd!K$npEn=>Gtjt+gNk literal 33125 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�rO!Jk3t}N0m9l2Ksp~i8H?sqK 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%0AnzTF82!^uYJ}S4w zNHY6Aj9AhneJ5@X?YF4MPb6m=MfL`#a+#;pDP%}tzyMj$(BCNw!})G?sd>~@}$S3&#*83WpCtz+>hW+ z+P?NoDD@BrGtD+@9NbcG)+hZ>x-n-i3g1`yrmDwcle?r?o=++o&Uig z^xYadvk8cQGDbGkUHhL20fm7C&>jIAW`uoy8Rs0}2J4C{ShzU@_=a!^y9WBHhQ$GgDKio zyH92_JxHV!?!BHYA>Kdd>CxwFCZf;h=`6ramq$8c#?Kfgd#FKW-N7bSs7k$EvWoZ& zwN;>{snVEaBHf_bSSoEp_*;ruWo=4%d{DH=@wOl5)vKkifBh|u4RO07ubIxM4_0AY zdvdiy1G){S=!C@R3Mqzw=?xFH=`qesS-QwCD>@>*08pHSWRUJ>6|GE{wW5nrAvE0=N$1q9G#A+MyU zH=8~Hn@j!|9K$9HF%;G{Wa69Gf_X-lok1~qaTo)fKfgkTBj3`$kJcU{8w}V^;vh}F z5KFQ!9gJ#g_!bNB5hZ=ds#o04_|5#AU}$Cb5(bYM%|}ogz{`@F_%uL7*9=$=H-%UONnusJ6*@5_#hc?!VL6fqSpisRTr zQ|!g*(?*wPn!4+E1^pq&_p(f?M z7t!TAAKhPITjN%&VKeql2=Z$PfJC(#GN7ONYFC-DTc^dE^8CAGRSWl`OpQ#wC!G< ze{mgzx((e88>4}ThO=j|vB+7cYfN37kx6o#@`Oj^HxRYNYY1xtEtj6naG^C*hkaiKI&s zA7vVFx)S0ahCSy0OP9<)?smvC#;*>T!>}RRmBFz)(n(vt4Bd3e{#J89O#~Onp~pT7 zif6h~5KwpH%l2?yyI~@_+Oz)>A8cb5Pu$6Ka`;Sg7R~He0n~e1Yti*aySZq1U`YE| z_zG7#YBoO->}@vOVgS8Ov25v|vjpzIuGqPkI&an8@ZyC<*^9m3mv_kC z&;VEJqmht%0wnZ%=vVAQ-LZFe!v&5oo-|vwHDMq7_{PHx=PJx&(r$H8Nhg(v@`JW5 zvi$P0M2cls7tClL9 z{&xRfsgb&uuG^=FNy`KmGeN-JXa?Y zFQa{sNslbZd_zuPhp6rl?w+x~8A2?g_xC%k2oVuT-Y^HN#vIG!0?A3Wl-w8n#TAc= zV~lSj?M`9V)=HaQarc@#WS4XJ=3nez=8~|a2;!{nzyZ`xE3;ke#B^q$pI$F}Iw!rw zI~&WqZ=kfoI@$s{QswSOQi|{PE91(A5*NWe^Dgq?IT|!Q=Nl{02|$`Ef1K8d1xOe| z!uMM2$rpMtx5|TuTM8z6e_SVg-DU=H>Xd0KTK)R2w%C>%J;rTWZM6#}A4Anb5jR3P zzdeSRPL5{%o6MME{<4^D`lguhYQ0+Up3Q$;R|EI? z4NkFpZBY)DUW=+cWZY{n6K01F-y9X(m}1E>rvv(=Jl6+;zz^+KJlv6d2nq~bNNt8A zF`{E(mp*f69PHWbi~$1^TLgB zX9hjuq7pc+?2w99s1L*Bn&>dSi8YZ6g(F8Q!DY<8o_KeRajA!(haw%zg={H6Z}nChK0jD<(XbF^dIXA@u(#cLl8+v?3F zlOSpO$7gaxZLivwA(VP18)O?nef7>^zR=G2T9eD(fhPfL5v>h={rVw7Q*4`pBH%K7 z7GEBQXw%-g(Y{$ev0ds{)Tl)_YnR|t%v&1NA)>g~C$I+KR?xA^+cs>t3#qQ=t!-X{ z9qA+2on1v<4n4%@khtX$Z#zH{^p0=qkG7Q2n(=~1M}9N+qGdbhOXM&w<#N}a0$nMZ z*PNxtM0DzzdST84M3FONT`IOLpO=w`IV(^G-&iMZyUOgudWX}e_qvuOrDWWs!uFMk(L)6_himJ{sPkt$@L8#=&Y3-7 ztGcvjcHId@w;V0V>ZamDfXSo@<7)$=@fY_Pdc%a?m0kZtAJW?rrVMGfL8?Rcv+oWS z^4R)|40k}V6^uUA-3C-HJF;HzZX55<=!?(1-69k+^%;Psz8H8KA?lDm@d{e)s+vdp z&o=lJ5+w_QbmS#8Dl@68BVPfvhBhXkN%dU9ptNuFCsKf$SxLJn8}Omb4IGeOW&J8N zj&vI0x&o`QQtm)=!|A)Z8quv}FswGxFefCF@1*;_CuDQ zi0kE8XmwhK{1Txo;fY;&@(sf|p;go^DOB6Vgpam+VsmQSr1p9K_J}sTCfA8xGk(I; zBscRLEBqBpd~0gCZpV9b#ZA1sS=ZXV-Fwq{(|HTH2~4jA+-h$q8hoWzMel5xeVM-6 zJ9Lh^|Bd$)^bX{o{RsaB`Ob0`OK=U@{pfmH-r$~0_)Y=C-|#gGo6~U%zK~bnKPrQ! zvX5xy7gqc_pl0SL_tzQl!LgxH<9lG?ZYrzbf__H?H}reJf6^~2Q-4UW^3NyWBdhF% zMDz)rzo-DEf95<_-SjWr@#rGY9yj3jVCvCeZ|bMl8FW%@%QBc2r$skuGVG~P^~rS7R@Z5D zENdNGS%AIF#o2XacJX-s5hZGRC`CPw}l_I z(n!zT&n4wq?>XKvPc1U82GjlHoXR!(x8b*$gWsso7k{AlOGf!BU!l3^ysiw-2kk1Gaxn~JUKX_CYLYvi7yNu-l? ztnYkB;p*GONu_1Ub18$q`3Yy^HP$LvOw%7l|FAU$>n~^Y4Dhe{m#JQDq%jZd6{`Fq zW6787rZoGey${u`LCDAWt&uoCd)ZkN0e9WwH^V3OrvWIMAR!MPS(58i>MPFB=lwOt zwK!``0gLy&7?Kp<0QA_9oEEfhzK?P)nHj4dIV6yN%RRML!97#jF6$HQ!zX#n`N;Yp zw<%ZX*BF^#f`xuSF1^wnS@Th4$&<66C8ukOe%{hPZ+kZN#PTR}haxra_84!_m2*ZC zYT^-N+AH`-ZIQS>p?~Yz-->H{=W|b+cRC_KY1(xM``E)kl)$(9$h?Kc67W)Kki^)F ztgPH?KZJE8g#-rPy{0$@et^5DF76O8=vKWege3JG4wt-|AGBcGo4n+R>j+4VA0}OW zLK=MuGZqE;kqE5;<(Kl|#xn=)EqD_!U$CAFxtHpIHWz+!_nNAw*|T#^JonD!SkNz( zQ+z(ZYoZ|U`zw*Y4W54fm6q#5`djz$^Gz1zGpsM^)k|5EN;bh!N-1`uIXPt=TV5z zT7n1aaP73vu}|RYUp{z0`ROKjDg$Oa_LDxTH;Z5~@H~jK+oqo1)0jE&rk3FB@!ts> zP&3;Vj*~YZpj#xzE%~pn6gJ#X@;Cwo!)b+%9F~5x1L(g|vh{2v~zDPy$M5Iw-ndWYKy-MK(Fm(cZV7nF6^HzweOekEFzhh3&qMG=9VEI~^CuhhG25}OsoF1uaM6~4#zkT^Ow2HQ z3)z4xi6OfFS}h? z4>{R=hSz_85kbmOS%Z#6nn31*xD6#VdXFMSLG6cqA9!58{CEk1p!?uM<>_~y!$Duy zmeDSvUO{TZct_A&@BO^DCw4FqF>rK0sJM|$Y7mb&v4(#G1GbYXh^cEl@G)s)Db**u zgDz6W3MK_7G%GFepGJoJLNlRn{g_(HxJk~NBm5;`Ys>FKD9w=#2A78n`8RrAl3(YS zD}_5uPRvF*zXq6U9zbMC648;e6{}-H#*4yVwGRV2v=G)sVLFHgax7KUhsYarm%>dN zab3?N;m{%W^?pNq3jWUG&KNxY9XVASl+N+&f?R?e8ueBl=v+|?DvMmwmdWb085&~h zP%uC&PL}1mzknl4gC@Pn$xJD2axjiCh&_obfx%9m7Cx5yRN@|Cf~AfqQ~=%-dG+ie zu?`yu75^l;+mu*@2*OM@ufus~+=r|<72)CVh*1z3b&#A+4#5mB%Gpp^q-Z!>uN0MCi~ zZP6bpa)9+h*Aj7$g>aAVp#BAmk6E`J20|lme$uYcQ1*}mlLxvE7s4>mxb*Uf4fX@N zL6CMml=XNSf@V+!J_xR%?y)8(sY(PO)%_yzca9X}*E%E!=CES*NBA2kEC&6N2g_?n zdk=ka5hUUUat8s&W4Q*2gG&~;JQGHb!>`}a1U~zPFeW>C%gs#5l86w$K`PMI-#oaz zE{WoVt&v0G8GdUSCZtPIk!yHRgZYvU2M195iKsE(o8fnaBqXv@#)=J~3l6@Z#Nimg zA-W!XE4G0QPMobwx(vj})D7~nT@S<# z7BT=yf|L*qGJy*(iz6rsS=yH-6G)4n;fL?L7T+{8AuiA%C^#g*C!Pqhd`pxOZY-0z z0?R(80j<}CW&)o#N#$!swnE+pc^$Lyg>X>+rTf!+bi$MMO&mc|M1d~3;>jYRR2)oS z;vCG*f)Q+zxTbnx*aNh=bmA{M&Hlsaj&;)I*biV?>iu~g#0MHazT}7)6NHY;0@FYq zYG_jm3S$uo3YH2d(ZjETT7)@nY|s)$=u>O{pn~%VeYZ*wR!AQ_15Kw8>41OY5KR6W z@#3osS=cXy5cZM{o=m~XMJ39gER6!7t9AqVAwkF5px*ieQ{-{$c|Mdc{wAbhMm@0> zp7~45K8FvXU`|vV+LTUBBpU@XIFs=B8hPRMwBsROUEOP@4=rZX;PuxuVh}QKi7&q% zz7^Ng|9(&Ieh-Kau?Oz!r*ygoALyopy;-$ZH9-aZQVlSvtg5Ppe3T&jTpp~4a-dgb zbA7T}!7n;ZASzJ0Q;yE>lHv@E4a(z##L2qR=oxNj7Abyb#>KkMQDd{ z=bJZuc{~%;UIvXVtLv*990LpXzS-`wkuZk7(A6~$#^TGRA zsB7VOS7BRT2F%Q?UffmHR*l*F5(rvT(^%udfIu5?t~gg!TZxa|3a#h7af`d!s+tZf zWMqAV+m|(2#WA-xZAN3AI4LSFyc9hY4HL{5o2pAMNFj1Me}t^U0#kIzd0JUVek3zM zOoYlO2NJP}C68NOaLVQtOro)QCXvgp9xKUaR!*8`@k%EntsVzJ6~J$lPTI{dX(!XL zb}A)Tvvz7FTeEt`k*`@f<&vLSIpvXKSv099U$S*7B;&EYBFpBLPlj8?y=M7jkTcBZ z$Y%8@Bx6}V7|H5YO-{4EO33m{CC9HG8}E!W%{T^;JCovMCYWs7QeIHqsJ?twl3!*~ zluTB$bt)%!Z?ge>ah-_(+lr@h%rmV*$^K=NpEe}UXFvHBj29`H>w-bEVssAkg7&ry+lG;C{&99Nbz;yQm>xc5hL<=4`yUvueB$tb zfpdxZfyIE^2{_A#9(k5=1wNB}BmTW?2)rigpWbFM_(VCiXN1@RTgT)=*b;J}gQ#{w z0k9$?s2CkVsX1cYB zpPl~Xep=dYfb&wRwga=4=MZcvQez+9hO7<9R|jA^O>Mu*B7m;eC+g{>xm0zofq(y> zq@Y*a6JInXr*(Q-pWuCzzLD>EQ)y$mraqRo*PHb=^*ar%<)3o&OMUd}A4q}S6-Mwf zP*++0&2t-Aw8CF&>dC)L;EC+&4W~S&lLGT zTFnZ(XRNHAb@JNA@e{jeu&iC(0v;a%^?%yfGq{AePwWEF@^*&(5-Uoz-20?aOc2d5Ut2IK`q1bx!Q$fED2RqJRnQQ zK->A*5Mj60`cWB-_lJw2{0n3eOQ`H4?Ep}O{SW#9-z%}{&?;`RGIH5@4!S9CzUvNluzU`sQ@zp=96?|Bw8vEIR1 z00jaHM)ZTd>DzMgo+edv=9-A0EjfY>v=n7-uBVw4rEcKmC&$ZqvtWYNE!DYt&2%d_ z=d`TylC3;EzNb|xTNQlMVvVy4r}Fn5{xOwD?GrZRw;BVLDQ5&Vak3glLNO9 z&aPFumpK-0Wt%&>$$&bQ?sDfQPpc}vb|5jZMa5h144q~1<}e>~=0>HvddYrF>H0NS zd1gsDu=6@EP;gk#dsff^x38ESr13yI8Y!NS%2?^GNpvb>QCj|fMlXO}hGVUCGb$ZJ zI+q3TRN0nfN`^Y1@phNn%UU`|T7XjAQVXDDF)NJ;4hGd}+kmN;{8Dt`InXJ+GSeUFg6hoklL;O65*!auy|wa~iZAszBIuvBPYCoywe}jh z#Y<51BxW-ZV^MqJ7Gx5u%vUs`eKNvq~y zFJEVcx-G>zx7{`n1Xvf4Rgq;M9_ws-fIN<87(NU*5rsdo!Mt|r@VpUEhI^^2J_R_7 zBbKQXC$h+98Km6Fnm;DkVd&cx;cTUB8#Wy-j0hCij+!#99Eao`BZfSQgJ`m65Bs_>j4+ToJIYhL%xP-@B1Z=*rnPc7t5WthB0m2p{ z1J`%M7-LLSx!D)l)w|Q~wNEk2FwCp?eu9$e`OgdH5cV^77ElHQ}XT z44N~Xoj_{;Bex@yUe00Ci>3k7fX$oSfD@2#p6apx0|+`ja~>#VK;WP*(jntc1$G&j zO0pe=)$S{0NjjtOCw1>f&!0?>k+08-s@v!KPs49CfvfMY@K1+qf2g;SkGYLCo8M>y zd>S~&ZUGitkiQNXuwmcV=Nv2DiQXZHv%C6*@PTgEh;qsIvHGbE2NSRn`Y52$e zfV_0zW_^Zqu|7QlFmgvX#w(KX+6k>R=W+f#81GOP;*I^~Q(knMPokwg+5{I#NcV~6 zeseB~=0B&B_moEkj&Ueh@xuaV_gn;T`c5bk;YY;rW5yq{OQz&VzfHmG3uJ;Xt|N8& zm|yobN0`1%ul6ZL7R~W?ZN6MBbL`A9*a5Vll9tRnA}$B35UJCgP5H;$AGkjEE%8 zGa+69egQWc1s4eCA+hIZ<4hSHrN(5PLfmpnY0@BsI*0*m;*g9UIdZl%J1QHbN2l9i zy~^*7?ua`5uvwl7Gn0r-Z*rq6u6gwr8n*rG1RqErh%<}UH5=DIQKJ;t-lxKfuhe! z;xKyR8*xna&YqHYJ?zz*f)WJH62?Dr$~Wqj`Q#0afpo@46k^f0RXx!ITFf+%a`QF< zRA*2Xo2gzg>d)yViLX>ievpWF!ns}I5gy5G_Qs#x;=?qO-S;7P)N$AiQQtjbZYOp5 zyK;kXP$9nV$K=3YiEtMkY_3pA9~gPm;$Q=8#moi92ju;)99*HO)7+-L(>*b}r*U#Px`WD!>(i+Kwqtc&D{|^D7lu0*0BE-zM|78Msr#5Gs1SJX2V6#az$^Rghb6hKa=?yYk`jKGYJ7%! zL=|`uXd`f`(fw|Hj@dFCj5f^W$_{8p^Oq03JHY50qUZLgQ9kWP9q^vo#*J%@^7cnh zjpBKw*ODIu5sho=Fu1@9Qe;b5CsFF*@aomvuCMIfGA^T^X(w2pf1Vm5Jmr}ICQt@6hz z#SyjqkZ2y4YKC^VR;*Irpf`?HK(bfrSwLJqv+>$`#w1C**%|LDX-5YVq@Yhf3Pvro zP6-9wfNTcdZIOK_IPgxie9W#dT=Jl@eSioF!9Kx)5J^C~{c3--BEp79xOM~~!d7yk zH8zcE%NReI4n|5PJJk;>`(B^2M#9?(tKt8x9(xvyj~elN7MeHQm-x^1NkzstSUiV_ zKt@C!R!lL#BS0T4_Vab#>1uRodw4$BBi{6DZR(OvQT<0KvmWd7G-)>kq5)8=u zI!}!404~(4%;5`qXQoKRurGd3!IHPHM%v<%cf~UV+#?^xImP3C9_yo~N9Ic&C5zq~ zkWRu37RZlBd9w5l^#n3n2nH^3uj9%Q8+cs7ecU1m*{dyoDEo=*7jUq@@UqJS9~(Jx z-t=2@9z^JuJn=DR63h?Gn-6f+Z!HriF6K-bJf*8AWF_mzd1_EU7D7C4;7%`pP0tLC zLaTtG-;mmcFjMY>1bCo8vh@Rq0?P<7iK`bGcHG{THHc^Gl(!8_lCf{@Zh>wrOp$m! zj#j;k`Xa{dCCd}GEUqoQl4kP_ot2n|ed*b{v4xyQNMQrQoX$N6KFXFHha88O@|YGs z&(2_PO)n5<+nVP&3Wv#9cS>Wf_l8tYbmUUyt}EJOhc5$bhVl8wsi@wwnRo7_=MF~( z->4Ueo+h5hgI9tRzO=s3xzkheL}J)|an&m)WX$lW(fHtp(R~T~{thPIXorT3f>Nq2 zml)#rfqMkcTyduzSgIfTY=!s>QF>rM$)|ukWr&!9G$GC*c#dynwvT?>;JzlH~JnX_O^zWb`1YV-+!!c{%7d_ z&5QKEp|k#h{U5jg|AqdqHpu@3_}~0`{tK{%{eJ`SU-zE>iSWPan*0|5h4=p+;eWmf VB-DRmLHt|8{`nD2`v0f({{R`').append($('').text(from), msg)); +} diff --git a/static/js/com.podnoms.utils.js b/static/js/com.podnoms.utils.js index f4b83cc..b91e68b 100644 --- a/static/js/com.podnoms.utils.js +++ b/static/js/com.podnoms.utils.js @@ -63,6 +63,11 @@ com.podnoms.utils = { this.hideAlert(); }); }, + showAlertModal: function(title, message){ + $('#alert-proxy-title').text(title); + $('#alert-proxy-message').html(message); + $('#alert-proxy').modal(); + }, hideAlert: function () { $('.alert').fadeOut('slow', function () { }); @@ -93,6 +98,20 @@ com.podnoms.utils = { return v.toString(16); }); }, + checkPlayCount: function(){ + if (document.cookie.indexOf('sessionId')){ + $.getJSON('/ajax/session_play_count', function (data) { + if ((data.play_count % 5) == 0){ + com.podnoms.utils.showAlertModal( + "Hey There!", + "We've noticed you've been playing a few mixes now.
" + + "This is cool and we're happy you're enjoying the site but we would love it " + + "if you would consider logging in.
" + + "This will let you comment on mixes and even download them."); + } + }); + } + }, downloadURL: function downloadURL(url) { var iframe; iframe = document.getElementById("hiddenDownloader"); diff --git a/static/js/libs/sm/soundmanager2-jsmin.js b/static/js/libs/sm/soundmanager2-jsmin.js index 2f52e5f..c7987c1 100644 --- a/static/js/libs/sm/soundmanager2-jsmin.js +++ b/static/js/libs/sm/soundmanager2-jsmin.js @@ -9,102 +9,98 @@ Code provided under the BSD License: http://schillmania.com/projects/soundmanager2/license.txt - V2.97a.20120916 + V2.97a.20130101 */ -(function(Z){function $($,oa){function aa(a){return c.preferFlash&&z&&!c.ignoreFlash&&"undefined"!==typeof c.flash[a]&&c.flash[a]}function q(a){return function(d){var e=this._t;!e||!e._a?(e&&e.id?c._wD(s+"ignoring "+d.type+": "+e.id):c._wD(s+"ignoring "+d.type),d=null):d=a.call(this,d);return d}}this.setupOptions={url:$||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null, -flashLoadTimeout:1E3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0,html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options= -{isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"], -required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID="sm2-container";this.id=oa||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20120916";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i}; -this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null};var pa;try{pa="undefined"!==typeof Audio&&"undefined"!==typeof(qa&&10>opera.version()?new Audio(null):new Audio).canPlayType}catch(ib){pa= -!1}this.hasHTML5=pa;this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=!1;var Ka,c=this,h=null,s="HTML5::",A,v=navigator.userAgent,k=Z,Q=k.location.href.toString(),i=document,ra,La,sa,j,D=[],ta=!0,x,R=!1,S=!1,m=!1,o=!1,ba=!1,n,eb=0,T,w,ua,H,va,I,J,K,Ma,wa,ca,da,ea,L,xa,U,fa,ga,M,Na,ya,fb=["log","info","warn","error"],Oa,ha,Pa,V=null,za=null,p,Aa,N,Qa,ia,ja,O,t,W=!1,Ba=!1,Ra,Sa,Ta,ka=0,X=null,la,B=null,Ua,ma,Y,E,Ca,Da,Va,u,Wa=Array.prototype.slice,G=!1,z,Ea,Xa,C,Ya,Fa=v.match(/(ipad|iphone|ipod)/i), -F=v.match(/msie/i),gb=v.match(/webkit/i),Ga=v.match(/safari/i)&&!v.match(/chrome/i),qa=v.match(/opera/i),Ha=v.match(/(mobile|pre\/|xoom)/i)||Fa,Ia=!Q.match(/usehtml5audio/i)&&!Q.match(/sm2\-ignorebadua/i)&&Ga&&!v.match(/silk/i)&&v.match(/OS X 10_6_([3-7])/i),Za="undefined"!==typeof console&&"undefined"!==typeof console.log,Ja="undefined"!==typeof i.hasFocus?i.hasFocus():null,na=Ga&&("undefined"===typeof i.hasFocus||!i.hasFocus()),$a=!na,ab=/(mp3|mp4|mpa|m4a|m4b)/i,P=i.location?i.location.protocol.match(/http/i): -null,bb=!P?"http://":"",cb=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,db="mpeg4,aac,flv,mov,mp4,m4v,f4v,m4a,m4b,mp4v,3gp,3g2".split(","),hb=RegExp("\\.("+db.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!P;this._global_a=null;if(Ha&&(c.useHTML5Audio=!0,c.preferFlash=!1,Fa))G=c.ignoreFlash=!0;this.setup=function(a){var d=!c.url;"undefined"!==typeof a&&m&&B&&c.ok()&&("undefined"!==typeof a.flashVersion|| -"undefined"!==typeof a.url)&&O(p("setupLate"));ua(a);d&&U&&"undefined"!==typeof a.url&&c.beginDelayedInit();!U&&"undefined"!==typeof a.url&&"complete"===i.readyState&&setTimeout(L,1);return c};this.supported=this.ok=function(){return B?m&&!o:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return A(c)||i[c]||k[c]};this.createSound=function(a,d){function e(){g=ia(g);c.sounds[f.id]=new Ka(f);c.soundIDs.push(f.id);return c.sounds[f.id]}var b,g=null,f=b=null;b="soundManager.createSound(): "+p(!m? -"notReady":"notOK");if(!m||!c.ok())return O(b),!1;"undefined"!==typeof d&&(a={id:a,url:d});g=w(a);g.url=la(g.url);f=g;f.id.toString().charAt(0).match(/^[0-9]$/)&&c._wD("soundManager.createSound(): "+p("badID",f.id),2);c._wD("soundManager.createSound(): "+f.id+" ("+f.url+")",1);if(t(f.id,!0))return c._wD("soundManager.createSound(): "+f.id+" exists",1),c.sounds[f.id];if(ma(f))b=e(),c._wD("Creating sound "+f.id+", using HTML5"),b._setup_html5(f);else{if(8=a)return!1;for(a-=1;0<=a;a--)if(c=y[a],!c.fired&&b.position>=c.position)c.fired=!0,q++,c.method.apply(c.scope,[c.position]);return!0};this._resetOnPosition=function(b){var a,c;a=y.length;if(!a)return!1;for(a-=1;0<=a;a--)if(c=y[a],c.fired&&b<=c.position)c.fired=!1,q--; -return!0};v=function(){var a=b._iO,d=a.from,e=a.to,f,g;g=function(){c._wD(b.id+': "to" time of '+e+" reached.");b.clearOnPosition(e,g);b.stop()};f=function(){c._wD(b.id+': playing "from" '+d);if(null!==e&&!isNaN(e))b.onPosition(e,g)};if(null!==d&&!isNaN(d))a.position=d,a.multiShot=!1,f();return a};k=function(){var a,c=b._iO.onposition;if(c)for(a in c)if(c.hasOwnProperty(a))b.onPosition(parseInt(a,10),c[a])};u=function(){var a,c=b._iO.onposition;if(c)for(a in c)c.hasOwnProperty(a)&&b.clearOnPosition(parseInt(a, -10))};i=function(){b.isHTML5&&Ra(b)};l=function(){b.isHTML5&&Sa(b)};g=function(a){a||(y=[],q=0);m=!1;b._hasTimer=null;b._a=null;b._html5_canplay=!1;b.bytesLoaded=null;b.bytesTotal=null;b.duration=b._iO&&b._iO.duration?b._iO.duration:null;b.durationEstimate=null;b.buffered=[];b.eqData=[];b.eqData.left=[];b.eqData.right=[];b.failures=0;b.isBuffering=!1;b.instanceOptions={};b.instanceCount=0;b.loaded=!1;b.metadata={};b.readyState=0;b.muted=!1;b.paused=!1;b.peakData={left:0,right:0};b.waveformData={left:[], -right:[]};b.playState=0;b.position=null;b.id3={}};g();this._onTimer=function(a){var c,f=!1,g={};if(b._hasTimer||a){if(b._a&&(a||(0opera.version()?new Audio(null):new Audio,e=b._a,e._called_load=!1,G)c._global_a=e;b.isHTML5=!0;b._a=e;e._t=b;f();b._apply_loop(e,a.loops);a.autoLoad||a.autoPlay?b.load():(e.autobuffer=!1,e.preload="auto");return e};f=function(){if(b._a._added_events)return!1;var a;b._a._added_events=!0;for(a in C)C.hasOwnProperty(a)&&b._a&&b._a.addEventListener(a,C[a],!1); -return!0};r=function(){var a;c._wD(s+"removing event listeners: "+b.id);b._a._added_events=!1;for(a in C)C.hasOwnProperty(a)&&b._a&&b._a.removeEventListener(a,C[a],!1)};this._onload=function(a){a=!!a||!b.isHTML5&&8===j&&b.duration;c._wD('SMSound._onload(): "'+b.id+'"'+(a?" loaded.":" failed to load? - "+b.url),a?1:2);!a&&!b.isHTML5&&(!0===c.sandbox.noRemote&&c._wD("SMSound._onload(): "+p("noNet"),1),!0===c.sandbox.noLocal&&c._wD("SMSound._onload(): "+p("noLocal"),1));b.loaded=a;b.readyState=a?3:2; -b._onbufferchange(0);b._iO.onload&&b._iO.onload.apply(b,[a]);return!0};this._onbufferchange=function(a){if(0===b.playState||a&&b.isBuffering||!a&&!b.isBuffering)return!1;b.isBuffering=1===a;b._iO.onbufferchange&&(c._wD("SMSound._onbufferchange(): "+a),b._iO.onbufferchange.apply(b));return!0};this._onsuspend=function(){b._iO.onsuspend&&(c._wD("SMSound._onsuspend()"),b._iO.onsuspend.apply(b));return!0};this._onfailure=function(a,d,e){b.failures++;c._wD('SMSound._onfailure(): "'+b.id+'" count '+b.failures); -if(b._iO.onfailure&&1===b.failures)b._iO.onfailure(b,a,d,e);else c._wD("SMSound._onfailure(): ignoring")};this._onfinish=function(){var a=b._iO.onfinish;b._onbufferchange(0);b._resetOnPosition(0);if(b.instanceCount){b.instanceCount--;if(!b.instanceCount&&(u(),b.playState=0,b.paused=!1,b.instanceCount=0,b.instanceOptions={},b._iO={},l(),b.isHTML5))b.position=0;if((!b.instanceCount||b._iO.multiShotEvents)&&a)c._wD('SMSound._onfinish(): "'+b.id+'"'),a.apply(b)}};this._whileloading=function(a,c,d,e){var f= -b._iO;b.bytesLoaded=a;b.bytesTotal=c;b.duration=Math.floor(d);b.bufferLength=e;b.durationEstimate=!b.isHTML5&&!f.isMovieStar?f.duration?b.duration>f.duration?b.duration:f.duration:parseInt(b.bytesTotal/b.bytesLoaded*b.duration,10):b.duration;if(!b.isHTML5)b.buffered=[{start:0,end:b.duration}];(3!==b.readyState||b.isHTML5)&&f.whileloading&&f.whileloading.apply(b)};this._whileplaying=function(a,c,d,e,f){var g=b._iO;if(isNaN(a)||null===a)return!1;b.position=Math.max(0,a);b._processOnPosition();if(!b.isHTML5&& -8opera.version()?new Audio(null): -new Audio:null,e,b,g={},f;f=c.audioFormats;for(e in f)if(f.hasOwnProperty(e)&&(b="audio/"+e,g[e]=a(f[e].type),g[b]=g[e],e.match(ab)?(c.flash[e]=!0,c.flash[b]=!0):(c.flash[e]=!1,c.flash[b]=!1),f[e]&&f[e].related))for(b=f[e].related.length-1;0<=b;b--)g["audio/"+f[e].related[b]]=g[e],c.html5[f[e].related[b]]=g[e],c.flash[f[e].related[b]]=g[e];g.canPlayType=d?a:null;c.html5=w(c.html5,g);return!0};da={notReady:"Not loaded yet - wait for soundManager.onready()",notOK:"Audio support is not available.",domError:"soundManager::createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.", -spcWmode:"soundManager::createMovie(): Removing wmode, preventing known SWF loading issue(s)",swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+i.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/", -waitFocus:"soundManager: Special case: Waiting for SWF to load with window focus...",waitImpatient:"soundManager: Getting impatient, still waiting for Flash%s...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",waitSWF:"soundManager: Retrying, waiting for 100% SWF load...",needFunction:"soundManager: Function object expected for %s",badID:'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:"--- soundManager._debug(): Current sound objects ---", -waitEI:"soundManager::initMovie(): Waiting for ExternalInterface call from Flash...",waitOnload:"soundManager: Waiting for window.onload()",docLoaded:"soundManager: Document already loaded",onload:"soundManager::initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",init:"soundManager::init()",didInit:"soundManager::init(): Already called?",flashJS:"soundManager: Attempting JS to Flash call...",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", -badRemove:"Warning: Failed to remove flash movie.",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager: Queueing %s handler",smFail:"soundManager: Failed to initialise.",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying .swf_timedout CSS...",fbLoaded:"Flash loaded",fbHandler:"soundManager::flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:"soundManager.load(): current URL already assigned.", +(function(j,g){function aa(aa,pa){function ba(a){return c.preferFlash&&z&&!c.ignoreFlash&&c.flash[a]!==g&&c.flash[a]}function q(a){return function(d){var e=this._s;!e||!e._a?(e&&e.id?c._wD(e.id+": Ignoring "+d.type):c._wD(pb+"Ignoring "+d.type),d=null):d=a.call(this,d);return d}}this.setupOptions={url:aa||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3, +wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0,html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null,usePeakData:!1, +useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},wav:{type:['audio/wav; codecs="1"', +"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID="sm2-container";this.id=pa||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20130101";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:!1,peakData:!1,waveformData:!1, +eqData:!1,movieStar:!1};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null};this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=!1;var Pa,c=this,Qa=null,i=null,pb="HTML5::",A,s=navigator.userAgent,R=j.location.href.toString(), +h=document,qa,Ra,ra,l,C=[],sa=!0,x,S=!1,T=!1,n=!1,r=!1,ca=!1,k,qb=0,U,v,ta,K,ua,I,L,M,Sa,va,da,F,ea,wa,N,xa,V,fa,ga,O,Ta,ya,Ua=["log","info","warn","error"],Va,za,Wa,W=null,Aa=null,p,Ba,P,Xa,ha,ia,Q,t,X=!1,Ca=!1,Ya,Za,$a,ja=0,Y=null,ka,J=[],B=null,ab,la,Z,G,Da,Ea,bb,u,cb=Array.prototype.slice,D=!1,Fa,z,Ga,db,E,eb,Ha,ma=s.match(/(ipad|iphone|ipod)/i),fb=s.match(/android/i),H=s.match(/msie/i),rb=s.match(/webkit/i),Ia=s.match(/safari/i)&&!s.match(/chrome/i),Ja=s.match(/opera/i),Ka=s.match(/(mobile|pre\/|xoom)/i)|| +ma||fb,La=!R.match(/usehtml5audio/i)&&!R.match(/sm2\-ignorebadua/i)&&Ia&&!s.match(/silk/i)&&s.match(/OS X 10_6_([3-7])/i),gb=j.console!==g&&console.log!==g,Ma=h.hasFocus!==g?h.hasFocus():null,na=Ia&&(h.hasFocus===g||!h.hasFocus()),hb=!na,ib=/(mp3|mp4|mpa|m4a|m4b)/i,$=h.location?h.location.protocol.match(/http/i):null,jb=!$?"http://":"",kb=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,lb="mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "),sb=RegExp("\\.("+ +lb.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!$;var Na;try{Na=Audio!==g&&(Ja&&opera!==g&&10>opera.version()?new Audio(null):new Audio).canPlayType!==g}catch(ub){Na=!1}this.hasHTML5=Na;this.setup=function(a){var d=!c.url;a!==g&&(n&&B&&c.ok()&&(a.flashVersion!==g||a.url!==g||a.html5Test!==g))&&Q(p("setupLate"));ta(a);d&&(V&&a.url!==g)&&c.beginDelayedInit();!V&&(a.url!==g&&"complete"===h.readyState)&&setTimeout(N,1);return c};this.supported= +this.ok=function(){return B?n&&!r:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return A(c)||h[c]||j[c]};this.createSound=function(a,d){function e(){f=ha(f);c.sounds[f.id]=new Pa(f);c.soundIDs.push(f.id);return c.sounds[f.id]}var b,f;b=null;b="soundManager.createSound(): "+p(!n?"notReady":"notOK");if(!n||!c.ok())return Q(b),!1;d!==g&&(a={id:a,url:d});f=v(a);f.url=ka(f.url);f.id.toString().charAt(0).match(/^[0-9]$/)&&c._wD("soundManager.createSound(): "+p("badID",f.id),2);c._wD("soundManager.createSound(): "+ +f.id+" ("+f.url+")",1);if(t(f.id,!0))return c._wD("soundManager.createSound(): "+f.id+" exists",1),c.sounds[f.id];la(f)?(b=e(),c._wD(f.id+": Using HTML5"),b._setup_html5(f)):(8=a)return!1;for(a-=1;0<=a;a--)c=y[a],!c.fired&&b.position>=c.position&&(c.fired=!0,s++,c.method.apply(c.scope,[c.position]));return!0};this._resetOnPosition=function(b){var a,c;a=y.length;if(!a)return!1;for(a-=1;0<=a;a--)c=y[a],c.fired&&b<=c.position&&(c.fired=!1,s--);return!0};u=function(){var a=b._iO,d=a.from,e=a.to,f,g;g=function(){c._wD(b.id+': "To" time of '+e+" reached.");b.clearOnPosition(e,g);b.stop()};f=function(){c._wD(b.id+': Playing "from" '+d);if(null!== +e&&!isNaN(e))b.onPosition(e,g)};null!==d&&!isNaN(d)&&(a.position=d,a.multiShot=!1,f());return a};n=function(){var a,c=b._iO.onposition;if(c)for(a in c)if(c.hasOwnProperty(a))b.onPosition(parseInt(a,10),c[a])};Oa=function(){var a,c=b._iO.onposition;if(c)for(a in c)c.hasOwnProperty(a)&&b.clearOnPosition(parseInt(a,10))};h=function(){b.isHTML5&&Ya(b)};m=function(){b.isHTML5&&Za(b)};f=function(a){a||(y=[],s=0);q=!1;b._hasTimer=null;b._a=null;b._html5_canplay=!1;b.bytesLoaded=null;b.bytesTotal=null;b.duration= +b._iO&&b._iO.duration?b._iO.duration:null;b.durationEstimate=null;b.buffered=[];b.eqData=[];b.eqData.left=[];b.eqData.right=[];b.failures=0;b.isBuffering=!1;b.instanceOptions={};b.instanceCount=0;b.loaded=!1;b.metadata={};b.readyState=0;b.muted=!1;b.paused=!1;b.peakData={left:0,right:0};b.waveformData={left:[],right:[]};b.playState=0;b.position=null;b.id3={}};f();this._onTimer=function(a){var c,f=!1,g={};if(b._hasTimer||a){if(b._a&&(a||(0opera.version()?new Audio(null):new Audio,d=b._a,d._called_load=!1,D&&(Qa=d);b.isHTML5=!0;b._a=d;d._s=b;j();b._apply_loop(d,a.loops);a.autoLoad||a.autoPlay?b.load():(d.autobuffer=!1,d.preload="auto");return d};j=function(){if(b._a._added_events)return!1; +var a;b._a._added_events=!0;for(a in E)E.hasOwnProperty(a)&&b._a&&b._a.addEventListener(a,E[a],!1);return!0};mb=function(){var a;c._wD(b.id+": Removing event listeners");b._a._added_events=!1;for(a in E)E.hasOwnProperty(a)&&b._a&&b._a.removeEventListener(a,E[a],!1)};this._onload=function(a){var d=!!a||!b.isHTML5&&8===l&&b.duration,a=b.id+": ";c._wD(a+(d?"onload()":"Failed to load? - "+b.url),d?1:2);!d&&!b.isHTML5&&(!0===c.sandbox.noRemote&&c._wD(a+p("noNet"),1),!0===c.sandbox.noLocal&&c._wD(a+p("noLocal"), +1));b.loaded=d;b.readyState=d?3:2;b._onbufferchange(0);b._iO.onload&&b._iO.onload.apply(b,[d]);return!0};this._onbufferchange=function(a){if(0===b.playState||a&&b.isBuffering||!a&&!b.isBuffering)return!1;b.isBuffering=1===a;b._iO.onbufferchange&&(c._wD(b.id+": Buffer state change: "+a),b._iO.onbufferchange.apply(b));return!0};this._onsuspend=function(){b._iO.onsuspend&&(c._wD(b.id+": Playback suspended"),b._iO.onsuspend.apply(b));return!0};this._onfailure=function(a,d,e){b.failures++;c._wD(b.id+": Failures = "+ +b.failures);if(b._iO.onfailure&&1===b.failures)b._iO.onfailure(b,a,d,e);else c._wD(b.id+": Ignoring failure")};this._onfinish=function(){var a=b._iO.onfinish;b._onbufferchange(0);b._resetOnPosition(0);if(b.instanceCount&&(b.instanceCount--,b.instanceCount||(Oa(),b.playState=0,b.paused=!1,b.instanceCount=0,b.instanceOptions={},b._iO={},m(),b.isHTML5&&(b.position=0)),(!b.instanceCount||b._iO.multiShotEvents)&&a))c._wD(b.id+": onfinish()"),a.apply(b)};this._whileloading=function(a,c,d,e){var f=b._iO; +b.bytesLoaded=a;b.bytesTotal=c;b.duration=Math.floor(d);b.bufferLength=e;b.durationEstimate=!b.isHTML5&&!f.isMovieStar?f.duration?b.duration>f.duration?b.duration:f.duration:parseInt(b.bytesTotal/b.bytesLoaded*b.duration,10):b.duration;b.isHTML5||(b.buffered=[{start:0,end:b.duration}]);(3!==b.readyState||b.isHTML5)&&f.whileloading&&f.whileloading.apply(b)};this._whileplaying=function(a,c,d,e,f){var m=b._iO;if(isNaN(a)||null===a)return!1;b.position=Math.max(0,a);b._processOnPosition();!b.isHTML5&& +8opera.version()?new Audio(null):new Audio:null,e,b,f={},h;h=c.audioFormats;for(e in h)if(h.hasOwnProperty(e)&&(b="audio/"+e,f[e]=a(h[e].type),f[b]=f[e],e.match(ib)?(c.flash[e]=!0,c.flash[b]=!0):(c.flash[e]=!1,c.flash[b]=!1),h[e]&&h[e].related))for(b=h[e].related.length-1;0<=b;b--)f["audio/"+h[e].related[b]]=f[e],c.html5[h[e].related[b]]=f[e],c.flash[h[e].related[b]]=f[e];f.canPlayType=d?a:null;c.html5= +v(c.html5,f);return!0};F={notReady:"Unavailable - wait until onready() has fired.",notOK:"Audio support is not available.",domError:"soundManagerexception caught while appending SWF to DOM.",spcWmode:"Removing wmode, preventing known SWF loading issue(s)",swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+h.location.protocol+ +" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/",waitFocus:"soundManager: Special case: Waiting for SWF to load with window focus...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",waitSWF:"soundManager: Waiting for 100% SWF load...",needFunction:"soundManager: Function object expected for %s", +badID:'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:"soundManager: _debug(): Current sound objects",waitOnload:"soundManager: Waiting for window.onload()",docLoaded:"soundManager: Document already loaded",onload:"soundManager: initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",didInit:"soundManager: init(): Already called?",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", +badRemove:"soundManager: Failed to remove Flash node.",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager: Queueing %s handler",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying .swf_timedout CSS...",fbLoaded:"Flash loaded",flRemoved:"soundManager: Flash movie removed.",fbHandler:"soundManager: flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:"soundManager.load(): current URL already assigned.", badFV:'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats",needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case",needFlash:"soundManager: Fatal error: Flash is needed to play some required formats, but is not available.",gotFocus:"soundManager: Got window focus.", -mfOn:"mobileFlash::enabling on-screen flash repositioning",policy:"Enabling usePolicyFile for data access",setup:"soundManager.setup(): allowed parameters: %s",setupError:'soundManager.setup(): "%s" cannot be assigned with this method.',setupUndef:'soundManager.setup(): Could not find option "%s"',setupLate:"soundManager.setup(): url + flashVersion changes will not take effect until reboot().",h5a:"creating HTML5 Audio() object",noURL:"soundManager: Flash URL required. Call soundManager.setup({url:...}) to get started."}; -p=function(){var a=Wa.call(arguments),c=a.shift(),c=da&&da[c]?da[c]:"",e,b;if(c&&a&&a.length)for(e=0,b=a.length;ej)c._wD(p("needfl9")),c.flashVersion=j=9;c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===j?" (AS3/Flash 9)":" (AS2/Flash 8)");8'}if(R&&S)return!1;if(c.html5Only)return wa(),e(),c.oMC=A(c.movieID),sa(),S=R=!0,!1;var g=d||c.url,f=c.altURL||g,h=fa(),l=N(),k=null,k=i.getElementsByTagName("html")[0],j,o,m,k=k&&k.dir&&k.dir.match(/rtl/i),a="undefined"===typeof a?c.id:a;wa();c.url=Pa(P?g:f);d=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(null!== -c.wmode&&(v.match(/msie 8/i)||!F&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))n("spcWmode"),c.wmode=null;h={name:a,id:a,src:d,quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:bb+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};if(c.debugFlash)h.FlashVars="debug=1";c.wmode||delete h.wmode;if(F)g=i.createElement("div"),o=['',b("movie",d),b("AllowScriptAccess",c.allowScriptAccess),b("quality",h.quality),c.wmode?b("wmode",c.wmode):"",b("bgcolor",c.bgColor),b("hasPriority","true"),c.debugFlash?b("FlashVars",h.FlashVars):"",""].join("");else for(j in g=i.createElement("embed"),h)h.hasOwnProperty(j)&&g.setAttribute(j, -h[j]);ya();l=N();if(h=fa())if(c.oMC=A(c.movieID)||i.createElement("div"),c.oMC.id){m=c.oMC.className;c.oMC.className=(m?m+" ":"movieContainer")+(l?" "+l:"");c.oMC.appendChild(g);if(F)j=c.oMC.appendChild(i.createElement("div")),j.className="sm2-object-box",j.innerHTML=o;S=!0}else{c.oMC.id=c.movieID;c.oMC.className="movieContainer "+l;j=l=null;if(!c.useFlashBlock)if(c.useHighPerformance)l={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else if(l={position:"absolute", -width:"6px",height:"6px",top:"-9999px",left:"-9999px"},k)l.left=Math.abs(parseInt(l.left,10))+"px";if(gb)c.oMC.style.zIndex=1E4;if(!c.debugFlash)for(m in l)l.hasOwnProperty(m)&&(c.oMC.style[m]=l[m]);try{F||c.oMC.appendChild(g);h.appendChild(c.oMC);if(F)j=c.oMC.appendChild(i.createElement("div")),j.className="sm2-object-box",j.innerHTML=o;S=!0}catch(q){throw Error(p("domError")+" \n"+q.toString());}}R=!0;e();c._wD("soundManager::createMovie(): Trying to load "+d+(!P&&c.altURL?" (alternate URL)":""), -1);return!0};ea=function(){if(c.html5Only)return ga(),!1;if(h)return!1;if(!c.url)return n("noURL"),!1;h=c.getMovie(c.id);if(!h)V?(F?c.oMC.innerHTML=za:c.oMC.appendChild(V),V=null,R=!0):ga(c.id,c.url),h=c.getMovie(c.id);h&&n("waitEI");"function"===typeof c.oninitmovie&&setTimeout(c.oninitmovie,1);return!0};K=function(){setTimeout(Ma,1E3)};Ma=function(){var a,d=!1;if(!c.url||W)return!1;W=!0;u.remove(k,"load",K);if(na&&!Ja)return n("waitFocus"),!1;m||(a=c.getMoviePercent(),c._wD(p("waitImpatient",0< -a?" (SWF "+a+"% loaded)":"")),0a&&(d=!0));setTimeout(function(){a=c.getMoviePercent();if(d)return W=!1,c._wD(p("waitSWF")),k.setTimeout(K,1),!1;m||(c._wD("soundManager: No Flash response within expected time.\nLikely causes: "+(0===a?"Loading "+c.movieURL+" may have failed (and/or Flash "+j+"+ not present?), ":"")+"Flash blocked or JS-Flash security error."+(c.debugFlash?" "+p("checkSWF"):""),2),!P&&a&&(n("localFail",2),c.debugFlash||n("tryDebug",2)),0===a&&c._wD(p("swf404",c.url)),x("flashtojs", -!1,": Timed out"+P?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)"));!m&&$a&&(null===a?c.useFlashBlock||0===c.flashLoadTimeout?(c.useFlashBlock&&Aa(),n("waitForever")):ha(!0):0===c.flashLoadTimeout?n("waitForever"):ha(!0))},c.flashLoadTimeout)};ca=function(){if(Ja||!na)return u.remove(k,"focus",ca),!0;Ja=$a=!0;n("gotFocus");W=!1;K();u.remove(k,"focus",ca);return!0};Ya=function(){var a,d=[];if(c.useHTML5Audio&&c.hasHTML5){for(a in c.audioFormats)c.audioFormats.hasOwnProperty(a)&& -d.push(a+": "+c.html5[a]+(!c.html5[a]&&z&&c.flash[a]?" (using flash)":c.preferFlash&&c.flash[a]&&z?" (preferring flash)":!c.html5[a]?" ("+(c.audioFormats[a].required?"required, ":"")+"and no flash support)":""));c._wD("-- SoundManager 2: HTML5 support tests ("+c.html5Test+"): "+d.join(", ")+" --",1)}};T=function(a){if(m)return!1;if(c.html5Only)return c._wD("-- SoundManager 2: loaded --"),m=!0,J(),x("onload",!0),!0;var d=!0,e;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())m=!0,o&&(e= -{type:!z&&B?"NO_FLASH":"INIT_TIMEOUT"});c._wD("-- SoundManager 2 "+(o?"failed to load":"loaded")+" ("+(o?"Flash security/load error":"OK")+") --",1);if(o||a){if(c.useFlashBlock&&c.oMC)c.oMC.className=N()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error");I({type:"ontimeout",error:e,ignoreInit:!0});x("onload",!1);M(e);d=!1}else x("onload",!0);o||(c.waitForWindowLoad&&!ba?(n("waitOnload"),u.add(k,"load",J)):(c.waitForWindowLoad&&ba&&n("docLoaded"),J()));return d};La=function(){var a,d=c.setupOptions; -for(a in d)d.hasOwnProperty(a)&&("undefined"===typeof c[a]?c[a]=d[a]:c[a]!==d[a]&&(c.setupOptions[a]=c[a]))};sa=function(){n("init");if(m)return n("didInit"),!1;if(c.html5Only){if(!m)u.remove(k,"load",c.beginDelayedInit),c.enabled=!0,T();return!0}ea();try{n("flashJS"),h._externalInterfaceTest(!1),Na(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||h._disableDebug(),c.enabled=!0,x("jstoflash",!0),c.html5Only||u.add(k,"unload",ra)}catch(a){return c._wD("js/flash exception: "+a.toString()), -x("jstoflash",!1),M({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),ha(!0),T(),!1}T();u.remove(k,"load",c.beginDelayedInit);return!0};L=function(){if(U)return!1;U=!0;La();ya();var a=null,a=null,d="undefined"!==typeof console&&"function"===typeof console.log,e=Q.toLowerCase();-1!==e.indexOf("sm2-usehtml5audio=")&&(a="1"===e.charAt(e.indexOf("sm2-usehtml5audio=")+18),d&&console.log((a?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter"),c.setup({useHTML5Audio:a}));-1!==e.indexOf("sm2-preferflash=")&& -(a="1"===e.charAt(e.indexOf("sm2-preferflash=")+16),d&&console.log((a?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),c.setup({preferFlash:a}));!z&&c.hasHTML5&&(c._wD("SoundManager: No Flash detected"+(!c.useHTML5Audio?", enabling HTML5.":". Trying HTML5-only mode.")),c.setup({useHTML5Audio:!0,preferFlash:!1}));Va();c.html5.usingFlash=Ua();B=c.html5.usingFlash;Ya();!z&&B&&(n("needFlash"),c.setup({flashLoadTimeout:1}));i.removeEventListener&&i.removeEventListener("DOMContentLoaded",L,!1); -ea();return!0};Da=function(){"complete"===i.readyState&&(L(),i.detachEvent("onreadystatechange",Da));return!0};xa=function(){ba=!0;u.remove(k,"load",xa)};Ea();u.add(k,"focus",ca);u.add(k,"load",K);u.add(k,"load",xa);i.addEventListener?i.addEventListener("DOMContentLoaded",L,!1):i.attachEvent?i.attachEvent("onreadystatechange",Da):(x("onload",!1),M({type:"NO_DOM2_EVENTS",fatal:!0}))}var oa=null;if("undefined"===typeof SM2_DEFER||!SM2_DEFER)oa=new $;Z.SoundManager=$;Z.soundManager=oa})(window); \ No newline at end of file +policy:"Enabling usePolicyFile for data access",setup:"soundManager.setup(): allowed parameters: %s",setupError:'soundManager.setup(): "%s" cannot be assigned with this method.',setupUndef:'soundManager.setup(): Could not find option "%s"',setupLate:"soundManager.setup(): url, flashVersion and html5Test property changes will not take effect until reboot().",noURL:"soundManager: Flash URL required. Call soundManager.setup({url:...}) to get started.",sm2Loaded:"SoundManager 2: Ready.",reset:"soundManager.reset(): Removing event callbacks", +mobileUA:"Mobile UA detected, preferring HTML5 by default.",globalHTML5:"Using singleton HTML5 Audio() pattern for this device."};p=function(){var a=cb.call(arguments),c=a.shift(),c=F&&F[c]?F[c]:"",e,b;if(c&&a&&a.length){e=0;for(b=a.length;el)&&(c._wD(p("needfl9")),c.flashVersion=l=9);c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===l?" (AS3/Flash 9)":" (AS2/Flash 8)");8'}if(S&&T)return!1;if(c.html5Only)return va(),e(),c.oMC=A(c.movieID),ra(),T=S=!0,!1;var f=d||c.url,j=c.altURL||f,i=fa(),m=P(),l=null,l=h.getElementsByTagName("html")[0],k,q,n,l=l&&l.dir&&l.dir.match(/rtl/i),a=a===g?c.id:a;va();c.url=Wa($?f:j);d=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(null!==c.wmode&&(s.match(/msie 8/i)||!H&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))J.push(F.spcWmode),c.wmode=null;i= +{name:a,id:a,src:d,quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:jb+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};c.debugFlash&&(i.FlashVars="debug=1");c.wmode||delete i.wmode;if(H)f=h.createElement("div"),q=['', +b("movie",d),b("AllowScriptAccess",c.allowScriptAccess),b("quality",i.quality),c.wmode?b("wmode",c.wmode):"",b("bgcolor",c.bgColor),b("hasPriority","true"),c.debugFlash?b("FlashVars",i.FlashVars):"",""].join("");else for(k in f=h.createElement("embed"),i)i.hasOwnProperty(k)&&f.setAttribute(k,i[k]);ya();m=P();if(i=fa())if(c.oMC=A(c.movieID)||h.createElement("div"),c.oMC.id)n=c.oMC.className,c.oMC.className=(n?n+" ":"movieContainer")+(m?" "+m:""),c.oMC.appendChild(f),H&&(k=c.oMC.appendChild(h.createElement("div")), +k.className="sm2-object-box",k.innerHTML=q),T=!0;else{c.oMC.id=c.movieID;c.oMC.className="movieContainer "+m;k=m=null;c.useFlashBlock||(c.useHighPerformance?m={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"}:(m={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},l&&(m.left=Math.abs(parseInt(m.left,10))+"px")));rb&&(c.oMC.style.zIndex=1E4);if(!c.debugFlash)for(n in m)m.hasOwnProperty(n)&&(c.oMC.style[n]=m[n]);try{H||c.oMC.appendChild(f), +i.appendChild(c.oMC),H&&(k=c.oMC.appendChild(h.createElement("div")),k.className="sm2-object-box",k.innerHTML=q),T=!0}catch(r){throw Error(p("domError")+" \n"+r.toString());}}S=!0;e();return!0};ea=function(){if(c.html5Only)return ga(),!1;if(i)return!1;if(!c.url)return k("noURL"),!1;i=c.getMovie(c.id);i||(W?(H?c.oMC.innerHTML=Aa:c.oMC.appendChild(W),W=null,S=!0):ga(c.id,c.url),i=c.getMovie(c.id));"function"===typeof c.oninitmovie&&setTimeout(c.oninitmovie,1);Ha();return!0};M=function(){setTimeout(Sa, +1E3)};Sa=function(){var a,d=!1;if(!c.url||X)return!1;X=!0;u.remove(j,"load",M);if(na&&!Ma)return k("waitFocus"),!1;n||(a=c.getMoviePercent(),0a&&(d=!0));setTimeout(function(){a=c.getMoviePercent();if(d)return X=!1,c._wD(p("waitSWF")),j.setTimeout(M,1),!1;n||(c._wD("soundManager: No Flash response within expected time. Likely causes: "+(0===a?"SWF load failed, ":"")+"Flash blocked or JS-Flash security error."+(c.debugFlash?" "+p("checkSWF"):""),2),!$&&a&&(k("localFail",2),c.debugFlash||k("tryDebug", +2)),0===a&&c._wD(p("swf404",c.url),1),x("flashtojs",!1,": Timed out"+$?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)"));!n&&hb&&(null===a?c.useFlashBlock||0===c.flashLoadTimeout?(c.useFlashBlock&&Ba(),k("waitForever")):(k("waitForever"),I({type:"ontimeout",ignoreInit:!0})):0===c.flashLoadTimeout?k("waitForever"):za(!0))},c.flashLoadTimeout)};da=function(){if(Ma||!na)return u.remove(j,"focus",da),!0;Ma=hb=!0;k("gotFocus");X=!1;M();u.remove(j,"focus",da);return!0};Ha=function(){J.length&& +(c._wD("SoundManager 2: "+J.join(" "),1),J=[])};eb=function(){Ha();var a,d=[];if(c.useHTML5Audio&&c.hasHTML5){for(a in c.audioFormats)c.audioFormats.hasOwnProperty(a)&&d.push(a+" = "+c.html5[a]+(!c.html5[a]&&z&&c.flash[a]?" (using flash)":c.preferFlash&&c.flash[a]&&z?" (preferring flash)":!c.html5[a]?" ("+(c.audioFormats[a].required?"required, ":"")+"and no flash support)":""));c._wD("SoundManager 2 HTML5 support: "+d.join(", "),1)}};U=function(a){if(n)return!1;if(c.html5Only)return k("sm2Loaded"), +n=!0,L(),x("onload",!0),!0;var d=!0,e;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())n=!0,r&&(e={type:!z&&B?"NO_FLASH":"INIT_TIMEOUT"});c._wD("SoundManager 2 "+(r?"failed to load":"loaded")+" ("+(r?"Flash security/load error":"OK")+")",r?2:1);r||a?(c.useFlashBlock&&c.oMC&&(c.oMC.className=P()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error")),I({type:"ontimeout",error:e,ignoreInit:!0}),x("onload",!1),O(e),d=!1):x("onload",!0);r||(c.waitForWindowLoad&&!ca?(k("waitOnload"), +u.add(j,"load",L)):(c.waitForWindowLoad&&ca&&k("docLoaded"),L()));return d};Ra=function(){var a,d=c.setupOptions;for(a in d)d.hasOwnProperty(a)&&(c[a]===g?c[a]=d[a]:c[a]!==d[a]&&(c.setupOptions[a]=c[a]))};ra=function(){if(n)return k("didInit"),!1;if(c.html5Only)return n||(u.remove(j,"load",c.beginDelayedInit),c.enabled=!0,U()),!0;ea();try{i._externalInterfaceTest(!1),Ta(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||i._disableDebug(),c.enabled=!0,x("jstoflash",!0),c.html5Only|| +u.add(j,"unload",qa)}catch(a){return c._wD("js/flash exception: "+a.toString()),x("jstoflash",!1),O({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),za(!0),U(),!1}U();u.remove(j,"load",c.beginDelayedInit);return!0};N=function(){if(V)return!1;V=!0;Ra();ya();var a=null,a=null,d=j.console!==g&&"function"===typeof console.log,e=R.toLowerCase();-1!==e.indexOf("sm2-usehtml5audio=")&&(a="1"===e.charAt(e.indexOf("sm2-usehtml5audio=")+18),d&&console.log((a?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter"), +c.setup({useHTML5Audio:a}));-1!==e.indexOf("sm2-preferflash=")&&(a="1"===e.charAt(e.indexOf("sm2-preferflash=")+16),d&&console.log((a?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),c.setup({preferFlash:a}));!z&&c.hasHTML5&&(c._wD("SoundManager: No Flash detected"+(!c.useHTML5Audio?", enabling HTML5.":". Trying HTML5-only mode."),1),c.setup({useHTML5Audio:!0,preferFlash:!1}));bb();c.html5.usingFlash=ab();B=c.html5.usingFlash;!z&&B&&(J.push(F.needFlash),c.setup({flashLoadTimeout:1}));h.removeEventListener&& +h.removeEventListener("DOMContentLoaded",N,!1);ea();return!0};Ea=function(){"complete"===h.readyState&&(N(),h.detachEvent("onreadystatechange",Ea));return!0};xa=function(){ca=!0;u.remove(j,"load",xa)};wa=function(){if(Ka&&((!c.setupOptions.useHTML5Audio||c.setupOptions.preferFlash)&&J.push(F.mobileUA),c.setupOptions.useHTML5Audio=!0,c.setupOptions.preferFlash=!1,ma||fb&&!s.match(/android\s2\.3/i)))J.push(F.globalHTML5),ma&&(c.ignoreFlash=!0),D=!0};wa();Ga();u.add(j,"focus",da);u.add(j,"load",M);u.add(j, +"load",xa);h.addEventListener?h.addEventListener("DOMContentLoaded",N,!1):h.attachEvent?h.attachEvent("onreadystatechange",Ea):(x("onload",!1),O({type:"NO_DOM2_EVENTS",fatal:!0}))}var pa=null;if(void 0===j.SM2_DEFER||!SM2_DEFER)pa=new aa;j.SoundManager=aa;j.soundManager=pa})(window); \ No newline at end of file diff --git a/static/js/libs/sm/soundmanager2-nodebug-jsmin.js b/static/js/libs/sm/soundmanager2-nodebug-jsmin.js index ca2fc0e..1c28af1 100644 --- a/static/js/libs/sm/soundmanager2-nodebug-jsmin.js +++ b/static/js/libs/sm/soundmanager2-nodebug-jsmin.js @@ -8,73 +8,71 @@ * Code provided under the BSD License: * http://schillmania.com/projects/soundmanager2/license.txt * - * V2.97a.20120916 + * V2.97a.20130101 */ -(function(fa){function R(R,ea){function S(a){return c.preferFlash&&y&&!c.ignoreFlash&&"undefined"!==typeof c.flash[a]&&c.flash[a]}function l(a){return function(c){var d=this._t;return!d||!d._a?null:a.call(this,c)}}this.setupOptions={url:R||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1, -useHTML5Audio:!0,html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null, -ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"], -required:!1}};this.movieID="sm2-container";this.id=ea||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20120916";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox= -{};var ga;try{ga="undefined"!==typeof Audio&&"undefined"!==typeof(ha&&10>opera.version()?new Audio(null):new Audio).canPlayType}catch(Za){ga=!1}this.hasHTML5=ga;this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=!1;var Da,c=this,i=null,T,q=navigator.userAgent,h=fa,ia=h.location.href.toString(),m=document,ja,Ea,ka,j,v=[],J=!1,K=!1,k=!1,s=!1,la=!1,L,r,ma,U,na,B,C,D,Fa,oa,V,W,E,pa,M,qa,X,F,Ga,ra,Ha,Y,Ia,N=null,sa=null,t,ta,G,Z,$,H,p,O=!1,ua=!1,Ja,Ka,La,aa=0,P=null,ba,n=null,Ma, -ca,Q,w,va,wa,Na,o,Wa=Array.prototype.slice,z=!1,y,xa,Oa,u,Pa,ya=q.match(/(ipad|iphone|ipod)/i),x=q.match(/msie/i),Xa=q.match(/webkit/i),za=q.match(/safari/i)&&!q.match(/chrome/i),ha=q.match(/opera/i),Aa=q.match(/(mobile|pre\/|xoom)/i)||ya,Qa=!ia.match(/usehtml5audio/i)&&!ia.match(/sm2\-ignorebadua/i)&&za&&!q.match(/silk/i)&&q.match(/OS X 10_6_([3-7])/i),Ba="undefined"!==typeof m.hasFocus?m.hasFocus():null,da=za&&("undefined"===typeof m.hasFocus||!m.hasFocus()),Ra=!da,Sa=/(mp3|mp4|mpa|m4a|m4b)/i,Ca= -m.location?m.location.protocol.match(/http/i):null,Ta=!Ca?"http://":"",Ua=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,Va="mpeg4,aac,flv,mov,mp4,m4v,f4v,m4a,m4b,mp4v,3gp,3g2".split(","),Ya=RegExp("\\.("+Va.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!Ca;this._global_a=null;if(Aa&&(c.useHTML5Audio=!0,c.preferFlash=!1,ya))z=c.ignoreFlash=!0;this.setup=function(a){var e=!c.url;"undefined"!==typeof a&& -k&&n&&c.ok()&&("undefined"!==typeof a.flashVersion||"undefined"!==typeof a.url)&&H(t("setupLate"));ma(a);e&&M&&"undefined"!==typeof a.url&&c.beginDelayedInit();!M&&"undefined"!==typeof a.url&&"complete"===m.readyState&&setTimeout(E,1);return c};this.supported=this.ok=function(){return n?k&&!s:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(a){return T(a)||m[a]||h[a]};this.createSound=function(a,e){function d(){b=Z(b);c.sounds[f.id]=new Da(f);c.soundIDs.push(f.id);return c.sounds[f.id]}var b=null, -g=null,f=null;if(!k||!c.ok())return H(void 0),!1;"undefined"!==typeof e&&(a={id:a,url:e});b=r(a);b.url=ba(b.url);f=b;if(p(f.id,!0))return c.sounds[f.id];if(ca(f))g=d(),g._setup_html5(f);else{if(8=a)return!1;for(a-=1;0<=a;a--)if(c=k[a],!c.fired&&b.position>=c.position)c.fired=!0,o++,c.method.apply(c.scope,[c.position]);return!0};this._resetOnPosition=function(b){var a,c;a=k.length;if(!a)return!1;for(a-=1;0<=a;a--)if(c=k[a],c.fired&&b<=c.position)c.fired=!1,o--;return!0};s=function(){var a=b._iO,c=a.from,e=a.to,d,f;f=function(){b.clearOnPosition(e, -f);b.stop()};d=function(){if(null!==e&&!isNaN(e))b.onPosition(e,f)};if(null!==c&&!isNaN(c))a.position=c,a.multiShot=!1,d();return a};m=function(){var a,c=b._iO.onposition;if(c)for(a in c)if(c.hasOwnProperty(a))b.onPosition(parseInt(a,10),c[a])};q=function(){var a,c=b._iO.onposition;if(c)for(a in c)c.hasOwnProperty(a)&&b.clearOnPosition(parseInt(a,10))};h=function(){b.isHTML5&&Ja(b)};I=function(){b.isHTML5&&Ka(b)};g=function(a){a||(k=[],o=0);l=!1;b._hasTimer=null;b._a=null;b._html5_canplay=!1;b.bytesLoaded= -null;b.bytesTotal=null;b.duration=b._iO&&b._iO.duration?b._iO.duration:null;b.durationEstimate=null;b.buffered=[];b.eqData=[];b.eqData.left=[];b.eqData.right=[];b.failures=0;b.isBuffering=!1;b.instanceOptions={};b.instanceCount=0;b.loaded=!1;b.metadata={};b.readyState=0;b.muted=!1;b.paused=!1;b.peakData={left:0,right:0};b.waveformData={left:[],right:[]};b.playState=0;b.position=null;b.id3={}};g();this._onTimer=function(a){var c,f=!1,g={};if(b._hasTimer||a){if(b._a&&(a||(0opera.version()?new Audio(null):new Audio,d=b._a,d._called_load=!1,z)c._global_a=d;b.isHTML5=!0;b._a=d;d._t=b;f();b._apply_loop(d,a.loops);a.autoLoad||a.autoPlay? -b.load():(d.autobuffer=!1,d.preload="auto");return d};f=function(){if(b._a._added_events)return!1;var a;b._a._added_events=!0;for(a in u)u.hasOwnProperty(a)&&b._a&&b._a.addEventListener(a,u[a],!1);return!0};A=function(){var a;b._a._added_events=!1;for(a in u)u.hasOwnProperty(a)&&b._a&&b._a.removeEventListener(a,u[a],!1)};this._onload=function(a){a=!!a||!b.isHTML5&&8===j&&b.duration;b.loaded=a;b.readyState=a?3:2;b._onbufferchange(0);b._iO.onload&&b._iO.onload.apply(b,[a]);return!0};this._onbufferchange= -function(a){if(0===b.playState||a&&b.isBuffering||!a&&!b.isBuffering)return!1;b.isBuffering=1===a;b._iO.onbufferchange&&b._iO.onbufferchange.apply(b);return!0};this._onsuspend=function(){b._iO.onsuspend&&b._iO.onsuspend.apply(b);return!0};this._onfailure=function(a,c,e){b.failures++;if(b._iO.onfailure&&1===b.failures)b._iO.onfailure(b,a,c,e)};this._onfinish=function(){var a=b._iO.onfinish;b._onbufferchange(0);b._resetOnPosition(0);if(b.instanceCount){b.instanceCount--;if(!b.instanceCount&&(q(),b.playState= -0,b.paused=!1,b.instanceCount=0,b.instanceOptions={},b._iO={},I(),b.isHTML5))b.position=0;(!b.instanceCount||b._iO.multiShotEvents)&&a&&a.apply(b)}};this._whileloading=function(a,c,e,d){var f=b._iO;b.bytesLoaded=a;b.bytesTotal=c;b.duration=Math.floor(e);b.bufferLength=d;b.durationEstimate=!b.isHTML5&&!f.isMovieStar?f.duration?b.duration>f.duration?b.duration:f.duration:parseInt(b.bytesTotal/b.bytesLoaded*b.duration,10):b.duration;if(!b.isHTML5)b.buffered=[{start:0,end:b.duration}];(3!==b.readyState|| -b.isHTML5)&&f.whileloading&&f.whileloading.apply(b)};this._whileplaying=function(a,c,e,d,f){var g=b._iO;if(isNaN(a)||null===a)return!1;b.position=Math.max(0,a);b._processOnPosition();if(!b.isHTML5&&8opera.version()?new Audio(null):new Audio:null,d,b,g={},f;f=c.audioFormats;for(d in f)if(f.hasOwnProperty(d)&&(b="audio/"+d,g[d]=a(f[d].type),g[b]=g[d],d.match(Sa)?(c.flash[d]=!0,c.flash[b]=!0):(c.flash[d]=!1,c.flash[b]=!1),f[d]&&f[d].related))for(b=f[d].related.length- -1;0<=b;b--)g["audio/"+f[d].related[b]]=g[d],c.html5[f[d].related[b]]=g[d],c.flash[f[d].related[b]]=g[d];g.canPlayType=e?a:null;c.html5=r(c.html5,g);return!0};t=function(){};Z=function(a){if(8===j&&1j)c.flashVersion=j=9;c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===j?" (AS3/Flash 9)":" (AS2/Flash 8)");8'}if(J&&K)return!1;if(c.html5Only)return oa(),c.oMC=T(c.movieID),ka(),K=J=!0,!1;var b=e||c.url,g=c.altURL||b,f=qa(),h=G(),i=null,i=m.getElementsByTagName("html")[0],j,k,l,i=i&&i.dir&&i.dir.match(/rtl/i),a="undefined"===typeof a?c.id:a;oa();c.url=Ia(Ca?b:g);e=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(null!==c.wmode&&(q.match(/msie 8/i)||!x&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))c.wmode= -null;f={name:a,id:a,src:e,quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Ta+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};if(c.debugFlash)f.FlashVars="debug=1";c.wmode||delete f.wmode;if(x)b=m.createElement("div"),k=['',d("movie",e),d("AllowScriptAccess",c.allowScriptAccess),d("quality",f.quality),c.wmode?d("wmode",c.wmode):"",d("bgcolor",c.bgColor),d("hasPriority","true"),c.debugFlash?d("FlashVars",f.FlashVars):"",""].join("");else for(j in b=m.createElement("embed"),f)f.hasOwnProperty(j)&&b.setAttribute(j,f[j]);ra();h=G();if(f=qa())if(c.oMC=T(c.movieID)||m.createElement("div"),c.oMC.id){l=c.oMC.className;c.oMC.className= -(l?l+" ":"movieContainer")+(h?" "+h:"");c.oMC.appendChild(b);if(x)j=c.oMC.appendChild(m.createElement("div")),j.className="sm2-object-box",j.innerHTML=k;K=!0}else{c.oMC.id=c.movieID;c.oMC.className="movieContainer "+h;j=h=null;if(!c.useFlashBlock)if(c.useHighPerformance)h={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else if(h={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},i)h.left=Math.abs(parseInt(h.left,10))+"px";if(Xa)c.oMC.style.zIndex= -1E4;if(!c.debugFlash)for(l in h)h.hasOwnProperty(l)&&(c.oMC.style[l]=h[l]);try{x||c.oMC.appendChild(b);f.appendChild(c.oMC);if(x)j=c.oMC.appendChild(m.createElement("div")),j.className="sm2-object-box",j.innerHTML=k;K=!0}catch(n){throw Error(t("domError")+" \n"+n.toString());}}return J=!0};W=function(){if(c.html5Only)return X(),!1;if(i||!c.url)return!1;i=c.getMovie(c.id);if(!i)N?(x?c.oMC.innerHTML=sa:c.oMC.appendChild(N),N=null,J=!0):X(c.id,c.url),i=c.getMovie(c.id);"function"===typeof c.oninitmovie&& -setTimeout(c.oninitmovie,1);return!0};D=function(){setTimeout(Fa,1E3)};Fa=function(){var a,e=!1;if(!c.url||O)return!1;O=!0;o.remove(h,"load",D);if(da&&!Ba)return!1;k||(a=c.getMoviePercent(),0a&&(e=!0));setTimeout(function(){a=c.getMoviePercent();if(e)return O=!1,h.setTimeout(D,1),!1;!k&&Ra&&(null===a?c.useFlashBlock||0===c.flashLoadTimeout?c.useFlashBlock&&ta():Y(!0):0!==c.flashLoadTimeout&&Y(!0))},c.flashLoadTimeout)};V=function(){if(Ba||!da)return o.remove(h,"focus",V),!0;Ba=Ra=!0;O=!1; -D();o.remove(h,"focus",V);return!0};Pa=function(){};L=function(a){if(k)return!1;if(c.html5Only)return k=!0,C(),!0;var e=!0,d;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())k=!0,s&&(d={type:!y&&n?"NO_FLASH":"INIT_TIMEOUT"});if(s||a){if(c.useFlashBlock&&c.oMC)c.oMC.className=G()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error");B({type:"ontimeout",error:d,ignoreInit:!0});F(d);e=!1}s||(c.waitForWindowLoad&&!la?o.add(h,"load",C):C());return e};Ea=function(){var a,e=c.setupOptions; -for(a in e)e.hasOwnProperty(a)&&("undefined"===typeof c[a]?c[a]=e[a]:c[a]!==e[a]&&(c.setupOptions[a]=c[a]))};ka=function(){if(k)return!1;if(c.html5Only){if(!k)o.remove(h,"load",c.beginDelayedInit),c.enabled=!0,L();return!0}W();try{i._externalInterfaceTest(!1),Ga(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||i._disableDebug(),c.enabled=!0,c.html5Only||o.add(h,"unload",ja)}catch(a){return F({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),Y(!0),L(),!1}L();o.remove(h,"load",c.beginDelayedInit); -return!0};E=function(){if(M)return!1;M=!0;Ea();ra();!y&&c.hasHTML5&&c.setup({useHTML5Audio:!0,preferFlash:!1});Na();c.html5.usingFlash=Ma();n=c.html5.usingFlash;Pa();!y&&n&&c.setup({flashLoadTimeout:1});m.removeEventListener&&m.removeEventListener("DOMContentLoaded",E,!1);W();return!0};wa=function(){"complete"===m.readyState&&(E(),m.detachEvent("onreadystatechange",wa));return!0};pa=function(){la=!0;o.remove(h,"load",pa)};xa();o.add(h,"focus",V);o.add(h,"load",D);o.add(h,"load",pa);m.addEventListener? -m.addEventListener("DOMContentLoaded",E,!1):m.attachEvent?m.attachEvent("onreadystatechange",wa):F({type:"NO_DOM2_EVENTS",fatal:!0})}var ea=null;if("undefined"===typeof SM2_DEFER||!SM2_DEFER)ea=new R;fa.SoundManager=R;fa.soundManager=ea})(window); \ No newline at end of file +(function(i,g){function R(R,fa){function S(b){return c.preferFlash&&A&&!c.ignoreFlash&&c.flash[b]!==g&&c.flash[b]}function m(b){return function(c){var d=this._s;return!d||!d._a?null:b.call(this,c)}}this.setupOptions={url:R||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0, +html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null}; +this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID= +"sm2-container";this.id=fa||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20130101";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox={};this.html5={usingFlash:null}; +this.flash={};this.ignoreFlash=this.html5Only=!1;var Ga,c=this,Ha=null,h=null,T,q=navigator.userAgent,ga=i.location.href.toString(),l=document,ha,Ia,ia,k,r=[],J=!1,K=!1,j=!1,s=!1,ja=!1,L,t,ka,U,la,B,C,D,Ja,ma,V,na,W,oa,E,pa,M,qa,X,F,Ka,ra,La,sa,Ma,N=null,ta=null,v,ua,G,Y,Z,H,p,O=!1,va=!1,Na,Oa,Pa,$=0,P=null,aa,Qa=[],u=null,Ra,ba,Q,y,wa,xa,Sa,n,db=Array.prototype.slice,w=!1,ya,A,za,Ta,x,ca=q.match(/(ipad|iphone|ipod)/i),Ua=q.match(/android/i),z=q.match(/msie/i),eb=q.match(/webkit/i),Aa=q.match(/safari/i)&& +!q.match(/chrome/i),Ba=q.match(/opera/i),Ca=q.match(/(mobile|pre\/|xoom)/i)||ca||Ua,Va=!ga.match(/usehtml5audio/i)&&!ga.match(/sm2\-ignorebadua/i)&&Aa&&!q.match(/silk/i)&&q.match(/OS X 10_6_([3-7])/i),Da=l.hasFocus!==g?l.hasFocus():null,da=Aa&&(l.hasFocus===g||!l.hasFocus()),Wa=!da,Xa=/(mp3|mp4|mpa|m4a|m4b)/i,Ea=l.location?l.location.protocol.match(/http/i):null,Ya=!Ea?"http://":"",Za=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,$a="mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "), +fb=RegExp("\\.("+$a.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!Ea;var Fa;try{Fa=Audio!==g&&(Ba&&opera!==g&&10>opera.version()?new Audio(null):new Audio).canPlayType!==g}catch(hb){Fa=!1}this.hasHTML5=Fa;this.setup=function(b){var e=!c.url;b!==g&&(j&&u&&c.ok()&&(b.flashVersion!==g||b.url!==g||b.html5Test!==g))&&H(v("setupLate"));ka(b);e&&(M&&b.url!==g)&&c.beginDelayedInit();!M&&(b.url!==g&&"complete"===l.readyState)&&setTimeout(E,1);return c}; +this.supported=this.ok=function(){return u?j&&!s:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(b){return T(b)||l[b]||i[b]};this.createSound=function(b,e){function d(){a=Y(a);c.sounds[a.id]=new Ga(a);c.soundIDs.push(a.id);return c.sounds[a.id]}var a,f=null;if(!j||!c.ok())return H(void 0),!1;e!==g&&(b={id:b,url:e});a=t(b);a.url=aa(a.url);if(p(a.id,!0))return c.sounds[a.id];ba(a)?(f=d(),f._setup_html5(a)):(8=b)return!1;for(b-=1;0<=b;b--)c=j[b],!c.fired&&a.position>=c.position&&(c.fired=!0,n++,c.method.apply(c.scope,[c.position]));return!0};this._resetOnPosition=function(a){var b,c;b=j.length;if(!b)return!1;for(b-=1;0<=b;b--)c=j[b],c.fired&&a<=c.position&&(c.fired=!1,n--);return!0};u=function(){var b=a._iO,c=b.from,e=b.to,d,f;f=function(){a.clearOnPosition(e,f);a.stop()};d=function(){if(null!==e&&!isNaN(e))a.onPosition(e, +f)};null!==c&&!isNaN(c)&&(b.position=c,b.multiShot=!1,d());return b};m=function(){var b,c=a._iO.onposition;if(c)for(b in c)if(c.hasOwnProperty(b))a.onPosition(parseInt(b,10),c[b])};s=function(){var b,c=a._iO.onposition;if(c)for(b in c)c.hasOwnProperty(b)&&a.clearOnPosition(parseInt(b,10))};l=function(){a.isHTML5&&Na(a)};I=function(){a.isHTML5&&Oa(a)};f=function(b){b||(j=[],n=0);q=!1;a._hasTimer=null;a._a=null;a._html5_canplay=!1;a.bytesLoaded=null;a.bytesTotal=null;a.duration=a._iO&&a._iO.duration? +a._iO.duration:null;a.durationEstimate=null;a.buffered=[];a.eqData=[];a.eqData.left=[];a.eqData.right=[];a.failures=0;a.isBuffering=!1;a.instanceOptions={};a.instanceCount=0;a.loaded=!1;a.metadata={};a.readyState=0;a.muted=!1;a.paused=!1;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.playState=0;a.position=null;a.id3={}};f();this._onTimer=function(b){var c,f=!1,g={};if(a._hasTimer||b){if(a._a&&(b||(0opera.version()?new Audio(null):new Audio,e=a._a,e._called_load=!1,w&&(Ha=e);a.isHTML5=!0;a._a=e;e._s=a;ab();a._apply_loop(e,b.loops);b.autoLoad||b.autoPlay?a.load():(e.autobuffer=!1,e.preload="auto");return e};ab=function(){if(a._a._added_events)return!1;var b;a._a._added_events=!0;for(b in x)x.hasOwnProperty(b)&& +a._a&&a._a.addEventListener(b,x[b],!1);return!0};i=function(){var b;a._a._added_events=!1;for(b in x)x.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,x[b],!1)};this._onload=function(b){b=!!b||!a.isHTML5&&8===k&&a.duration;a.loaded=b;a.readyState=b?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[b]);return!0};this._onbufferchange=function(b){if(0===a.playState||b&&a.isBuffering||!b&&!a.isBuffering)return!1;a.isBuffering=1===b;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return!0}; +this._onsuspend=function(){a._iO.onsuspend&&a._iO.onsuspend.apply(a);return!0};this._onfailure=function(b,c,e){a.failures++;if(a._iO.onfailure&&1===a.failures)a._iO.onfailure(a,b,c,e)};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a._resetOnPosition(0);a.instanceCount&&(a.instanceCount--,a.instanceCount||(s(),a.playState=0,a.paused=!1,a.instanceCount=0,a.instanceOptions={},a._iO={},I(),a.isHTML5&&(a.position=0)),(!a.instanceCount||a._iO.multiShotEvents)&&b&&b.apply(a))};this._whileloading= +function(b,c,e,d){var f=a._iO;a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(e);a.bufferLength=d;a.durationEstimate=!a.isHTML5&&!f.isMovieStar?f.duration?a.duration>f.duration?a.duration:f.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10):a.duration;a.isHTML5||(a.buffered=[{start:0,end:a.duration}]);(3!==a.readyState||a.isHTML5)&&f.whileloading&&f.whileloading.apply(a)};this._whileplaying=function(b,c,e,d,f){var h=a._iO;if(isNaN(b)||null===b)return!1;a.position=Math.max(0,b);a._processOnPosition(); +!a.isHTML5&&8opera.version()?new Audio(null):new Audio:null,d,a,f={},h;h=c.audioFormats;for(d in h)if(h.hasOwnProperty(d)&&(a="audio/"+d,f[d]=b(h[d].type),f[a]=f[d],d.match(Xa)?(c.flash[d]=!0,c.flash[a]= +!0):(c.flash[d]=!1,c.flash[a]=!1),h[d]&&h[d].related))for(a=h[d].related.length-1;0<=a;a--)f["audio/"+h[d].related[a]]=f[d],c.html5[h[d].related[a]]=f[d],c.flash[h[d].related[a]]=f[d];f.canPlayType=e?b:null;c.html5=t(c.html5,f);return!0};na={};v=function(){};Y=function(b){8===k&&(1k)&&(c.flashVersion=k=9);c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===k?" (AS3/Flash 9)":" (AS2/Flash 8)");8'}if(J&&K)return!1;if(c.html5Only)return ma(),c.oMC=T(c.movieID),ia(),K=J=!0,!1;var a=e||c.url,f=c.altURL||a,h=qa(),i=G(),k=null,k=l.getElementsByTagName("html")[0],j,n,m,k=k&&k.dir&&k.dir.match(/rtl/i),b=b===g?c.id:b;ma();c.url=Ma(Ea?a:f);e=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(null!==c.wmode&&(q.match(/msie 8/i)||!z&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))Qa.push(na.spcWmode), +c.wmode=null;h={name:b,id:b,src:e,quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Ya+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};c.debugFlash&&(h.FlashVars="debug=1");c.wmode||delete h.wmode;if(z)a=l.createElement("div"),n=['',d("movie",e),d("AllowScriptAccess",c.allowScriptAccess),d("quality",h.quality),c.wmode?d("wmode",c.wmode):"",d("bgcolor",c.bgColor),d("hasPriority","true"),c.debugFlash?d("FlashVars",h.FlashVars):"",""].join("");else for(j in a=l.createElement("embed"),h)h.hasOwnProperty(j)&&a.setAttribute(j,h[j]);ra();i=G();if(h=qa())if(c.oMC=T(c.movieID)||l.createElement("div"),c.oMC.id)m=c.oMC.className,c.oMC.className= +(m?m+" ":"movieContainer")+(i?" "+i:""),c.oMC.appendChild(a),z&&(j=c.oMC.appendChild(l.createElement("div")),j.className="sm2-object-box",j.innerHTML=n),K=!0;else{c.oMC.id=c.movieID;c.oMC.className="movieContainer "+i;j=i=null;c.useFlashBlock||(c.useHighPerformance?i={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"}:(i={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},k&&(i.left=Math.abs(parseInt(i.left,10))+"px")));eb&&(c.oMC.style.zIndex= +1E4);if(!c.debugFlash)for(m in i)i.hasOwnProperty(m)&&(c.oMC.style[m]=i[m]);try{z||c.oMC.appendChild(a),h.appendChild(c.oMC),z&&(j=c.oMC.appendChild(l.createElement("div")),j.className="sm2-object-box",j.innerHTML=n),K=!0}catch(p){throw Error(v("domError")+" \n"+p.toString());}}return J=!0};W=function(){if(c.html5Only)return X(),!1;if(h||!c.url)return!1;h=c.getMovie(c.id);h||(N?(z?c.oMC.innerHTML=ta:c.oMC.appendChild(N),N=null,J=!0):X(c.id,c.url),h=c.getMovie(c.id));"function"===typeof c.oninitmovie&& +setTimeout(c.oninitmovie,1);return!0};D=function(){setTimeout(Ja,1E3)};Ja=function(){var b,e=!1;if(!c.url||O)return!1;O=!0;n.remove(i,"load",D);if(da&&!Da)return!1;j||(b=c.getMoviePercent(),0b&&(e=!0));setTimeout(function(){b=c.getMoviePercent();if(e)return O=!1,i.setTimeout(D,1),!1;!j&&Wa&&(null===b?c.useFlashBlock||0===c.flashLoadTimeout?c.useFlashBlock&&ua():B({type:"ontimeout",ignoreInit:!0}):0!==c.flashLoadTimeout&&sa(!0))},c.flashLoadTimeout)};V=function(){if(Da||!da)return n.remove(i, +"focus",V),!0;Da=Wa=!0;O=!1;D();n.remove(i,"focus",V);return!0};L=function(b){if(j)return!1;if(c.html5Only)return j=!0,C(),!0;var e=!0,d;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())j=!0,s&&(d={type:!A&&u?"NO_FLASH":"INIT_TIMEOUT"});if(s||b)c.useFlashBlock&&c.oMC&&(c.oMC.className=G()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error")),B({type:"ontimeout",error:d,ignoreInit:!0}),F(d),e=!1;s||(c.waitForWindowLoad&&!ja?n.add(i,"load",C):C());return e};Ia=function(){var b,e= +c.setupOptions;for(b in e)e.hasOwnProperty(b)&&(c[b]===g?c[b]=e[b]:c[b]!==e[b]&&(c.setupOptions[b]=c[b]))};ia=function(){if(j)return!1;if(c.html5Only)return j||(n.remove(i,"load",c.beginDelayedInit),c.enabled=!0,L()),!0;W();try{h._externalInterfaceTest(!1),Ka(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||h._disableDebug(),c.enabled=!0,c.html5Only||n.add(i,"unload",ha)}catch(b){return F({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),sa(!0),L(),!1}L();n.remove(i,"load",c.beginDelayedInit); +return!0};E=function(){if(M)return!1;M=!0;Ia();ra();!A&&c.hasHTML5&&c.setup({useHTML5Audio:!0,preferFlash:!1});Sa();c.html5.usingFlash=Ra();u=c.html5.usingFlash;!A&&u&&(Qa.push(na.needFlash),c.setup({flashLoadTimeout:1}));l.removeEventListener&&l.removeEventListener("DOMContentLoaded",E,!1);W();return!0};xa=function(){"complete"===l.readyState&&(E(),l.detachEvent("onreadystatechange",xa));return!0};pa=function(){ja=!0;n.remove(i,"load",pa)};oa=function(){if(Ca&&(c.setupOptions.useHTML5Audio=!0,c.setupOptions.preferFlash= +!1,ca||Ua&&!q.match(/android\s2\.3/i)))ca&&(c.ignoreFlash=!0),w=!0};oa();za();n.add(i,"focus",V);n.add(i,"load",D);n.add(i,"load",pa);l.addEventListener?l.addEventListener("DOMContentLoaded",E,!1):l.attachEvent?l.attachEvent("onreadystatechange",xa):F({type:"NO_DOM2_EVENTS",fatal:!0})}var fa=null;if(void 0===i.SM2_DEFER||!SM2_DEFER)fa=new R;i.SoundManager=R;i.soundManager=fa})(window); \ No newline at end of file diff --git a/static/js/libs/sm/soundmanager2-nodebug.js b/static/js/libs/sm/soundmanager2-nodebug.js index 856175b..66ede33 100644 --- a/static/js/libs/sm/soundmanager2-nodebug.js +++ b/static/js/libs/sm/soundmanager2-nodebug.js @@ -8,13 +8,14 @@ * Code provided under the BSD License: * http://schillmania.com/projects/soundmanager2/license.txt * - * V2.97a.20120916 + * V2.97a.20130101 */ -/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ +/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */ /*jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */ -(function(window) { +(function(window, _undefined) { +"use strict"; var soundManager = null; function SoundManager(smURL, smID) { this.setupOptions = { @@ -101,7 +102,7 @@ function SoundManager(smURL, smID) { this.id = (smID || 'sm2movie'); this.debugID = 'soundmanager-debug'; this.debugURLParam = /([#?&])debug=1/i; - this.versionNumber = 'V2.97a.20120916'; + this.versionNumber = 'V2.97a.20130101'; this.version = null; this.movieURL = null; this.altURL = null; @@ -126,13 +127,6 @@ function SoundManager(smURL, smID) { }; this.sandbox = { }; - this.hasHTML5 = (function() { - try { - return (typeof Audio !== 'undefined' && typeof (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== 'undefined'); - } catch(e) { - return false; - } - }()); this.html5 = { 'usingFlash': null }; @@ -140,22 +134,21 @@ function SoundManager(smURL, smID) { this.html5Only = false; this.ignoreFlash = false; var SMSound, - _s = this, _flash = null, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _setProperties, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _assign, _extraOptions, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _winOnLoad, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _swfCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _startTimer, _stopTimer, _timerExecute, _h5TimerCount = 0, _h5IntervalTimer = null, _parseURL, - _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport, - _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)), - _mobileHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice), - _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && !_ua.match(/silk/i) && _ua.match(/OS X 10_6_([3-7])/i)), - _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && (typeof _doc.hasFocus === 'undefined' || !_doc.hasFocus())), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i, - _emptyURL = 'about:blank', - _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null), - _http = (!_overHTTP ? 'http:/'+'/' : ''), - _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i, - _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'], - _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [], + needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages, + is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)), + mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid), + isBadSafari = (!wl.match(/usehtml5audio/i) && !wl.match(/sm2\-ignorebadua/i) && isSafari && !ua.match(/silk/i) && ua.match(/OS X 10_6_([3-7])/i)), + hasConsole = (window.console !== _undefined && console.log !== _undefined), isFocused = (doc.hasFocus !== _undefined?doc.hasFocus():null), tryInitOnFocus = (isSafari && (doc.hasFocus === _undefined || !doc.hasFocus())), okToDisable = !tryInitOnFocus, flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i, + emptyURL = 'about:blank', + overHTTP = (doc.location?doc.location.protocol.match(/http/i):null), + http = (!overHTTP ? 'http:/'+'/' : ''), + netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i, + netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'], + netStreamPattern = new RegExp('\\.(' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; - this.useAltURL = !_overHTTP; - this._global_a = null; - _swfCSS = { + this.useAltURL = !overHTTP; + swfCSS = { 'swfBox': 'sm2-object-box', 'swfDefault': 'movieContainer', 'swfError': 'swf_error', @@ -166,101 +159,99 @@ function SoundManager(smURL, smID) { 'highPerf': 'high_performance', 'flashDebug': 'flash_debug' }; - if (_mobileHTML5) { - _s.useHTML5Audio = true; - _s.preferFlash = false; - if (_is_iDevice) { - _s.ignoreFlash = true; - _useGlobalHTML5Audio = true; + this.hasHTML5 = (function() { + try { + return (Audio !== _undefined && (isOpera && opera !== _undefined && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== _undefined); + } catch(e) { + return false; } - } + }()); this.setup = function(options) { - var noURL = (!_s.url); - if (typeof options !== 'undefined' && _didInit && _needsFlash && _s.ok() && (typeof options.flashVersion !== 'undefined' || typeof options.url !== 'undefined')) { - _complain(_str('setupLate')); + var noURL = (!sm2.url); + if (options !== _undefined && didInit && needsFlash && sm2.ok() && (options.flashVersion !== _undefined || options.url !== _undefined || options.html5Test !== _undefined)) { + complain(str('setupLate')); } - _assign(options); - if (noURL && _didDCLoaded && typeof options.url !== 'undefined') { - _s.beginDelayedInit(); + assign(options); + if (noURL && didDCLoaded && options.url !== _undefined) { + sm2.beginDelayedInit(); } - if (!_didDCLoaded && typeof options.url !== 'undefined' && _doc.readyState === 'complete') { - setTimeout(_domContentLoaded, 1); + if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') { + setTimeout(domContentLoaded, 1); } - return _s; + return sm2; }; this.ok = function() { - return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); + return (needsFlash?(didInit && !disabled):(sm2.useHTML5Audio && sm2.hasHTML5)); }; this.supported = this.ok; this.getMovie = function(smID) { - return _id(smID) || _doc[smID] || _win[smID]; + return id(smID) || doc[smID] || window[smID]; }; this.createSound = function(oOptions, _url) { - var _cs, _cs_string, thisOptions = null, oSound = null, _tO = null; - if (!_didInit || !_s.ok()) { - _complain(_cs_string); + var cs, cs_string, options, oSound = null; + if (!didInit || !sm2.ok()) { + complain(cs_string); return false; } - if (typeof _url !== 'undefined') { + if (_url !== _undefined) { oOptions = { 'id': oOptions, 'url': _url }; } - thisOptions = _mixin(oOptions); - thisOptions.url = _parseURL(thisOptions.url); - _tO = thisOptions; - if (_idCheck(_tO.id, true)) { - return _s.sounds[_tO.id]; + options = mixin(oOptions); + options.url = parseURL(options.url); + if (idCheck(options.id, true)) { + return sm2.sounds[options.id]; } function make() { - thisOptions = _loopFix(thisOptions); - _s.sounds[_tO.id] = new SMSound(_tO); - _s.soundIDs.push(_tO.id); - return _s.sounds[_tO.id]; + options = loopFix(options); + sm2.sounds[options.id] = new SMSound(options); + sm2.soundIDs.push(options.id); + return sm2.sounds[options.id]; } - if (_html5OK(_tO)) { + if (html5OK(options)) { oSound = make(); - oSound._setup_html5(_tO); + oSound._setup_html5(options); } else { - if (_fV > 8) { - if (_tO.isMovieStar === null) { - _tO.isMovieStar = !!(_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern)); + if (fV > 8) { + if (options.isMovieStar === null) { + options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || options.url.match(netStreamPattern)); } } - _tO = _policyFix(_tO, _cs); + options = policyFix(options, cs); oSound = make(); - if (_fV === 8) { - _flash._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile); + if (fV === 8) { + flash._createSound(options.id, options.loops||1, options.usePolicyFile); } else { - _flash._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile); - if (!_tO.serverURL) { + flash._createSound(options.id, options.url, options.usePeakData, options.useWaveformData, options.useEQData, options.isMovieStar, (options.isMovieStar?options.bufferTime:false), options.loops||1, options.serverURL, options.duration||null, options.autoPlay, true, options.autoLoad, options.usePolicyFile); + if (!options.serverURL) { oSound.connected = true; - if (_tO.onconnect) { - _tO.onconnect.apply(oSound); + if (options.onconnect) { + options.onconnect.apply(oSound); } } } - if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) { - oSound.load(_tO); + if (!options.serverURL && (options.autoLoad || options.autoPlay)) { + oSound.load(options); } } - if (!_tO.serverURL && _tO.autoPlay) { + if (!options.serverURL && options.autoPlay) { oSound.play(); } return oSound; }; this.destroySound = function(sID, _bFromSound) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - var oS = _s.sounds[sID], i; + var oS = sm2.sounds[sID], i; oS._iO = {}; oS.stop(); oS.unload(); - for (i = 0; i < _s.soundIDs.length; i++) { - if (_s.soundIDs[i] === sID) { - _s.soundIDs.splice(i, 1); + for (i = 0; i < sm2.soundIDs.length; i++) { + if (sm2.soundIDs[i] === sID) { + sm2.soundIDs.splice(i, 1); break; } } @@ -268,41 +259,41 @@ function SoundManager(smURL, smID) { oS.destruct(true); } oS = null; - delete _s.sounds[sID]; + delete sm2.sounds[sID]; return true; }; this.load = function(sID, oOptions) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].load(oOptions); + return sm2.sounds[sID].load(oOptions); }; this.unload = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].unload(); + return sm2.sounds[sID].unload(); }; this.onPosition = function(sID, nPosition, oMethod, oScope) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].onposition(nPosition, oMethod, oScope); + return sm2.sounds[sID].onposition(nPosition, oMethod, oScope); }; this.onposition = this.onPosition; this.clearOnPosition = function(sID, nPosition, oMethod) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].clearOnPosition(nPosition, oMethod); + return sm2.sounds[sID].clearOnPosition(nPosition, oMethod); }; this.play = function(sID, oOptions) { var result = false; - if (!_didInit || !_s.ok()) { - _complain(_sm+'.play(): ' + _str(!_didInit?'notReady':'notOK')); + if (!didInit || !sm2.ok()) { + complain(sm + '.play(): ' + str(!didInit?'notReady':'notOK')); return result; } - if (!_idCheck(sID)) { + if (!idCheck(sID)) { if (!(oOptions instanceof Object)) { oOptions = { url: oOptions @@ -310,179 +301,179 @@ function SoundManager(smURL, smID) { } if (oOptions && oOptions.url) { oOptions.id = sID; - result = _s.createSound(oOptions).play(); + result = sm2.createSound(oOptions).play(); } return result; } - return _s.sounds[sID].play(oOptions); + return sm2.sounds[sID].play(oOptions); }; this.start = this.play; this.setPosition = function(sID, nMsecOffset) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].setPosition(nMsecOffset); + return sm2.sounds[sID].setPosition(nMsecOffset); }; this.stop = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].stop(); + return sm2.sounds[sID].stop(); }; this.stopAll = function() { var oSound; - for (oSound in _s.sounds) { - if (_s.sounds.hasOwnProperty(oSound)) { - _s.sounds[oSound].stop(); + for (oSound in sm2.sounds) { + if (sm2.sounds.hasOwnProperty(oSound)) { + sm2.sounds[oSound].stop(); } } }; this.pause = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].pause(); + return sm2.sounds[sID].pause(); }; this.pauseAll = function() { var i; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].pause(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].pause(); } }; this.resume = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].resume(); + return sm2.sounds[sID].resume(); }; this.resumeAll = function() { var i; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].resume(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].resume(); } }; this.togglePause = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].togglePause(); + return sm2.sounds[sID].togglePause(); }; this.setPan = function(sID, nPan) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].setPan(nPan); + return sm2.sounds[sID].setPan(nPan); }; this.setVolume = function(sID, nVol) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].setVolume(nVol); + return sm2.sounds[sID].setVolume(nVol); }; this.mute = function(sID) { var i = 0; - if (typeof sID !== 'string') { + if (sID instanceof String) { sID = null; } if (!sID) { - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].mute(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].mute(); } - _s.muted = true; + sm2.muted = true; } else { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].mute(); + return sm2.sounds[sID].mute(); } return true; }; this.muteAll = function() { - _s.mute(); + sm2.mute(); }; this.unmute = function(sID) { var i; - if (typeof sID !== 'string') { + if (sID instanceof String) { sID = null; } if (!sID) { - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].unmute(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].unmute(); } - _s.muted = false; + sm2.muted = false; } else { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].unmute(); + return sm2.sounds[sID].unmute(); } return true; }; this.unmuteAll = function() { - _s.unmute(); + sm2.unmute(); }; this.toggleMute = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].toggleMute(); + return sm2.sounds[sID].toggleMute(); }; this.getMemoryUse = function() { var ram = 0; - if (_flash && _fV !== 8) { - ram = parseInt(_flash._getMemoryUse(), 10); + if (flash && fV !== 8) { + ram = parseInt(flash._getMemoryUse(), 10); } return ram; }; this.disable = function(bNoDisable) { var i; - if (typeof bNoDisable === 'undefined') { + if (bNoDisable === _undefined) { bNoDisable = false; } - if (_disabled) { + if (disabled) { return false; } - _disabled = true; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _disableObject(_s.sounds[_s.soundIDs[i]]); + disabled = true; + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + disableObject(sm2.sounds[sm2.soundIDs[i]]); } - _initComplete(bNoDisable); - _event.remove(_win, 'load', _initUserOnload); + initComplete(bNoDisable); + event.remove(window, 'load', initUserOnload); return true; }; this.canPlayMIME = function(sMIME) { var result; - if (_s.hasHTML5) { - result = _html5CanPlay({type:sMIME}); + if (sm2.hasHTML5) { + result = html5CanPlay({type:sMIME}); } - if (!result && _needsFlash) { - result = (sMIME && _s.ok() ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null); + if (!result && needsFlash) { + result = (sMIME && sm2.ok() ? !!((fV > 8 ? sMIME.match(netStreamMimeTypes) : null) || sMIME.match(sm2.mimePattern)) : null); } return result; }; this.canPlayURL = function(sURL) { var result; - if (_s.hasHTML5) { - result = _html5CanPlay({url: sURL}); + if (sm2.hasHTML5) { + result = html5CanPlay({url: sURL}); } - if (!result && _needsFlash) { - result = (sURL && _s.ok() ? !!(sURL.match(_s.filePattern)) : null); + if (!result && needsFlash) { + result = (sURL && sm2.ok() ? !!(sURL.match(sm2.filePattern)) : null); } return result; }; this.canPlayLink = function(oLink) { - if (typeof oLink.type !== 'undefined' && oLink.type) { - if (_s.canPlayMIME(oLink.type)) { + if (oLink.type !== _undefined && oLink.type) { + if (sm2.canPlayMIME(oLink.type)) { return true; } } - return _s.canPlayURL(oLink.href); + return sm2.canPlayURL(oLink.href); }; this.getSoundById = function(sID, _suppressDebug) { if (!sID) { - throw new Error(_sm+'.getSoundById(): sID is null/undefined'); + throw new Error(sm + '.getSoundById(): sID is null/_undefined'); } - var result = _s.sounds[sID]; + var result = sm2.sounds[sID]; return result; }; this.onready = function(oMethod, oScope) { @@ -490,13 +481,13 @@ function SoundManager(smURL, smID) { result = false; if (typeof oMethod === 'function') { if (!oScope) { - oScope = _win; + oScope = window; } - _addOnEvent(sType, oMethod, oScope); - _processOnEvents(); + addOnEvent(sType, oMethod, oScope); + processOnEvents(); result = true; } else { - throw _str('needFunction', sType); + throw str('needFunction', sType); } return result; }; @@ -505,80 +496,98 @@ function SoundManager(smURL, smID) { result = false; if (typeof oMethod === 'function') { if (!oScope) { - oScope = _win; + oScope = window; } - _addOnEvent(sType, oMethod, oScope); - _processOnEvents({type:sType}); + addOnEvent(sType, oMethod, oScope); + processOnEvents({type:sType}); result = true; } else { - throw _str('needFunction', sType); + throw str('needFunction', sType); } return result; }; - this._writeDebug = function(sText, sType, _bTimestamp) { + this._writeDebug = function(sText, sType) { return true; }; this._wD = this._writeDebug; this._debug = function() { }; - this.reboot = function() { - var i, j; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].destruct(); + this.reboot = function(resetEvents, excludeInit) { + var i, j, k; + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].destruct(); } - if (_flash) { + if (flash) { try { - if (_isIE) { - _oRemovedHTML = _flash.innerHTML; + if (isIE) { + oRemovedHTML = flash.innerHTML; } - _oRemoved = _flash.parentNode.removeChild(_flash); + oRemoved = flash.parentNode.removeChild(flash); } catch(e) { } } - _oRemovedHTML = _oRemoved = _needsFlash = null; - _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; - _s.soundIDs = []; - _s.sounds = {}; - _flash = null; - for (i in _on_queue) { - if (_on_queue.hasOwnProperty(i)) { - for (j = _on_queue[i].length-1; j >= 0; j--) { - _on_queue[i][j].fired = false; + oRemovedHTML = oRemoved = needsFlash = flash = null; + sm2.enabled = didDCLoaded = didInit = waitingForEI = initPending = didAppend = appendSuccess = disabled = useGlobalHTML5Audio = sm2.swfLoaded = false; + sm2.soundIDs = []; + sm2.sounds = {}; + if (!resetEvents) { + for (i in on_queue) { + if (on_queue.hasOwnProperty(i)) { + for (j = 0, k = on_queue[i].length; j < k; j++) { + on_queue[i][j].fired = false; + } } } + } else { + on_queue = []; } - _win.setTimeout(_s.beginDelayedInit, 20); + sm2.html5 = { + 'usingFlash': null + }; + sm2.flash = {}; + sm2.html5Only = false; + sm2.ignoreFlash = false; + window.setTimeout(function() { + preInit(); + if (!excludeInit) { + sm2.beginDelayedInit(); + } + }, 20); + return sm2; + }; + this.reset = function() { + return sm2.reboot(true, true); }; this.getMoviePercent = function() { - return (_flash && typeof _flash.PercentLoaded !== 'undefined' ? _flash.PercentLoaded() : null); + return (flash && 'PercentLoaded' in flash ? flash.PercentLoaded() : null); }; this.beginDelayedInit = function() { - _windowLoaded = true; - _domContentLoaded(); + windowLoaded = true; + domContentLoaded(); setTimeout(function() { - if (_initPending) { + if (initPending) { return false; } - _createMovie(); - _initMovie(); - _initPending = true; + createMovie(); + initMovie(); + initPending = true; return true; }, 20); - _delayWaitForEI(); + delayWaitForEI(); }; this.destruct = function() { - _s.disable(true); + sm2.disable(true); }; SMSound = function(oOptions) { - var _t = this, _resetProperties, _add_html5_events, _remove_html5_events, _stop_html5_timer, _start_html5_timer, _attachOnPosition, _onplay_called = false, _onPositionItems = [], _onPositionFired = 0, _detachOnPosition, _applyFromTo, _lastURL = null, _lastHTML5State; - _lastHTML5State = { + var s = this, resetProperties, add_html5_events, remove_html5_events, stop_html5_timer, start_html5_timer, attachOnPosition, onplay_called = false, onPositionItems = [], onPositionFired = 0, detachOnPosition, applyFromTo, lastURL = null, lastHTML5State; + lastHTML5State = { duration: null, time: null }; this.id = oOptions.id; this.sID = this.id; this.url = oOptions.url; - this.options = _mixin(oOptions); + this.options = mixin(oOptions); this.instanceOptions = this.options; this._iO = this.instanceOptions; this.pan = this.options.pan; @@ -589,155 +598,154 @@ function SoundManager(smURL, smID) { this._debug = function() { }; this.load = function(oOptions) { - var oS = null, _iO; - if (typeof oOptions !== 'undefined') { - _t._iO = _mixin(oOptions, _t.options); - _t.instanceOptions = _t._iO; + var oSound = null, instanceOptions; + if (oOptions !== _undefined) { + s._iO = mixin(oOptions, s.options); } else { - oOptions = _t.options; - _t._iO = oOptions; - _t.instanceOptions = _t._iO; - if (_lastURL && _lastURL !== _t.url) { - _t._iO.url = _t.url; - _t.url = null; + oOptions = s.options; + s._iO = oOptions; + if (lastURL && lastURL !== s.url) { + s._iO.url = s.url; + s.url = null; } } - if (!_t._iO.url) { - _t._iO.url = _t.url; + if (!s._iO.url) { + s._iO.url = s.url; } - _t._iO.url = _parseURL(_t._iO.url); - if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { - if (_t.readyState === 3 && _t._iO.onload) { - _t._iO.onload.apply(_t, [(!!_t.duration)]); + s._iO.url = parseURL(s._iO.url); + s.instanceOptions = s._iO; + instanceOptions = s._iO; + if (instanceOptions.url === s.url && s.readyState !== 0 && s.readyState !== 2) { + if (s.readyState === 3 && instanceOptions.onload) { + instanceOptions.onload.apply(s, [(!!s.duration)]); } - return _t; + return s; } - _iO = _t._iO; - _lastURL = (_t.url && _t.url.toString ? _t.url.toString() : null); - _t.loaded = false; - _t.readyState = 1; - _t.playState = 0; - _t.id3 = {}; - if (_html5OK(_iO)) { - oS = _t._setup_html5(_iO); - if (!oS._called_load) { - _t._html5_canplay = false; - if (_t._a.src !== _iO.url) { - _t._a.src = _iO.url; - _t.setPosition(0); + s.loaded = false; + s.readyState = 1; + s.playState = 0; + s.id3 = {}; + if (html5OK(instanceOptions)) { + oSound = s._setup_html5(instanceOptions); + if (!oSound._called_load) { + s._html5_canplay = false; + if (s.url !== instanceOptions.url) { + s._a.src = instanceOptions.url; + s.setPosition(0); } - _t._a.autobuffer = 'auto'; - _t._a.preload = 'auto'; - oS._called_load = true; - if (_iO.autoPlay) { - _t.play(); + s._a.autobuffer = 'auto'; + s._a.preload = 'auto'; + s._a._called_load = true; + if (instanceOptions.autoPlay) { + s.play(); } } else { } } else { try { - _t.isHTML5 = false; - _t._iO = _policyFix(_loopFix(_iO)); - _iO = _t._iO; - if (_fV === 8) { - _flash._load(_t.id, _iO.url, _iO.stream, _iO.autoPlay, (_iO.whileloading?1:0), _iO.loops||1, _iO.usePolicyFile); + s.isHTML5 = false; + s._iO = policyFix(loopFix(instanceOptions)); + instanceOptions = s._iO; + if (fV === 8) { + flash._load(s.id, instanceOptions.url, instanceOptions.stream, instanceOptions.autoPlay, instanceOptions.usePolicyFile); } else { - _flash._load(_t.id, _iO.url, !!(_iO.stream), !!(_iO.autoPlay), _iO.loops||1, !!(_iO.autoLoad), _iO.usePolicyFile); + flash._load(s.id, instanceOptions.url, !!(instanceOptions.stream), !!(instanceOptions.autoPlay), instanceOptions.loops||1, !!(instanceOptions.autoLoad), instanceOptions.usePolicyFile); } } catch(e) { - _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true}); + catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true}); } } - _t.url = _iO.url; - return _t; + s.url = instanceOptions.url; + return s; }; this.unload = function() { - if (_t.readyState !== 0) { - if (!_t.isHTML5) { - if (_fV === 8) { - _flash._unload(_t.id, _emptyURL); + if (s.readyState !== 0) { + if (!s.isHTML5) { + if (fV === 8) { + flash._unload(s.id, emptyURL); } else { - _flash._unload(_t.id); + flash._unload(s.id); } } else { - _stop_html5_timer(); - if (_t._a) { - _t._a.pause(); - _html5Unload(_t._a, _emptyURL); - _t.url = _emptyURL; + stop_html5_timer(); + if (s._a) { + s._a.pause(); + html5Unload(s._a, emptyURL); + lastURL = emptyURL; } } - _resetProperties(); + resetProperties(); } - return _t; + return s; }; this.destruct = function(_bFromSM) { - if (!_t.isHTML5) { - _t._iO.onfailure = null; - _flash._destroySound(_t.id); + if (!s.isHTML5) { + s._iO.onfailure = null; + flash._destroySound(s.id); } else { - _stop_html5_timer(); - if (_t._a) { - _t._a.pause(); - _html5Unload(_t._a); - if (!_useGlobalHTML5Audio) { - _remove_html5_events(); + stop_html5_timer(); + if (s._a) { + s._a.pause(); + html5Unload(s._a); + if (!useGlobalHTML5Audio) { + remove_html5_events(); } - _t._a._t = null; - _t._a = null; + s._a._s = null; + s._a = null; } } if (!_bFromSM) { - _s.destroySound(_t.id, true); + sm2.destroySound(s.id, true); } }; this.play = function(oOptions, _updatePlayState) { var fN, allowMulti, a, onready, startOK = true, exit = null; - _updatePlayState = (typeof _updatePlayState === 'undefined' ? true : _updatePlayState); + _updatePlayState = (_updatePlayState === _undefined ? true : _updatePlayState); if (!oOptions) { oOptions = {}; } - if (_t.url) { - _t._iO.url = _t.url; + if (s.url) { + s._iO.url = s.url; } - _t._iO = _mixin(_t._iO, _t.options); - _t._iO = _mixin(oOptions, _t._iO); - _t._iO.url = _parseURL(_t._iO.url); - _t.instanceOptions = _t._iO; - if (_t._iO.serverURL && !_t.connected) { - if (!_t.getAutoPlay()) { - _t.setAutoPlay(true); + s._iO = mixin(s._iO, s.options); + s._iO = mixin(oOptions, s._iO); + s._iO.url = parseURL(s._iO.url); + s.instanceOptions = s._iO; + if (s._iO.serverURL && !s.connected) { + if (!s.getAutoPlay()) { + s.setAutoPlay(true); } - return _t; + return s; } - if (_html5OK(_t._iO)) { - _t._setup_html5(_t._iO); - _start_html5_timer(); + if (html5OK(s._iO)) { + s._setup_html5(s._iO); + start_html5_timer(); } - if (_t.playState === 1 && !_t.paused) { - allowMulti = _t._iO.multiShot; + if (s.playState === 1 && !s.paused) { + allowMulti = s._iO.multiShot; if (!allowMulti) { - exit = _t; + exit = s; } else { } } if (exit !== null) { return exit; } - if (oOptions.url && oOptions.url !== _t.url) { - _t.load(_t._iO); + if (oOptions.url && oOptions.url !== s.url) { + s.load(s._iO); } - if (!_t.loaded) { - if (_t.readyState === 0) { - if (!_t.isHTML5) { - _t._iO.autoPlay = true; - _t.load(_t._iO); + if (!s.loaded) { + if (s.readyState === 0) { + if (!s.isHTML5) { + s._iO.autoPlay = true; + s.load(s._iO); } else { - _t.load(_t._iO); + s.load(s._iO); } - } else if (_t.readyState === 2) { - exit = _t; + s.instanceOptions = s._iO; + } else if (s.readyState === 2) { + exit = s; } else { } } else { @@ -745,25 +753,25 @@ function SoundManager(smURL, smID) { if (exit !== null) { return exit; } - if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) { + if (!s.isHTML5 && fV === 9 && s.position > 0 && s.position === s.duration) { oOptions.position = 0; } - if (_t.paused && _t.position >= 0 && (!_t._iO.serverURL || _t.position > 0)) { - _t.resume(); + if (s.paused && s.position >= 0 && (!s._iO.serverURL || s.position > 0)) { + s.resume(); } else { - _t._iO = _mixin(oOptions, _t._iO); - if (_t._iO.from !== null && _t._iO.to !== null && _t.instanceCount === 0 && _t.playState === 0 && !_t._iO.serverURL) { + s._iO = mixin(oOptions, s._iO); + if (s._iO.from !== null && s._iO.to !== null && s.instanceCount === 0 && s.playState === 0 && !s._iO.serverURL) { onready = function() { - _t._iO = _mixin(oOptions, _t._iO); - _t.play(_t._iO); + s._iO = mixin(oOptions, s._iO); + s.play(s._iO); }; - if (_t.isHTML5 && !_t._html5_canplay) { - _t.load({ - _oncanplay: onready + if (s.isHTML5 && !s._html5_canplay) { + s.load({ + oncanplay: onready }); exit = false; - } else if (!_t.isHTML5 && !_t.loaded && (!_t.readyState || _t.readyState !== 2)) { - _t.load({ + } else if (!s.isHTML5 && !s.loaded && (!s.readyState || s.readyState !== 2)) { + s.load({ onload: onready }); exit = false; @@ -771,118 +779,119 @@ function SoundManager(smURL, smID) { if (exit !== null) { return exit; } - _t._iO = _applyFromTo(); + s._iO = applyFromTo(); } - if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) { - _t.instanceCount++; + if (!s.instanceCount || s._iO.multiShotEvents || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) { + s.instanceCount++; } - if (_t._iO.onposition && _t.playState === 0) { - _attachOnPosition(_t); + if (s._iO.onposition && s.playState === 0) { + attachOnPosition(s); } - _t.playState = 1; - _t.paused = false; - _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position) ? _t._iO.position : 0); - if (!_t.isHTML5) { - _t._iO = _policyFix(_loopFix(_t._iO)); + s.playState = 1; + s.paused = false; + s.position = (s._iO.position !== _undefined && !isNaN(s._iO.position) ? s._iO.position : 0); + if (!s.isHTML5) { + s._iO = policyFix(loopFix(s._iO)); } - if (_t._iO.onplay && _updatePlayState) { - _t._iO.onplay.apply(_t); - _onplay_called = true; + if (s._iO.onplay && _updatePlayState) { + s._iO.onplay.apply(s); + onplay_called = true; } - _t.setVolume(_t._iO.volume, true); - _t.setPan(_t._iO.pan, true); - if (!_t.isHTML5) { - startOK = _flash._start(_t.id, _t._iO.loops || 1, (_fV === 9 ? _t._iO.position : _t._iO.position / 1000), _t._iO.multiShot); - if (_fV === 9 && !startOK) { - if (_t._iO.onplayerror) { - _t._iO.onplayerror.apply(_t); + s.setVolume(s._iO.volume, true); + s.setPan(s._iO.pan, true); + if (!s.isHTML5) { + startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s._iO.position : s._iO.position / 1000), s._iO.multiShot); + if (fV === 9 && !startOK) { + if (s._iO.onplayerror) { + s._iO.onplayerror.apply(s); } } } else { - _start_html5_timer(); - a = _t._setup_html5(); - _t.setPosition(_t._iO.position); + start_html5_timer(); + a = s._setup_html5(); + s.setPosition(s._iO.position); a.play(); } } - return _t; + return s; }; this.start = this.play; this.stop = function(bAll) { - var _iO = _t._iO, _oP; - if (_t.playState === 1) { - _t._onbufferchange(0); - _t._resetOnPosition(0); - _t.paused = false; - if (!_t.isHTML5) { - _t.playState = 0; + var instanceOptions = s._iO, + originalPosition; + if (s.playState === 1) { + s._onbufferchange(0); + s._resetOnPosition(0); + s.paused = false; + if (!s.isHTML5) { + s.playState = 0; } - _detachOnPosition(); - if (_iO.to) { - _t.clearOnPosition(_iO.to); + detachOnPosition(); + if (instanceOptions.to) { + s.clearOnPosition(instanceOptions.to); } - if (!_t.isHTML5) { - _flash._stop(_t.id, bAll); - if (_iO.serverURL) { - _t.unload(); + if (!s.isHTML5) { + flash._stop(s.id, bAll); + if (instanceOptions.serverURL) { + s.unload(); } } else { - if (_t._a) { - _oP = _t.position; - _t.setPosition(0); - _t.position = _oP; - _t._a.pause(); - _t.playState = 0; - _t._onTimer(); - _stop_html5_timer(); + if (s._a) { + originalPosition = s.position; + s.setPosition(0); + s.position = originalPosition; + s._a.pause(); + s.playState = 0; + s._onTimer(); + stop_html5_timer(); } } - _t.instanceCount = 0; - _t._iO = {}; - if (_iO.onstop) { - _iO.onstop.apply(_t); + s.instanceCount = 0; + s._iO = {}; + if (instanceOptions.onstop) { + instanceOptions.onstop.apply(s); } } - return _t; + return s; }; this.setAutoPlay = function(autoPlay) { - _t._iO.autoPlay = autoPlay; - if (!_t.isHTML5) { - _flash._setAutoPlay(_t.id, autoPlay); + s._iO.autoPlay = autoPlay; + if (!s.isHTML5) { + flash._setAutoPlay(s.id, autoPlay); if (autoPlay) { - if (!_t.instanceCount && _t.readyState === 1) { - _t.instanceCount++; + if (!s.instanceCount && s.readyState === 1) { + s.instanceCount++; } } } }; this.getAutoPlay = function() { - return _t._iO.autoPlay; + return s._iO.autoPlay; }; this.setPosition = function(nMsecOffset) { - if (typeof nMsecOffset === 'undefined') { + if (nMsecOffset === _undefined) { nMsecOffset = 0; } var original_pos, position, position1K, - offset = (_t.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); - original_pos = _t.position; - _t.position = offset; - position1K = _t.position/1000; - _t._resetOnPosition(_t.position); - _t._iO.position = offset; - if (!_t.isHTML5) { - position = (_fV === 9 ? _t.position : position1K); - if (_t.readyState && _t.readyState !== 2) { - _flash._setPosition(_t.id, position, (_t.paused || !_t.playState), _t._iO.multiShot); + offset = (s.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(s.duration || s._iO.duration, Math.max(nMsecOffset, 0))); + original_pos = s.position; + s.position = offset; + position1K = s.position/1000; + s._resetOnPosition(s.position); + s._iO.position = offset; + if (!s.isHTML5) { + position = (fV === 9 ? s.position : position1K); + if (s.readyState && s.readyState !== 2) { + flash._setPosition(s.id, position, (s.paused || !s.playState), s._iO.multiShot); } - } else if (_t._a) { - if (_t._html5_canplay) { - if (_t._a.currentTime !== position1K) { + } else if (s._a) { + if (s._html5_canplay) { + if (s._a.currentTime !== position1K) { try { - _t._a.currentTime = position1K; - if (_t.playState === 0 || _t.paused) { - _t._a.pause(); + s._a.currentTime = position1K; + if (s.playState === 0 || s.paused) { + s._a.pause(); } } catch(e) { } @@ -890,135 +899,135 @@ function SoundManager(smURL, smID) { } else { } } - if (_t.isHTML5) { - if (_t.paused) { - _t._onTimer(true); + if (s.isHTML5) { + if (s.paused) { + s._onTimer(true); } } - return _t; + return s; }; this.pause = function(_bCallFlash) { - if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { - return _t; + if (s.paused || (s.playState === 0 && s.readyState !== 1)) { + return s; } - _t.paused = true; - if (!_t.isHTML5) { - if (_bCallFlash || typeof _bCallFlash === 'undefined') { - _flash._pause(_t.id, _t._iO.multiShot); + s.paused = true; + if (!s.isHTML5) { + if (_bCallFlash || _bCallFlash === _undefined) { + flash._pause(s.id, s._iO.multiShot); } } else { - _t._setup_html5().pause(); - _stop_html5_timer(); + s._setup_html5().pause(); + stop_html5_timer(); } - if (_t._iO.onpause) { - _t._iO.onpause.apply(_t); + if (s._iO.onpause) { + s._iO.onpause.apply(s); } - return _t; + return s; }; this.resume = function() { - var _iO = _t._iO; - if (!_t.paused) { - return _t; + var instanceOptions = s._iO; + if (!s.paused) { + return s; } - _t.paused = false; - _t.playState = 1; - if (!_t.isHTML5) { - if (_iO.isMovieStar && !_iO.serverURL) { - _t.setPosition(_t.position); + s.paused = false; + s.playState = 1; + if (!s.isHTML5) { + if (instanceOptions.isMovieStar && !instanceOptions.serverURL) { + s.setPosition(s.position); } - _flash._pause(_t.id, _iO.multiShot); + flash._pause(s.id, instanceOptions.multiShot); } else { - _t._setup_html5().play(); - _start_html5_timer(); + s._setup_html5().play(); + start_html5_timer(); } - if (!_onplay_called && _iO.onplay) { - _iO.onplay.apply(_t); - _onplay_called = true; - } else if (_iO.onresume) { - _iO.onresume.apply(_t); + if (!onplay_called && instanceOptions.onplay) { + instanceOptions.onplay.apply(s); + onplay_called = true; + } else if (instanceOptions.onresume) { + instanceOptions.onresume.apply(s); } - return _t; + return s; }; this.togglePause = function() { - if (_t.playState === 0) { - _t.play({ - position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000) + if (s.playState === 0) { + s.play({ + position: (fV === 9 && !s.isHTML5 ? s.position : s.position / 1000) }); - return _t; + return s; } - if (_t.paused) { - _t.resume(); + if (s.paused) { + s.resume(); } else { - _t.pause(); + s.pause(); } - return _t; + return s; }; this.setPan = function(nPan, bInstanceOnly) { - if (typeof nPan === 'undefined') { + if (nPan === _undefined) { nPan = 0; } - if (typeof bInstanceOnly === 'undefined') { + if (bInstanceOnly === _undefined) { bInstanceOnly = false; } - if (!_t.isHTML5) { - _flash._setPan(_t.id, nPan); + if (!s.isHTML5) { + flash._setPan(s.id, nPan); } - _t._iO.pan = nPan; + s._iO.pan = nPan; if (!bInstanceOnly) { - _t.pan = nPan; - _t.options.pan = nPan; + s.pan = nPan; + s.options.pan = nPan; } - return _t; + return s; }; this.setVolume = function(nVol, _bInstanceOnly) { - if (typeof nVol === 'undefined') { + if (nVol === _undefined) { nVol = 100; } - if (typeof _bInstanceOnly === 'undefined') { + if (_bInstanceOnly === _undefined) { _bInstanceOnly = false; } - if (!_t.isHTML5) { - _flash._setVolume(_t.id, (_s.muted && !_t.muted) || _t.muted?0:nVol); - } else if (_t._a) { - _t._a.volume = Math.max(0, Math.min(1, nVol/100)); + if (!s.isHTML5) { + flash._setVolume(s.id, (sm2.muted && !s.muted) || s.muted?0:nVol); + } else if (s._a) { + s._a.volume = Math.max(0, Math.min(1, nVol/100)); } - _t._iO.volume = nVol; + s._iO.volume = nVol; if (!_bInstanceOnly) { - _t.volume = nVol; - _t.options.volume = nVol; + s.volume = nVol; + s.options.volume = nVol; } - return _t; + return s; }; this.mute = function() { - _t.muted = true; - if (!_t.isHTML5) { - _flash._setVolume(_t.id, 0); - } else if (_t._a) { - _t._a.muted = true; + s.muted = true; + if (!s.isHTML5) { + flash._setVolume(s.id, 0); + } else if (s._a) { + s._a.muted = true; } - return _t; + return s; }; this.unmute = function() { - _t.muted = false; - var hasIO = (typeof _t._iO.volume !== 'undefined'); - if (!_t.isHTML5) { - _flash._setVolume(_t.id, hasIO?_t._iO.volume:_t.options.volume); - } else if (_t._a) { - _t._a.muted = false; + s.muted = false; + var hasIO = (s._iO.volume !== _undefined); + if (!s.isHTML5) { + flash._setVolume(s.id, hasIO?s._iO.volume:s.options.volume); + } else if (s._a) { + s._a.muted = false; } - return _t; + return s; }; this.toggleMute = function() { - return (_t.muted?_t.unmute():_t.mute()); + return (s.muted?s.unmute():s.mute()); }; this.onPosition = function(nPosition, oMethod, oScope) { - _onPositionItems.push({ + onPositionItems.push({ position: parseInt(nPosition, 10), method: oMethod, - scope: (typeof oScope !== 'undefined' ? oScope : _t), + scope: (oScope !== _undefined ? oScope : s), fired: false }); - return _t; + return s; }; this.onposition = this.onPosition; this.clearOnPosition = function(nPosition, oMethod) { @@ -1027,164 +1036,164 @@ function SoundManager(smURL, smID) { if (isNaN(nPosition)) { return false; } - for (i=0; i < _onPositionItems.length; i++) { - if (nPosition === _onPositionItems[i].position) { - if (!oMethod || (oMethod === _onPositionItems[i].method)) { - if (_onPositionItems[i].fired) { - _onPositionFired--; + for (i=0; i < onPositionItems.length; i++) { + if (nPosition === onPositionItems[i].position) { + if (!oMethod || (oMethod === onPositionItems[i].method)) { + if (onPositionItems[i].fired) { + onPositionFired--; } - _onPositionItems.splice(i, 1); + onPositionItems.splice(i, 1); } } } }; this._processOnPosition = function() { - var i, item, j = _onPositionItems.length; - if (!j || !_t.playState || _onPositionFired >= j) { + var i, item, j = onPositionItems.length; + if (!j || !s.playState || onPositionFired >= j) { return false; } for (i=j-1; i >= 0; i--) { - item = _onPositionItems[i]; - if (!item.fired && _t.position >= item.position) { + item = onPositionItems[i]; + if (!item.fired && s.position >= item.position) { item.fired = true; - _onPositionFired++; + onPositionFired++; item.method.apply(item.scope, [item.position]); } } return true; }; this._resetOnPosition = function(nPosition) { - var i, item, j = _onPositionItems.length; + var i, item, j = onPositionItems.length; if (!j) { return false; } for (i=j-1; i >= 0; i--) { - item = _onPositionItems[i]; + item = onPositionItems[i]; if (item.fired && nPosition <= item.position) { item.fired = false; - _onPositionFired--; + onPositionFired--; } } return true; }; - _applyFromTo = function() { - var _iO = _t._iO, - f = _iO.from, - t = _iO.to, + applyFromTo = function() { + var instanceOptions = s._iO, + f = instanceOptions.from, + t = instanceOptions.to, start, end; end = function() { - _t.clearOnPosition(t, end); - _t.stop(); + s.clearOnPosition(t, end); + s.stop(); }; start = function() { if (t !== null && !isNaN(t)) { - _t.onPosition(t, end); + s.onPosition(t, end); } }; if (f !== null && !isNaN(f)) { - _iO.position = f; - _iO.multiShot = false; + instanceOptions.position = f; + instanceOptions.multiShot = false; start(); } - return _iO; + return instanceOptions; }; - _attachOnPosition = function() { + attachOnPosition = function() { var item, - op = _t._iO.onposition; + op = s._iO.onposition; if (op) { for (item in op) { if (op.hasOwnProperty(item)) { - _t.onPosition(parseInt(item, 10), op[item]); + s.onPosition(parseInt(item, 10), op[item]); } } } }; - _detachOnPosition = function() { + detachOnPosition = function() { var item, - op = _t._iO.onposition; + op = s._iO.onposition; if (op) { for (item in op) { if (op.hasOwnProperty(item)) { - _t.clearOnPosition(parseInt(item, 10)); + s.clearOnPosition(parseInt(item, 10)); } } } }; - _start_html5_timer = function() { - if (_t.isHTML5) { - _startTimer(_t); + start_html5_timer = function() { + if (s.isHTML5) { + startTimer(s); } }; - _stop_html5_timer = function() { - if (_t.isHTML5) { - _stopTimer(_t); + stop_html5_timer = function() { + if (s.isHTML5) { + stopTimer(s); } }; - _resetProperties = function(retainPosition) { + resetProperties = function(retainPosition) { if (!retainPosition) { - _onPositionItems = []; - _onPositionFired = 0; + onPositionItems = []; + onPositionFired = 0; } - _onplay_called = false; - _t._hasTimer = null; - _t._a = null; - _t._html5_canplay = false; - _t.bytesLoaded = null; - _t.bytesTotal = null; - _t.duration = (_t._iO && _t._iO.duration ? _t._iO.duration : null); - _t.durationEstimate = null; - _t.buffered = []; - _t.eqData = []; - _t.eqData.left = []; - _t.eqData.right = []; - _t.failures = 0; - _t.isBuffering = false; - _t.instanceOptions = {}; - _t.instanceCount = 0; - _t.loaded = false; - _t.metadata = {}; - _t.readyState = 0; - _t.muted = false; - _t.paused = false; - _t.peakData = { + onplay_called = false; + s._hasTimer = null; + s._a = null; + s._html5_canplay = false; + s.bytesLoaded = null; + s.bytesTotal = null; + s.duration = (s._iO && s._iO.duration ? s._iO.duration : null); + s.durationEstimate = null; + s.buffered = []; + s.eqData = []; + s.eqData.left = []; + s.eqData.right = []; + s.failures = 0; + s.isBuffering = false; + s.instanceOptions = {}; + s.instanceCount = 0; + s.loaded = false; + s.metadata = {}; + s.readyState = 0; + s.muted = false; + s.paused = false; + s.peakData = { left: 0, right: 0 }; - _t.waveformData = { + s.waveformData = { left: [], right: [] }; - _t.playState = 0; - _t.position = null; - _t.id3 = {}; + s.playState = 0; + s.position = null; + s.id3 = {}; }; - _resetProperties(); + resetProperties(); this._onTimer = function(bForce) { var duration, isNew = false, time, x = {}; - if (_t._hasTimer || bForce) { - if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { - duration = _t._get_html5_duration(); - if (duration !== _lastHTML5State.duration) { - _lastHTML5State.duration = duration; - _t.duration = duration; + if (s._hasTimer || bForce) { + if (s._a && (bForce || ((s.playState > 0 || s.readyState === 1) && !s.paused))) { + duration = s._get_html5_duration(); + if (duration !== lastHTML5State.duration) { + lastHTML5State.duration = duration; + s.duration = duration; isNew = true; } - _t.durationEstimate = _t.duration; - time = (_t._a.currentTime * 1000 || 0); - if (time !== _lastHTML5State.time) { - _lastHTML5State.time = time; + s.durationEstimate = s.duration; + time = (s._a.currentTime * 1000 || 0); + if (time !== lastHTML5State.time) { + lastHTML5State.time = time; isNew = true; } if (isNew || bForce) { - _t._whileplaying(time,x,x,x,x); + s._whileplaying(time,x,x,x,x); } } return isNew; } }; this._get_html5_duration = function() { - var _iO = _t._iO, - d = (_t._a && _t._a.duration ? _t._a.duration*1000 : (_iO && _iO.duration ? _iO.duration : null)), + var instanceOptions = s._iO, + d = (s._a && s._a.duration ? s._a.duration*1000 : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)), result = (d && !isNaN(d) && d !== Infinity ? d : null); return result; }; @@ -1192,338 +1201,343 @@ function SoundManager(smURL, smID) { a.loop = (nLoops > 1 ? 'loop' : ''); }; this._setup_html5 = function(oOptions) { - var _iO = _mixin(_t._iO, oOptions), d = decodeURI, - _a = _useGlobalHTML5Audio ? _s._global_a : _t._a, - _dURL = d(_iO.url), - _oldIO = (_a && _a._t ? _a._t.instanceOptions : null), - result; - if (_a) { - if (_a._t) { - if (!_useGlobalHTML5Audio && _dURL === d(_lastURL)) { - result = _a; - } else if (_useGlobalHTML5Audio && _oldIO.url === _iO.url && (!_lastURL || (_lastURL === _oldIO.url))) { - result = _a; - } - if (result) { - _t._apply_loop(_a, _iO.loops); - return result; + var instanceOptions = mixin(s._iO, oOptions), d = decodeURI, + a = useGlobalHTML5Audio ? globalHTML5Audio : s._a, + dURL = d(instanceOptions.url), + sameURL; + if (useGlobalHTML5Audio) { + if (dURL === lastGlobalHTML5URL) { + sameURL = true; + } + } else if (dURL === lastURL) { + sameURL = true; + } + if (a) { + if (a._s) { + if (useGlobalHTML5Audio) { + if (a._s && a._s.playState && !sameURL) { + a._s.stop(); + } + } else if (!useGlobalHTML5Audio && dURL === d(lastURL)) { + s._apply_loop(a, instanceOptions.loops); + return a; } } - if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) { - _a._t.stop(); + if (!sameURL) { + resetProperties(false); + a.src = instanceOptions.url; + s.url = instanceOptions.url; + lastURL = instanceOptions.url; + lastGlobalHTML5URL = instanceOptions.url; + a._called_load = false; } - _resetProperties((_oldIO && _oldIO.url ? _iO.url === _oldIO.url : (_lastURL ? _lastURL === _iO.url : false))); - _a.src = _iO.url; - _t.url = _iO.url; - _lastURL = _iO.url; - _a._called_load = false; } else { - if (_iO.autoLoad || _iO.autoPlay) { - _t._a = new Audio(_iO.url); + if (instanceOptions.autoLoad || instanceOptions.autoPlay) { + s._a = new Audio(instanceOptions.url); } else { - _t._a = (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()); + s._a = (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()); } - _a = _t._a; - _a._called_load = false; - if (_useGlobalHTML5Audio) { - _s._global_a = _a; + a = s._a; + a._called_load = false; + if (useGlobalHTML5Audio) { + globalHTML5Audio = a; } } - _t.isHTML5 = true; - _t._a = _a; - _a._t = _t; - _add_html5_events(); - _t._apply_loop(_a, _iO.loops); - if (_iO.autoLoad || _iO.autoPlay) { - _t.load(); + s.isHTML5 = true; + s._a = a; + a._s = s; + add_html5_events(); + s._apply_loop(a, instanceOptions.loops); + if (instanceOptions.autoLoad || instanceOptions.autoPlay) { + s.load(); } else { - _a.autobuffer = false; - _a.preload = 'auto'; + a.autobuffer = false; + a.preload = 'auto'; } - return _a; + return a; }; - _add_html5_events = function() { - if (_t._a._added_events) { + add_html5_events = function() { + if (s._a._added_events) { return false; } var f; function add(oEvt, oFn, bCapture) { - return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null; + return s._a ? s._a.addEventListener(oEvt, oFn, bCapture||false) : null; } - _t._a._added_events = true; - for (f in _html5_events) { - if (_html5_events.hasOwnProperty(f)) { - add(f, _html5_events[f]); + s._a._added_events = true; + for (f in html5_events) { + if (html5_events.hasOwnProperty(f)) { + add(f, html5_events[f]); } } return true; }; - _remove_html5_events = function() { + remove_html5_events = function() { var f; function remove(oEvt, oFn, bCapture) { - return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null); + return (s._a ? s._a.removeEventListener(oEvt, oFn, bCapture||false) : null); } - _t._a._added_events = false; - for (f in _html5_events) { - if (_html5_events.hasOwnProperty(f)) { - remove(f, _html5_events[f]); + s._a._added_events = false; + for (f in html5_events) { + if (html5_events.hasOwnProperty(f)) { + remove(f, html5_events[f]); } } }; this._onload = function(nSuccess) { var fN, - loadOK = (!!(nSuccess) || (!_t.isHTML5 && _fV === 8 && _t.duration)); - _t.loaded = loadOK; - _t.readyState = loadOK?3:2; - _t._onbufferchange(0); - if (_t._iO.onload) { - _t._iO.onload.apply(_t, [loadOK]); + loadOK = !!nSuccess || (!s.isHTML5 && fV === 8 && s.duration); + s.loaded = loadOK; + s.readyState = loadOK?3:2; + s._onbufferchange(0); + if (s._iO.onload) { + s._iO.onload.apply(s, [loadOK]); } return true; }; this._onbufferchange = function(nIsBuffering) { - if (_t.playState === 0) { + if (s.playState === 0) { return false; } - if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { + if ((nIsBuffering && s.isBuffering) || (!nIsBuffering && !s.isBuffering)) { return false; } - _t.isBuffering = (nIsBuffering === 1); - if (_t._iO.onbufferchange) { - _t._iO.onbufferchange.apply(_t); + s.isBuffering = (nIsBuffering === 1); + if (s._iO.onbufferchange) { + s._iO.onbufferchange.apply(s); } return true; }; this._onsuspend = function() { - if (_t._iO.onsuspend) { - _t._iO.onsuspend.apply(_t); + if (s._iO.onsuspend) { + s._iO.onsuspend.apply(s); } return true; }; this._onfailure = function(msg, level, code) { - _t.failures++; - if (_t._iO.onfailure && _t.failures === 1) { - _t._iO.onfailure(_t, msg, level, code); + s.failures++; + if (s._iO.onfailure && s.failures === 1) { + s._iO.onfailure(s, msg, level, code); } else { } }; this._onfinish = function() { - var _io_onfinish = _t._iO.onfinish; - _t._onbufferchange(0); - _t._resetOnPosition(0); - if (_t.instanceCount) { - _t.instanceCount--; - if (!_t.instanceCount) { - _detachOnPosition(); - _t.playState = 0; - _t.paused = false; - _t.instanceCount = 0; - _t.instanceOptions = {}; - _t._iO = {}; - _stop_html5_timer(); - if (_t.isHTML5) { - _t.position = 0; + var io_onfinish = s._iO.onfinish; + s._onbufferchange(0); + s._resetOnPosition(0); + if (s.instanceCount) { + s.instanceCount--; + if (!s.instanceCount) { + detachOnPosition(); + s.playState = 0; + s.paused = false; + s.instanceCount = 0; + s.instanceOptions = {}; + s._iO = {}; + stop_html5_timer(); + if (s.isHTML5) { + s.position = 0; } } - if (!_t.instanceCount || _t._iO.multiShotEvents) { - if (_io_onfinish) { - _io_onfinish.apply(_t); + if (!s.instanceCount || s._iO.multiShotEvents) { + if (io_onfinish) { + io_onfinish.apply(s); } } } }; this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { - var _iO = _t._iO; - _t.bytesLoaded = nBytesLoaded; - _t.bytesTotal = nBytesTotal; - _t.duration = Math.floor(nDuration); - _t.bufferLength = nBufferLength; - if (!_t.isHTML5 && !_iO.isMovieStar) { - if (_iO.duration) { - _t.durationEstimate = (_t.duration > _iO.duration) ? _t.duration : _iO.duration; + var instanceOptions = s._iO; + s.bytesLoaded = nBytesLoaded; + s.bytesTotal = nBytesTotal; + s.duration = Math.floor(nDuration); + s.bufferLength = nBufferLength; + if (!s.isHTML5 && !instanceOptions.isMovieStar) { + if (instanceOptions.duration) { + s.durationEstimate = (s.duration > instanceOptions.duration) ? s.duration : instanceOptions.duration; } else { - _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); + s.durationEstimate = parseInt((s.bytesTotal / s.bytesLoaded) * s.duration, 10); } } else { - _t.durationEstimate = _t.duration; + s.durationEstimate = s.duration; } - if (!_t.isHTML5) { - _t.buffered = [{ + if (!s.isHTML5) { + s.buffered = [{ 'start': 0, - 'end': _t.duration + 'end': s.duration }]; } - if ((_t.readyState !== 3 || _t.isHTML5) && _iO.whileloading) { - _iO.whileloading.apply(_t); + if ((s.readyState !== 3 || s.isHTML5) && instanceOptions.whileloading) { + instanceOptions.whileloading.apply(s); } }; this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { - var _iO = _t._iO, + var instanceOptions = s._iO, eqLeft; if (isNaN(nPosition) || nPosition === null) { return false; } - _t.position = Math.max(0, nPosition); - _t._processOnPosition(); - if (!_t.isHTML5 && _fV > 8) { - if (_iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { - _t.peakData = { + s.position = Math.max(0, nPosition); + s._processOnPosition(); + if (!s.isHTML5 && fV > 8) { + if (instanceOptions.usePeakData && oPeakData !== _undefined && oPeakData) { + s.peakData = { left: oPeakData.leftPeak, right: oPeakData.rightPeak }; } - if (_iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { - _t.waveformData = { + if (instanceOptions.useWaveformData && oWaveformDataLeft !== _undefined && oWaveformDataLeft) { + s.waveformData = { left: oWaveformDataLeft.split(','), right: oWaveformDataRight.split(',') }; } - if (_iO.useEQData) { - if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { + if (instanceOptions.useEQData) { + if (oEQData !== _undefined && oEQData && oEQData.leftEQ) { eqLeft = oEQData.leftEQ.split(','); - _t.eqData = eqLeft; - _t.eqData.left = eqLeft; - if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { - _t.eqData.right = oEQData.rightEQ.split(','); + s.eqData = eqLeft; + s.eqData.left = eqLeft; + if (oEQData.rightEQ !== _undefined && oEQData.rightEQ) { + s.eqData.right = oEQData.rightEQ.split(','); } } } } - if (_t.playState === 1) { - if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) { - _t._onbufferchange(0); + if (s.playState === 1) { + if (!s.isHTML5 && fV === 8 && !s.position && s.isBuffering) { + s._onbufferchange(0); } - if (_iO.whileplaying) { - _iO.whileplaying.apply(_t); + if (instanceOptions.whileplaying) { + instanceOptions.whileplaying.apply(s); } } return true; }; this._oncaptiondata = function(oData) { - _t.captiondata = oData; - if (_t._iO.oncaptiondata) { - _t._iO.oncaptiondata.apply(_t, [oData]); + s.captiondata = oData; + if (s._iO.oncaptiondata) { + s._iO.oncaptiondata.apply(s, [oData]); } - }; + }; this._onmetadata = function(oMDProps, oMDData) { var oData = {}, i, j; for (i = 0, j = oMDProps.length; i < j; i++) { oData[oMDProps[i]] = oMDData[i]; } - _t.metadata = oData; - if (_t._iO.onmetadata) { - _t._iO.onmetadata.apply(_t); + s.metadata = oData; + if (s._iO.onmetadata) { + s._iO.onmetadata.apply(s); } - }; + }; this._onid3 = function(oID3Props, oID3Data) { var oData = [], i, j; for (i = 0, j = oID3Props.length; i < j; i++) { oData[oID3Props[i]] = oID3Data[i]; } - _t.id3 = _mixin(_t.id3, oData); - if (_t._iO.onid3) { - _t._iO.onid3.apply(_t); + s.id3 = mixin(s.id3, oData); + if (s._iO.onid3) { + s._iO.onid3.apply(s); } }; this._onconnect = function(bSuccess) { bSuccess = (bSuccess === 1); - _t.connected = bSuccess; + s.connected = bSuccess; if (bSuccess) { - _t.failures = 0; - if (_idCheck(_t.id)) { - if (_t.getAutoPlay()) { - _t.play(undefined, _t.getAutoPlay()); - } else if (_t._iO.autoLoad) { - _t.load(); + s.failures = 0; + if (idCheck(s.id)) { + if (s.getAutoPlay()) { + s.play(_undefined, s.getAutoPlay()); + } else if (s._iO.autoLoad) { + s.load(); } } - if (_t._iO.onconnect) { - _t._iO.onconnect.apply(_t, [bSuccess]); + if (s._iO.onconnect) { + s._iO.onconnect.apply(s, [bSuccess]); } } }; this._ondataerror = function(sError) { - if (_t.playState > 0) { - if (_t._iO.ondataerror) { - _t._iO.ondataerror.apply(_t); + if (s.playState > 0) { + if (s._iO.ondataerror) { + s._iO.ondataerror.apply(s); } } }; }; - _getDocument = function() { - return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]); + getDocument = function() { + return (doc.body || doc._docElement || doc.getElementsByTagName('div')[0]); }; - _id = function(sID) { - return _doc.getElementById(sID); + id = function(sID) { + return doc.getElementById(sID); }; - _mixin = function(oMain, oAdd) { + mixin = function(oMain, oAdd) { var o1 = (oMain || {}), o2, o; - o2 = (typeof oAdd === 'undefined' ? _s.defaultOptions : oAdd); + o2 = (oAdd === _undefined ? sm2.defaultOptions : oAdd); for (o in o2) { - if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { + if (o2.hasOwnProperty(o) && o1[o] === _undefined) { if (typeof o2[o] !== 'object' || o2[o] === null) { o1[o] = o2[o]; } else { - o1[o] = _mixin(o1[o], o2[o]); + o1[o] = mixin(o1[o], o2[o]); } } } return o1; }; - _extraOptions = { + extraOptions = { 'onready': 1, 'ontimeout': 1, 'defaultOptions': 1, 'flash9Options': 1, 'movieStarOptions': 1 }; - _assign = function(o, oParent) { + assign = function(o, oParent) { var i, result = true, - hasParent = (typeof oParent !== 'undefined'), - setupOptions = _s.setupOptions, - extraOptions = _extraOptions; + hasParent = (oParent !== _undefined), + setupOptions = sm2.setupOptions, + bonusOptions = extraOptions; for (i in o) { if (o.hasOwnProperty(i)) { - if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array) { - if (hasParent && typeof extraOptions[oParent] !== 'undefined') { - _s[oParent][i] = o[i]; - } else if (typeof setupOptions[i] !== 'undefined') { - _s.setupOptions[i] = o[i]; - _s[i] = o[i]; - } else if (typeof extraOptions[i] === 'undefined') { - _complain(_str((typeof _s[i] === 'undefined' ? 'setupUndef' : 'setupError'), i), 2); + if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array || o[i] instanceof RegExp) { + if (hasParent && bonusOptions[oParent] !== _undefined) { + sm2[oParent][i] = o[i]; + } else if (setupOptions[i] !== _undefined) { + sm2.setupOptions[i] = o[i]; + sm2[i] = o[i]; + } else if (bonusOptions[i] === _undefined) { + complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2); result = false; } else { - if (_s[i] instanceof Function) { - _s[i].apply(_s, (o[i] instanceof Array? o[i] : [o[i]])); + if (sm2[i] instanceof Function) { + sm2[i].apply(sm2, (o[i] instanceof Array? o[i] : [o[i]])); } else { - _s[i] = o[i]; + sm2[i] = o[i]; } } } else { - if (typeof extraOptions[i] === 'undefined') { - _complain(_str((typeof _s[i] === 'undefined' ? 'setupUndef' : 'setupError'), i), 2); + if (bonusOptions[i] === _undefined) { + complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2); result = false; } else { - return _assign(o[i], i); + return assign(o[i], i); } } } } return result; }; - function _preferFlashCheck(kind) { - return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind])); + function preferFlashCheck(kind) { + return (sm2.preferFlash && hasFlash && !sm2.ignoreFlash && (sm2.flash[kind] !== _undefined && sm2.flash[kind])); } - _event = (function() { - var old = (_win.attachEvent), + event = (function() { + var old = (window.attachEvent), evt = { add: (old?'attachEvent':'addEventListener'), remove: (old?'detachEvent':'removeEventListener') }; function getArgs(oArgs) { - var args = _slice.call(oArgs), + var args = slice.call(oArgs), len = args.length; if (old) { args[1] = 'on' + args[1]; @@ -1555,11 +1569,11 @@ function SoundManager(smURL, smID) { 'remove': remove }; }()); - function _html5_event(oFn) { + function html5_event(oFn) { return function(e) { - var t = this._t, + var s = this._s, result; - if (!t || !t._a) { + if (!s || !s._a) { result = null; } else { result = oFn.call(this, e); @@ -1567,72 +1581,72 @@ function SoundManager(smURL, smID) { return result; }; } - _html5_events = { - abort: _html5_event(function() { + html5_events = { + abort: html5_event(function() { }), - canplay: _html5_event(function() { - var t = this._t, + canplay: html5_event(function() { + var s = this._s, position1K; - if (t._html5_canplay) { + if (s._html5_canplay) { return true; } - t._html5_canplay = true; - t._onbufferchange(0); - position1K = (typeof t._iO.position !== 'undefined' && !isNaN(t._iO.position)?t._iO.position/1000:null); - if (t.position && this.currentTime !== position1K) { + s._html5_canplay = true; + s._onbufferchange(0); + position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/1000:null); + if (s.position && this.currentTime !== position1K) { try { this.currentTime = position1K; } catch(ee) { } } - if (t._iO._oncanplay) { - t._iO._oncanplay(); + if (s._iO._oncanplay) { + s._iO._oncanplay(); } }), - canplaythrough: _html5_event(function() { - var t = this._t; - if (!t.loaded) { - t._onbufferchange(0); - t._whileloading(t.bytesLoaded, t.bytesTotal, t._get_html5_duration()); - t._onload(true); + canplaythrough: html5_event(function() { + var s = this._s; + if (!s.loaded) { + s._onbufferchange(0); + s._whileloading(s.bytesLoaded, s.bytesTotal, s._get_html5_duration()); + s._onload(true); } }), - ended: _html5_event(function() { - var t = this._t; - t._onfinish(); + ended: html5_event(function() { + var s = this._s; + s._onfinish(); }), - error: _html5_event(function() { - this._t._onload(false); + error: html5_event(function() { + this._s._onload(false); }), - loadeddata: _html5_event(function() { - var t = this._t; - if (!t._loaded && !_isSafari) { - t.duration = t._get_html5_duration(); + loadeddata: html5_event(function() { + var s = this._s; + if (!s._loaded && !isSafari) { + s.duration = s._get_html5_duration(); } }), - loadedmetadata: _html5_event(function() { + loadedmetadata: html5_event(function() { }), - loadstart: _html5_event(function() { - this._t._onbufferchange(1); + loadstart: html5_event(function() { + this._s._onbufferchange(1); }), - play: _html5_event(function() { - this._t._onbufferchange(0); + play: html5_event(function() { + this._s._onbufferchange(0); }), - playing: _html5_event(function() { - this._t._onbufferchange(0); + playing: html5_event(function() { + this._s._onbufferchange(0); }), - progress: _html5_event(function(e) { - var t = this._t, + progress: html5_event(function(e) { + var s = this._s, i, j, str, buffered = 0, isProgress = (e.type === 'progress'), ranges = e.target.buffered, loaded = (e.loaded||0), total = (e.total||1), scale = 1000; - t.buffered = []; + s.buffered = []; if (ranges && ranges.length) { for (i=0, j=ranges.length; i= 0; i--) { support['audio/'+aF[item].related[i]] = support[item]; - _s.html5[aF[item].related[i]] = support[item]; - _s.flash[aF[item].related[i]] = support[item]; + sm2.html5[aF[item].related[i]] = support[item]; + sm2.flash[aF[item].related[i]] = support[item]; } } } } - support.canPlayType = (a?_cp:null); - _s.html5 = _mixin(_s.html5, support); + support.canPlayType = (a?cp:null); + sm2.html5 = mixin(sm2.html5, support); return true; }; - _strings = { + strings = { }; - _str = function() { + str = function() { }; - _loopFix = function(sOpt) { - if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { + loopFix = function(sOpt) { + if (fV === 8 && sOpt.loops > 1 && sOpt.stream) { sOpt.stream = false; } return sOpt; }; - _policyFix = function(sOpt, sPre) { + policyFix = function(sOpt, sPre) { if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { sOpt.usePolicyFile = true; } return sOpt; }; - _complain = function(sMsg) { + complain = function(sMsg) { }; - _doNothing = function() { + doNothing = function() { return false; }; - _disableObject = function(o) { + disableObject = function(o) { var oProp; for (oProp in o) { if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { - o[oProp] = _doNothing; + o[oProp] = doNothing; } } oProp = null; }; - _failSafely = function(bNoDisable) { - if (typeof bNoDisable === 'undefined') { + failSafely = function(bNoDisable) { + if (bNoDisable === _undefined) { bNoDisable = false; } - if (_disabled || bNoDisable) { - _s.disable(bNoDisable); + if (disabled || bNoDisable) { + sm2.disable(bNoDisable); } }; - _normalizeMovieURL = function(smURL) { + normalizeMovieURL = function(smURL) { var urlParams = null, url; if (smURL) { if (smURL.match(/\.swf(\?.*)?$/i)) { @@ -1830,110 +1848,110 @@ function SoundManager(smURL, smID) { smURL += '/'; } } - url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL; - if (_s.noSWFCache) { + url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + sm2.movieURL; + if (sm2.noSWFCache) { url += ('?ts=' + new Date().getTime()); } return url; }; - _setVersionInfo = function() { - _fV = parseInt(_s.flashVersion, 10); - if (_fV !== 8 && _fV !== 9) { - _s.flashVersion = _fV = _defaultFlashVersion; + setVersionInfo = function() { + fV = parseInt(sm2.flashVersion, 10); + if (fV !== 8 && fV !== 9) { + sm2.flashVersion = fV = defaultFlashVersion; } - var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); - if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) { - _s.flashVersion = _fV = 9; + var isDebug = (sm2.debugMode || sm2.debugFlash?'_debug.swf':'.swf'); + if (sm2.useHTML5Audio && !sm2.html5Only && sm2.audioFormats.mp4.required && fV < 9) { + sm2.flashVersion = fV = 9; } - _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); - if (_fV > 8) { - _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); - _s.features.buffering = true; - _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); - _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); - _s.features.movieStar = true; + sm2.version = sm2.versionNumber + (sm2.html5Only?' (HTML5-only mode)':(fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); + if (fV > 8) { + sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.flash9Options); + sm2.features.buffering = true; + sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.movieStarOptions); + sm2.filePatterns.flash9 = new RegExp('\\.(mp3|' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + sm2.features.movieStar = true; } else { - _s.features.movieStar = false; + sm2.features.movieStar = false; } - _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; - _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug); - _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); + sm2.filePattern = sm2.filePatterns[(fV !== 8?'flash9':'flash8')]; + sm2.movieURL = (fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug); + sm2.features.peakData = sm2.features.waveformData = sm2.features.eqData = (fV > 8); }; - _setPolling = function(bPolling, bHighPerformance) { - if (!_flash) { + setPolling = function(bPolling, bHighPerformance) { + if (!flash) { return false; } - _flash._setPolling(bPolling, bHighPerformance); + flash._setPolling(bPolling, bHighPerformance); }; - _initDebug = function() { - if (_s.debugURLParam.test(_wl)) { - _s.debugMode = true; + initDebug = function() { + if (sm2.debugURLParam.test(wl)) { + sm2.debugMode = true; } }; - _idCheck = this.getSoundById; - _getSWFCSS = function() { + idCheck = this.getSoundById; + getSWFCSS = function() { var css = []; - if (_s.debugMode) { - css.push(_swfCSS.sm2Debug); + if (sm2.debugMode) { + css.push(swfCSS.sm2Debug); } - if (_s.debugFlash) { - css.push(_swfCSS.flashDebug); + if (sm2.debugFlash) { + css.push(swfCSS.flashDebug); } - if (_s.useHighPerformance) { - css.push(_swfCSS.highPerf); + if (sm2.useHighPerformance) { + css.push(swfCSS.highPerf); } return css.join(' '); }; - _flashBlockHandler = function() { - var name = _str('fbHandler'), - p = _s.getMoviePercent(), - css = _swfCSS, + flashBlockHandler = function() { + var name = str('fbHandler'), + p = sm2.getMoviePercent(), + css = swfCSS, error = {type:'FLASHBLOCK'}; - if (_s.html5Only) { + if (sm2.html5Only) { return false; } - if (!_s.ok()) { - if (_needsFlash) { - _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError); + if (!sm2.ok()) { + if (needsFlash) { + sm2.oMC.className = getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError); } - _s.didFlashBlock = true; - _processOnEvents({type:'ontimeout', ignoreInit:true, error:error}); - _catchError(error); + sm2.didFlashBlock = true; + processOnEvents({type:'ontimeout', ignoreInit:true, error:error}); + catchError(error); } else { - if (_s.oMC) { - _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' '); + if (sm2.oMC) { + sm2.oMC.className = [getSWFCSS(), css.swfDefault, css.swfLoaded + (sm2.didFlashBlock?' '+css.swfUnblocked:'')].join(' '); } } }; - _addOnEvent = function(sType, oMethod, oScope) { - if (typeof _on_queue[sType] === 'undefined') { - _on_queue[sType] = []; + addOnEvent = function(sType, oMethod, oScope) { + if (on_queue[sType] === _undefined) { + on_queue[sType] = []; } - _on_queue[sType].push({ + on_queue[sType].push({ 'method': oMethod, 'scope': (oScope || null), 'fired': false }); }; - _processOnEvents = function(oOptions) { + processOnEvents = function(oOptions) { if (!oOptions) { oOptions = { - type: (_s.ok() ? 'onready' : 'ontimeout') + type: (sm2.ok() ? 'onready' : 'ontimeout') }; } - if (!_didInit && oOptions && !oOptions.ignoreInit) { + if (!didInit && oOptions && !oOptions.ignoreInit) { return false; } - if (oOptions.type === 'ontimeout' && (_s.ok() || (_disabled && !oOptions.ignoreInit))) { + if (oOptions.type === 'ontimeout' && (sm2.ok() || (disabled && !oOptions.ignoreInit))) { return false; } var status = { - success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled) + success: (oOptions && oOptions.ignoreInit?sm2.ok():!disabled) }, - srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]), + srcQueue = (oOptions && oOptions.type?on_queue[oOptions.type]||[]:[]), queue = [], i, j, args = [status], - canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok()); + canRetry = (needsFlash && !sm2.ok()); if (oOptions.error) { args[0].error = oOptions.error; } @@ -1956,86 +1974,87 @@ function SoundManager(smURL, smID) { } return true; }; - _initUserOnload = function() { - _win.setTimeout(function() { - if (_s.useFlashBlock) { - _flashBlockHandler(); + initUserOnload = function() { + window.setTimeout(function() { + if (sm2.useFlashBlock) { + flashBlockHandler(); } - _processOnEvents(); - if (typeof _s.onload === 'function') { - _s.onload.apply(_win); + processOnEvents(); + if (typeof sm2.onload === 'function') { + sm2.onload.apply(window); } - if (_s.waitForWindowLoad) { - _event.add(_win, 'load', _initUserOnload); + if (sm2.waitForWindowLoad) { + event.add(window, 'load', initUserOnload); } },1); }; - _detectFlash = function() { - if (typeof _hasFlash !== 'undefined') { - return _hasFlash; + detectFlash = function() { + if (hasFlash !== _undefined) { + return hasFlash; } - var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject; + var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = window.ActiveXObject; if (nP && nP.length) { type = 'application/x-shockwave-flash'; types = n.mimeTypes; if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) { hasPlugin = true; } - } else if (typeof AX !== 'undefined') { + } else if (AX !== _undefined && !ua.match(/MSAppHost/i)) { try { obj = new AX('ShockwaveFlash.ShockwaveFlash'); } catch(e) { } hasPlugin = (!!obj); + obj = null; } - _hasFlash = hasPlugin; + hasFlash = hasPlugin; return hasPlugin; }; - _featureCheck = function() { + featureCheck = function() { var needsFlash, item, result = true, - formats = _s.audioFormats, - isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i))); + formats = sm2.audioFormats, + isSpecial = (is_iDevice && !!(ua.match(/os (1|2|3_0|3_1)/i))); if (isSpecial) { - _s.hasHTML5 = false; - _s.html5Only = true; - if (_s.oMC) { - _s.oMC.style.display = 'none'; + sm2.hasHTML5 = false; + sm2.html5Only = true; + if (sm2.oMC) { + sm2.oMC.style.display = 'none'; } result = false; } else { - if (_s.useHTML5Audio) { - if (!_s.html5 || !_s.html5.canPlayType) { - _s.hasHTML5 = false; + if (sm2.useHTML5Audio) { + if (!sm2.html5 || !sm2.html5.canPlayType) { + sm2.hasHTML5 = false; } } } - if (_s.useHTML5Audio && _s.hasHTML5) { + if (sm2.useHTML5Audio && sm2.hasHTML5) { for (item in formats) { if (formats.hasOwnProperty(item)) { - if ((formats[item].required && !_s.html5.canPlayType(formats[item].type)) || (_s.preferFlash && (_s.flash[item] || _s.flash[formats[item].type]))) { + if ((formats[item].required && !sm2.html5.canPlayType(formats[item].type)) || (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type]))) { needsFlash = true; } } } } - if (_s.ignoreFlash) { + if (sm2.ignoreFlash) { needsFlash = false; } - _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash); - return (!_s.html5Only); + sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !needsFlash); + return (!sm2.html5Only); }; - _parseURL = function(url) { + parseURL = function(url) { var i, j, urlResult = 0, result; if (url instanceof Array) { for (i=0, j=url.length; i= 0; i--) { - if (_s.sounds[_s.soundIDs[i]].isHTML5 && _s.sounds[_s.soundIDs[i]]._hasTimer) { - _s.sounds[_s.soundIDs[i]]._onTimer(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + if (sm2.sounds[sm2.soundIDs[i]].isHTML5 && sm2.sounds[sm2.soundIDs[i]]._hasTimer) { + sm2.sounds[sm2.soundIDs[i]]._onTimer(); } } }; - _catchError = function(options) { - options = (typeof options !== 'undefined' ? options : {}); - if (typeof _s.onerror === 'function') { - _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]); + catchError = function(options) { + options = (options !== _undefined ? options : {}); + if (typeof sm2.onerror === 'function') { + sm2.onerror.apply(window, [{type:(options.type !== _undefined ? options.type : null)}]); } - if (typeof options.fatal !== 'undefined' && options.fatal) { - _s.disable(); + if (options.fatal !== _undefined && options.fatal) { + sm2.disable(); } }; - _badSafariFix = function() { - if (!_isBadSafari || !_detectFlash()) { + badSafariFix = function() { + if (!isBadSafari || !detectFlash()) { return false; } - var aF = _s.audioFormats, i, item; + var aF = sm2.audioFormats, i, item; for (item in aF) { if (aF.hasOwnProperty(item)) { if (item === 'mp3' || item === 'mp4') { - _s.html5[item] = false; + sm2.html5[item] = false; if (aF[item] && aF[item].related) { for (i = aF[item].related.length-1; i >= 0; i--) { - _s.html5[aF[item].related[i]] = false; + sm2.html5[aF[item].related[i]] = false; } } } @@ -2111,104 +2130,105 @@ function SoundManager(smURL, smID) { this._setSandboxType = function(sandboxType) { }; this._externalInterfaceOK = function(flashDate, swfVersion) { - if (_s.swfLoaded) { + if (sm2.swfLoaded) { return false; } - var e, eiTime = new Date().getTime(); - _s.swfLoaded = true; - _tryInitOnFocus = false; - if (_isBadSafari) { - _badSafariFix(); + var e; + sm2.swfLoaded = true; + tryInitOnFocus = false; + if (isBadSafari) { + badSafariFix(); } - setTimeout(_init, _isIE ? 100 : 1); + setTimeout(init, isIE ? 100 : 1); }; - _createMovie = function(smID, smURL) { - if (_didAppend && _appendSuccess) { + createMovie = function(smID, smURL) { + if (didAppend && appendSuccess) { return false; } - function _initMsg() { + function initMsg() { } - if (_s.html5Only) { - _setVersionInfo(); - _initMsg(); - _s.oMC = _id(_s.movieID); - _init(); - _didAppend = true; - _appendSuccess = true; + if (sm2.html5Only) { + setVersionInfo(); + initMsg(); + sm2.oMC = id(sm2.movieID); + init(); + didAppend = true; + appendSuccess = true; return false; } - var remoteURL = (smURL || _s.url), - localURL = (_s.altURL || remoteURL), + var remoteURL = (smURL || sm2.url), + localURL = (sm2.altURL || remoteURL), swfTitle = 'JS/Flash audio component (SoundManager 2)', - oTarget = _getDocument(), - extraClass = _getSWFCSS(), + oTarget = getDocument(), + extraClass = getSWFCSS(), isRTL = null, - html = _doc.getElementsByTagName('html')[0], + html = doc.getElementsByTagName('html')[0], oEmbed, oMovie, tmp, movieHTML, oEl, s, x, sClass; isRTL = (html && html.dir && html.dir.match(/rtl/i)); - smID = (typeof smID === 'undefined'?_s.id:smID); + smID = (smID === _undefined?sm2.id:smID); function param(name, value) { return ''; } - _setVersionInfo(); - _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL); - smURL = _s.url; - _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode); - if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) { - _s.wmode = null; + setVersionInfo(); + sm2.url = normalizeMovieURL(overHTTP?remoteURL:localURL); + smURL = sm2.url; + sm2.wmode = (!sm2.wmode && sm2.useHighPerformance ? 'transparent' : sm2.wmode); + if (sm2.wmode !== null && (ua.match(/msie 8/i) || (!isIE && !sm2.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) { + messages.push(strings.spcWmode); + sm2.wmode = null; } oEmbed = { 'name': smID, 'id': smID, 'src': smURL, 'quality': 'high', - 'allowScriptAccess': _s.allowScriptAccess, - 'bgcolor': _s.bgColor, - 'pluginspage': _http+'www.macromedia.com/go/getflashplayer', + 'allowScriptAccess': sm2.allowScriptAccess, + 'bgcolor': sm2.bgColor, + 'pluginspage': http+'www.macromedia.com/go/getflashplayer', 'title': swfTitle, 'type': 'application/x-shockwave-flash', - 'wmode': _s.wmode, + 'wmode': sm2.wmode, 'hasPriority': 'true' }; - if (_s.debugFlash) { + if (sm2.debugFlash) { oEmbed.FlashVars = 'debug=1'; } - if (!_s.wmode) { + if (!sm2.wmode) { delete oEmbed.wmode; } - if (_isIE) { - oMovie = _doc.createElement('div'); + if (isIE) { + oMovie = doc.createElement('div'); movieHTML = [ - '', + '', param('movie', smURL), - param('AllowScriptAccess', _s.allowScriptAccess), + param('AllowScriptAccess', sm2.allowScriptAccess), param('quality', oEmbed.quality), - (_s.wmode? param('wmode', _s.wmode): ''), - param('bgcolor', _s.bgColor), + (sm2.wmode? param('wmode', sm2.wmode): ''), + param('bgcolor', sm2.bgColor), param('hasPriority', 'true'), - (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''), + (sm2.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''), '' ].join(''); } else { - oMovie = _doc.createElement('embed'); + oMovie = doc.createElement('embed'); for (tmp in oEmbed) { if (oEmbed.hasOwnProperty(tmp)) { oMovie.setAttribute(tmp, oEmbed[tmp]); } } } - _initDebug(); - extraClass = _getSWFCSS(); - oTarget = _getDocument(); + initDebug(); + extraClass = getSWFCSS(); + oTarget = getDocument(); if (oTarget) { - _s.oMC = (_id(_s.movieID) || _doc.createElement('div')); - if (!_s.oMC.id) { - _s.oMC.id = _s.movieID; - _s.oMC.className = _swfCSS.swfDefault + ' ' + extraClass; + sm2.oMC = (id(sm2.movieID) || doc.createElement('div')); + if (!sm2.oMC.id) { + sm2.oMC.id = sm2.movieID; + sm2.oMC.className = swfCSS.swfDefault + ' ' + extraClass; s = null; oEl = null; - if (!_s.useFlashBlock) { - if (_s.useHighPerformance) { + if (!sm2.useFlashBlock) { + if (sm2.useHighPerformance) { s = { 'position': 'fixed', 'width': '8px', @@ -2230,280 +2250,295 @@ function SoundManager(smURL, smID) { } } } - if (_isWebkit) { - _s.oMC.style.zIndex = 10000; + if (isWebkit) { + sm2.oMC.style.zIndex = 10000; } - if (!_s.debugFlash) { + if (!sm2.debugFlash) { for (x in s) { if (s.hasOwnProperty(x)) { - _s.oMC.style[x] = s[x]; + sm2.oMC.style[x] = s[x]; } } } try { - if (!_isIE) { - _s.oMC.appendChild(oMovie); + if (!isIE) { + sm2.oMC.appendChild(oMovie); } - oTarget.appendChild(_s.oMC); - if (_isIE) { - oEl = _s.oMC.appendChild(_doc.createElement('div')); - oEl.className = _swfCSS.swfBox; + oTarget.appendChild(sm2.oMC); + if (isIE) { + oEl = sm2.oMC.appendChild(doc.createElement('div')); + oEl.className = swfCSS.swfBox; oEl.innerHTML = movieHTML; } - _appendSuccess = true; + appendSuccess = true; } catch(e) { - throw new Error(_str('domError')+' \n'+e.toString()); + throw new Error(str('domError')+' \n'+e.toString()); } } else { - sClass = _s.oMC.className; - _s.oMC.className = (sClass?sClass+' ':_swfCSS.swfDefault) + (extraClass?' '+extraClass:''); - _s.oMC.appendChild(oMovie); - if (_isIE) { - oEl = _s.oMC.appendChild(_doc.createElement('div')); - oEl.className = _swfCSS.swfBox; + sClass = sm2.oMC.className; + sm2.oMC.className = (sClass?sClass+' ':swfCSS.swfDefault) + (extraClass?' '+extraClass:''); + sm2.oMC.appendChild(oMovie); + if (isIE) { + oEl = sm2.oMC.appendChild(doc.createElement('div')); + oEl.className = swfCSS.swfBox; oEl.innerHTML = movieHTML; } - _appendSuccess = true; + appendSuccess = true; } } - _didAppend = true; - _initMsg(); + didAppend = true; + initMsg(); return true; }; - _initMovie = function() { - if (_s.html5Only) { - _createMovie(); + initMovie = function() { + if (sm2.html5Only) { + createMovie(); return false; } - if (_flash) { + if (flash) { return false; } - if (!_s.url) { + if (!sm2.url) { return false; } - _flash = _s.getMovie(_s.id); - if (!_flash) { - if (!_oRemoved) { - _createMovie(_s.id, _s.url); + flash = sm2.getMovie(sm2.id); + if (!flash) { + if (!oRemoved) { + createMovie(sm2.id, sm2.url); } else { - if (!_isIE) { - _s.oMC.appendChild(_oRemoved); + if (!isIE) { + sm2.oMC.appendChild(oRemoved); } else { - _s.oMC.innerHTML = _oRemovedHTML; + sm2.oMC.innerHTML = oRemovedHTML; } - _oRemoved = null; - _didAppend = true; + oRemoved = null; + didAppend = true; } - _flash = _s.getMovie(_s.id); + flash = sm2.getMovie(sm2.id); } - if (typeof _s.oninitmovie === 'function') { - setTimeout(_s.oninitmovie, 1); + if (typeof sm2.oninitmovie === 'function') { + setTimeout(sm2.oninitmovie, 1); } return true; }; - _delayWaitForEI = function() { - setTimeout(_waitForEI, 1000); + delayWaitForEI = function() { + setTimeout(waitForEI, 1000); }; - _waitForEI = function() { + waitForEI = function() { var p, loadIncomplete = false; - if (!_s.url) { + if (!sm2.url) { return false; } - if (_waitingForEI) { + if (waitingForEI) { return false; } - _waitingForEI = true; - _event.remove(_win, 'load', _delayWaitForEI); - if (_tryInitOnFocus && !_isFocused) { + waitingForEI = true; + event.remove(window, 'load', delayWaitForEI); + if (tryInitOnFocus && !isFocused) { return false; } - if (!_didInit) { - p = _s.getMoviePercent(); + if (!didInit) { + p = sm2.getMoviePercent(); if (p > 0 && p < 100) { loadIncomplete = true; } } setTimeout(function() { - p = _s.getMoviePercent(); + p = sm2.getMoviePercent(); if (loadIncomplete) { - _waitingForEI = false; - _win.setTimeout(_delayWaitForEI, 1); + waitingForEI = false; + window.setTimeout(delayWaitForEI, 1); return false; } - if (!_didInit && _okToDisable) { + if (!didInit && okToDisable) { if (p === null) { - if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { - if (_s.useFlashBlock) { - _flashBlockHandler(); + if (sm2.useFlashBlock || sm2.flashLoadTimeout === 0) { + if (sm2.useFlashBlock) { + flashBlockHandler(); } } else { - _failSafely(true); + processOnEvents({type:'ontimeout', ignoreInit: true}); } } else { - if (_s.flashLoadTimeout === 0) { + if (sm2.flashLoadTimeout === 0) { } else { - _failSafely(true); + failSafely(true); } } } - }, _s.flashLoadTimeout); + }, sm2.flashLoadTimeout); }; - _handleFocus = function() { + handleFocus = function() { function cleanup() { - _event.remove(_win, 'focus', _handleFocus); + event.remove(window, 'focus', handleFocus); } - if (_isFocused || !_tryInitOnFocus) { + if (isFocused || !tryInitOnFocus) { cleanup(); return true; } - _okToDisable = true; - _isFocused = true; - _waitingForEI = false; - _delayWaitForEI(); + okToDisable = true; + isFocused = true; + waitingForEI = false; + delayWaitForEI(); cleanup(); return true; }; - _showSupport = function() { + flushMessages = function() { }; - _initComplete = function(bNoDisable) { - if (_didInit) { + showSupport = function() { + }; + initComplete = function(bNoDisable) { + if (didInit) { return false; } - if (_s.html5Only) { - _didInit = true; - _initUserOnload(); + if (sm2.html5Only) { + didInit = true; + initUserOnload(); return true; } - var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()), + var wasTimeout = (sm2.useFlashBlock && sm2.flashLoadTimeout && !sm2.getMoviePercent()), result = true, error; if (!wasTimeout) { - _didInit = true; - if (_disabled) { - error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')}; + didInit = true; + if (disabled) { + error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')}; } } - if (_disabled || bNoDisable) { - if (_s.useFlashBlock && _s.oMC) { - _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_swfCSS.swfTimedout:_swfCSS.swfError); + if (disabled || bNoDisable) { + if (sm2.useFlashBlock && sm2.oMC) { + sm2.oMC.className = getSWFCSS() + ' ' + (sm2.getMoviePercent() === null?swfCSS.swfTimedout:swfCSS.swfError); } - _processOnEvents({type:'ontimeout', error:error, ignoreInit: true}); - _catchError(error); + processOnEvents({type:'ontimeout', error:error, ignoreInit: true}); + catchError(error); result = false; } else { } - if (!_disabled) { - if (_s.waitForWindowLoad && !_windowLoaded) { - _event.add(_win, 'load', _initUserOnload); + if (!disabled) { + if (sm2.waitForWindowLoad && !windowLoaded) { + event.add(window, 'load', initUserOnload); } else { - _initUserOnload(); + initUserOnload(); } } return result; }; - _setProperties = function() { + setProperties = function() { var i, - o = _s.setupOptions; + o = sm2.setupOptions; for (i in o) { if (o.hasOwnProperty(i)) { - if (typeof _s[i] === 'undefined') { - _s[i] = o[i]; - } else if (_s[i] !== o[i]) { - _s.setupOptions[i] = _s[i]; + if (sm2[i] === _undefined) { + sm2[i] = o[i]; + } else if (sm2[i] !== o[i]) { + sm2.setupOptions[i] = sm2[i]; } } } }; - _init = function() { - if (_didInit) { + init = function() { + if (didInit) { return false; } - function _cleanup() { - _event.remove(_win, 'load', _s.beginDelayedInit); + function cleanup() { + event.remove(window, 'load', sm2.beginDelayedInit); } - if (_s.html5Only) { - if (!_didInit) { - _cleanup(); - _s.enabled = true; - _initComplete(); + if (sm2.html5Only) { + if (!didInit) { + cleanup(); + sm2.enabled = true; + initComplete(); } return true; } - _initMovie(); + initMovie(); try { - _flash._externalInterfaceTest(false); - _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50))); - if (!_s.debugMode) { - _flash._disableDebug(); + flash._externalInterfaceTest(false); + setPolling(true, (sm2.flashPollingInterval || (sm2.useHighPerformance ? 10 : 50))); + if (!sm2.debugMode) { + flash._disableDebug(); } - _s.enabled = true; - if (!_s.html5Only) { - _event.add(_win, 'unload', _doNothing); + sm2.enabled = true; + if (!sm2.html5Only) { + event.add(window, 'unload', doNothing); } } catch(e) { - _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true}); - _failSafely(true); - _initComplete(); + catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true}); + failSafely(true); + initComplete(); return false; } - _initComplete(); - _cleanup(); + initComplete(); + cleanup(); return true; }; - _domContentLoaded = function() { - if (_didDCLoaded) { + domContentLoaded = function() { + if (didDCLoaded) { return false; } - _didDCLoaded = true; - _setProperties(); - _initDebug(); - if (!_hasFlash && _s.hasHTML5) { - _s.setup({ + didDCLoaded = true; + setProperties(); + initDebug(); + if (!hasFlash && sm2.hasHTML5) { + sm2.setup({ 'useHTML5Audio': true, 'preferFlash': false }); } - _testHTML5(); - _s.html5.usingFlash = _featureCheck(); - _needsFlash = _s.html5.usingFlash; - _showSupport(); - if (!_hasFlash && _needsFlash) { - _s.setup({ + testHTML5(); + sm2.html5.usingFlash = featureCheck(); + needsFlash = sm2.html5.usingFlash; + if (!hasFlash && needsFlash) { + messages.push(strings.needFlash); + sm2.setup({ 'flashLoadTimeout': 1 }); } - if (_doc.removeEventListener) { - _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false); + if (doc.removeEventListener) { + doc.removeEventListener('DOMContentLoaded', domContentLoaded, false); } - _initMovie(); + initMovie(); return true; }; - _domContentLoadedIE = function() { - if (_doc.readyState === 'complete') { - _domContentLoaded(); - _doc.detachEvent('onreadystatechange', _domContentLoadedIE); + domContentLoadedIE = function() { + if (doc.readyState === 'complete') { + domContentLoaded(); + doc.detachEvent('onreadystatechange', domContentLoadedIE); } return true; }; - _winOnLoad = function() { - _windowLoaded = true; - _event.remove(_win, 'load', _winOnLoad); + winOnLoad = function() { + windowLoaded = true; + event.remove(window, 'load', winOnLoad); }; - _detectFlash(); - _event.add(_win, 'focus', _handleFocus); - _event.add(_win, 'load', _delayWaitForEI); - _event.add(_win, 'load', _winOnLoad); - if (_doc.addEventListener) { - _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false); - } else if (_doc.attachEvent) { - _doc.attachEvent('onreadystatechange', _domContentLoadedIE); + preInit = function() { + if (mobileHTML5) { + sm2.setupOptions.useHTML5Audio = true; + sm2.setupOptions.preferFlash = false; + if (is_iDevice || (isAndroid && !ua.match(/android\s2\.3/i))) { + if (is_iDevice) { + sm2.ignoreFlash = true; + } + useGlobalHTML5Audio = true; + } + } + }; + preInit(); + detectFlash(); + event.add(window, 'focus', handleFocus); + event.add(window, 'load', delayWaitForEI); + event.add(window, 'load', winOnLoad); + if (doc.addEventListener) { + doc.addEventListener('DOMContentLoaded', domContentLoaded, false); + } else if (doc.attachEvent) { + doc.attachEvent('onreadystatechange', domContentLoadedIE); } else { - _catchError({type:'NO_DOM2_EVENTS', fatal:true}); + catchError({type:'NO_DOM2_EVENTS', fatal:true}); } } // SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading -if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { +if (window.SM2_DEFER === undefined || !SM2_DEFER) { soundManager = new SoundManager(); } window.SoundManager = SoundManager; diff --git a/static/js/libs/sm/soundmanager2.js b/static/js/libs/sm/soundmanager2.js index d9d4422..b4ec888 100755 --- a/static/js/libs/sm/soundmanager2.js +++ b/static/js/libs/sm/soundmanager2.js @@ -8,15 +8,15 @@ * Code provided under the BSD License: * http://schillmania.com/projects/soundmanager2/license.txt * - * V2.97a.20120916 + * V2.97a.20130101 */ -/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ +/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */ /*jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */ /** * About this file - * --------------- + * ------------------------------------------------------------------------------------- * This is the fully-commented source version of the SoundManager 2 API, * recommended for use during development and testing. * @@ -30,7 +30,9 @@ * Also, as you may note: Whoa, reliable cross-platform/device audio support is hard! ;) */ -(function(window) { +(function(window, _undefined) { + +"use strict"; var soundManager = null; @@ -181,7 +183,7 @@ function SoundManager(smURL, smID) { // dynamic attributes - this.versionNumber = 'V2.97a.20120916'; + this.versionNumber = 'V2.97a.20130101'; this.version = null; this.movieURL = null; this.altURL = null; @@ -232,21 +234,6 @@ function SoundManager(smURL, smID) { }; - /** - * basic HTML5 Audio() support test - * try...catch because of IE 9 "not implemented" nonsense - * https://github.com/Modernizr/Modernizr/issues/224 - */ - - this.hasHTML5 = (function() { - try { - // new Audio(null) for stupid Opera 9.64 case, which throws not_enough_arguments exception otherwise. - return (typeof Audio !== 'undefined' && typeof (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== 'undefined'); - } catch(e) { - return false; - } - }()); - /** * format support (html5/flash) * stores canPlayType() results based on audioFormats. @@ -272,29 +259,27 @@ function SoundManager(smURL, smID) { */ var SMSound, - _s = this, _flash = null, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _setProperties, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _assign, _extraOptions, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _winOnLoad, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _swfCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _startTimer, _stopTimer, _timerExecute, _h5TimerCount = 0, _h5IntervalTimer = null, _parseURL, - _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport, - _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)), - _mobileHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice), - _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && !_ua.match(/silk/i) && _ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 (excluding Kindle Fire, "Silk") occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159 - _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && (typeof _doc.hasFocus === 'undefined' || !_doc.hasFocus())), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i, - _emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs) - _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null), - _http = (!_overHTTP ? 'http:/'+'/' : ''), + sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [], + needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages, + is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)), + mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid), + isBadSafari = (!wl.match(/usehtml5audio/i) && !wl.match(/sm2\-ignorebadua/i) && isSafari && !ua.match(/silk/i) && ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 (excluding Kindle Fire, "Silk") occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159 + hasConsole = (window.console !== _undefined && console.log !== _undefined), isFocused = (doc.hasFocus !== _undefined?doc.hasFocus():null), tryInitOnFocus = (isSafari && (doc.hasFocus === _undefined || !doc.hasFocus())), okToDisable = !tryInitOnFocus, flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i, + emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs) + overHTTP = (doc.location?doc.location.protocol.match(/http/i):null), + http = (!overHTTP ? 'http:/'+'/' : ''), // mp3, mp4, aac etc. - _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i, + netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i, // Flash v9.0r115+ "moviestar" formats - _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'], - _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'], + netStreamPattern = new RegExp('\\.(' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // default mp3 set // use altURL if not "online" - this.useAltURL = !_overHTTP; + this.useAltURL = !overHTTP; - this._global_a = null; - - _swfCSS = { + swfCSS = { 'swfBox': 'sm2-object-box', 'swfDefault': 'movieContainer', @@ -308,19 +293,20 @@ function SoundManager(smURL, smID) { }; - if (_mobileHTML5) { + /** + * basic HTML5 Audio() support test + * try...catch because of IE 9 "not implemented" nonsense + * https://github.com/Modernizr/Modernizr/issues/224 + */ - // prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point. - _s.useHTML5Audio = true; - _s.preferFlash = false; - - if (_is_iDevice) { - // by default, use global feature. iOS onfinish() -> next may fail otherwise. - _s.ignoreFlash = true; - _useGlobalHTML5Audio = true; + this.hasHTML5 = (function() { + try { + // new Audio(null) for stupid Opera 9.64 case, which throws not_enough_arguments exception otherwise. + return (Audio !== _undefined && (isOpera && opera !== _undefined && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== _undefined); + } catch(e) { + return false; } - - } + }()); /** * Public SoundManager API @@ -336,37 +322,37 @@ function SoundManager(smURL, smID) { this.setup = function(options) { - var noURL = (!_s.url); + var noURL = (!sm2.url); // warn if flash options have already been applied - if (typeof options !== 'undefined' && _didInit && _needsFlash && _s.ok() && (typeof options.flashVersion !== 'undefined' || typeof options.url !== 'undefined')) { - _complain(_str('setupLate')); + if (options !== _undefined && didInit && needsFlash && sm2.ok() && (options.flashVersion !== _undefined || options.url !== _undefined || options.html5Test !== _undefined)) { + complain(str('setupLate')); } // TODO: defer: true? - _assign(options); + assign(options); // special case 1: "Late setup". SM2 loaded normally, but user didn't assign flash URL eg., setup({url:...}) before SM2 init. Treat as delayed init. - if (noURL && _didDCLoaded && typeof options.url !== 'undefined') { - _s.beginDelayedInit(); + if (noURL && didDCLoaded && options.url !== _undefined) { + sm2.beginDelayedInit(); } // special case 2: If lazy-loading SM2 (DOMContentLoaded has already happened) and user calls setup() with url: parameter, try to init ASAP. - if (!_didDCLoaded && typeof options.url !== 'undefined' && _doc.readyState === 'complete') { - setTimeout(_domContentLoaded, 1); + if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') { + setTimeout(domContentLoaded, 1); } - return _s; + return sm2; }; this.ok = function() { - return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); + return (needsFlash?(didInit && !disabled):(sm2.useHTML5Audio && sm2.hasHTML5)); }; @@ -375,7 +361,7 @@ function SoundManager(smURL, smID) { this.getMovie = function(smID) { // safety net: some old browsers differ on SWF references, possibly related to ExternalInterface / flash version - return _id(smID) || _doc[smID] || _win[smID]; + return id(smID) || doc[smID] || window[smID]; }; @@ -388,19 +374,19 @@ function SoundManager(smURL, smID) { this.createSound = function(oOptions, _url) { - var _cs, _cs_string, thisOptions = null, oSound = null, _tO = null; + var cs, cs_string, options, oSound = null; // - _cs = _sm+'.createSound(): '; - _cs_string = _cs + _str(!_didInit?'notReady':'notOK'); + cs = sm + '.createSound(): '; + cs_string = cs + str(!didInit?'notReady':'notOK'); // - if (!_didInit || !_s.ok()) { - _complain(_cs_string); + if (!didInit || !sm2.ok()) { + complain(cs_string); return false; } - if (typeof _url !== 'undefined') { + if (_url !== _undefined) { // function overloading in JS! :) ..assume simple createSound(id,url) use case oOptions = { 'id': oOptions, @@ -409,83 +395,80 @@ function SoundManager(smURL, smID) { } // inherit from defaultOptions - thisOptions = _mixin(oOptions); + options = mixin(oOptions); - thisOptions.url = _parseURL(thisOptions.url); - - // local shortcut - _tO = thisOptions; + options.url = parseURL(options.url); // - if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) { - _s._wD(_cs + _str('badID', _tO.id), 2); + if (options.id.toString().charAt(0).match(/^[0-9]$/)) { + sm2._wD(cs + str('badID', options.id), 2); } - _s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1); + sm2._wD(cs + options.id + ' (' + options.url + ')', 1); // - if (_idCheck(_tO.id, true)) { - _s._wD(_cs + _tO.id + ' exists', 1); - return _s.sounds[_tO.id]; + if (idCheck(options.id, true)) { + sm2._wD(cs + options.id + ' exists', 1); + return sm2.sounds[options.id]; } function make() { - thisOptions = _loopFix(thisOptions); - _s.sounds[_tO.id] = new SMSound(_tO); - _s.soundIDs.push(_tO.id); - return _s.sounds[_tO.id]; + options = loopFix(options); + sm2.sounds[options.id] = new SMSound(options); + sm2.soundIDs.push(options.id); + return sm2.sounds[options.id]; } - if (_html5OK(_tO)) { + if (html5OK(options)) { oSound = make(); - _s._wD('Creating sound '+_tO.id+', using HTML5'); - oSound._setup_html5(_tO); + sm2._wD(options.id + ': Using HTML5'); + oSound._setup_html5(options); } else { - if (_fV > 8) { - if (_tO.isMovieStar === null) { + if (fV > 8) { + if (options.isMovieStar === null) { // attempt to detect MPEG-4 formats - _tO.isMovieStar = !!(_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern)); + options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || options.url.match(netStreamPattern)); } // - if (_tO.isMovieStar) { - _s._wD(_cs + 'using MovieStar handling'); - if (_tO.loops > 1) { + if (options.isMovieStar) { + sm2._wD(cs + 'using MovieStar handling'); + if (options.loops > 1) { _wDS('noNSLoop'); } } // } - _tO = _policyFix(_tO, _cs); + options = policyFix(options, cs); oSound = make(); - if (_fV === 8) { - _flash._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile); + if (fV === 8) { + flash._createSound(options.id, options.loops||1, options.usePolicyFile); } else { - _flash._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile); - if (!_tO.serverURL) { + flash._createSound(options.id, options.url, options.usePeakData, options.useWaveformData, options.useEQData, options.isMovieStar, (options.isMovieStar?options.bufferTime:false), options.loops||1, options.serverURL, options.duration||null, options.autoPlay, true, options.autoLoad, options.usePolicyFile); + if (!options.serverURL) { // We are connected immediately oSound.connected = true; - if (_tO.onconnect) { - _tO.onconnect.apply(oSound); + if (options.onconnect) { + options.onconnect.apply(oSound); } } } - if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) { + if (!options.serverURL && (options.autoLoad || options.autoPlay)) { // call load for non-rtmp streams - oSound.load(_tO); + oSound.load(options); } } // rtmp will play in onconnect - if (!_tO.serverURL && _tO.autoPlay) { + if (!options.serverURL && options.autoPlay) { oSound.play(); } @@ -503,11 +486,11 @@ function SoundManager(smURL, smID) { // explicitly destroy a sound before normal page unload, etc. - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - var oS = _s.sounds[sID], i; + var oS = sm2.sounds[sID], i; // Disable all callbacks while the sound is being destroyed oS._iO = {}; @@ -515,9 +498,9 @@ function SoundManager(smURL, smID) { oS.stop(); oS.unload(); - for (i = 0; i < _s.soundIDs.length; i++) { - if (_s.soundIDs[i] === sID) { - _s.soundIDs.splice(i, 1); + for (i = 0; i < sm2.soundIDs.length; i++) { + if (sm2.soundIDs[i] === sID) { + sm2.soundIDs.splice(i, 1); break; } } @@ -528,7 +511,7 @@ function SoundManager(smURL, smID) { } oS = null; - delete _s.sounds[sID]; + delete sm2.sounds[sID]; return true; @@ -543,10 +526,10 @@ function SoundManager(smURL, smID) { this.load = function(sID, oOptions) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].load(oOptions); + return sm2.sounds[sID].load(oOptions); }; @@ -558,10 +541,10 @@ function SoundManager(smURL, smID) { this.unload = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].unload(); + return sm2.sounds[sID].unload(); }; @@ -577,10 +560,10 @@ function SoundManager(smURL, smID) { this.onPosition = function(sID, nPosition, oMethod, oScope) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].onposition(nPosition, oMethod, oScope); + return sm2.sounds[sID].onposition(nPosition, oMethod, oScope); }; @@ -598,10 +581,10 @@ function SoundManager(smURL, smID) { this.clearOnPosition = function(sID, nPosition, oMethod) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].clearOnPosition(nPosition, oMethod); + return sm2.sounds[sID].clearOnPosition(nPosition, oMethod); }; @@ -617,12 +600,12 @@ function SoundManager(smURL, smID) { var result = false; - if (!_didInit || !_s.ok()) { - _complain(_sm+'.play(): ' + _str(!_didInit?'notReady':'notOK')); + if (!didInit || !sm2.ok()) { + complain(sm + '.play(): ' + str(!didInit?'notReady':'notOK')); return result; } - if (!_idCheck(sID)) { + if (!idCheck(sID)) { if (!(oOptions instanceof Object)) { // overloading use case: play('mySound','/path/to/some.mp3'); oOptions = { @@ -631,14 +614,14 @@ function SoundManager(smURL, smID) { } if (oOptions && oOptions.url) { // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); - _s._wD(_sm+'.play(): attempting to create "' + sID + '"', 1); + sm2._wD(sm + '.play(): attempting to create "' + sID + '"', 1); oOptions.id = sID; - result = _s.createSound(oOptions).play(); + result = sm2.createSound(oOptions).play(); } return result; } - return _s.sounds[sID].play(oOptions); + return sm2.sounds[sID].play(oOptions); }; @@ -654,10 +637,10 @@ function SoundManager(smURL, smID) { this.setPosition = function(sID, nMsecOffset) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].setPosition(nMsecOffset); + return sm2.sounds[sID].setPosition(nMsecOffset); }; @@ -670,12 +653,12 @@ function SoundManager(smURL, smID) { this.stop = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - _s._wD(_sm+'.stop(' + sID + ')', 1); - return _s.sounds[sID].stop(); + sm2._wD(sm + '.stop(' + sID + ')', 1); + return sm2.sounds[sID].stop(); }; @@ -686,12 +669,12 @@ function SoundManager(smURL, smID) { this.stopAll = function() { var oSound; - _s._wD(_sm+'.stopAll()', 1); + sm2._wD(sm + '.stopAll()', 1); - for (oSound in _s.sounds) { - if (_s.sounds.hasOwnProperty(oSound)) { + for (oSound in sm2.sounds) { + if (sm2.sounds.hasOwnProperty(oSound)) { // apply only to sound objects - _s.sounds[oSound].stop(); + sm2.sounds[oSound].stop(); } } @@ -706,10 +689,10 @@ function SoundManager(smURL, smID) { this.pause = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].pause(); + return sm2.sounds[sID].pause(); }; @@ -720,8 +703,8 @@ function SoundManager(smURL, smID) { this.pauseAll = function() { var i; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].pause(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].pause(); } }; @@ -735,10 +718,10 @@ function SoundManager(smURL, smID) { this.resume = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].resume(); + return sm2.sounds[sID].resume(); }; @@ -749,8 +732,8 @@ function SoundManager(smURL, smID) { this.resumeAll = function() { var i; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].resume(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].resume(); } }; @@ -764,10 +747,10 @@ function SoundManager(smURL, smID) { this.togglePause = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].togglePause(); + return sm2.sounds[sID].togglePause(); }; @@ -781,10 +764,10 @@ function SoundManager(smURL, smID) { this.setPan = function(sID, nPan) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].setPan(nPan); + return sm2.sounds[sID].setPan(nPan); }; @@ -798,10 +781,10 @@ function SoundManager(smURL, smID) { this.setVolume = function(sID, nVol) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].setVolume(nVol); + return sm2.sounds[sID].setVolume(nVol); }; @@ -815,22 +798,26 @@ function SoundManager(smURL, smID) { var i = 0; - if (typeof sID !== 'string') { + if (sID instanceof String) { sID = null; } if (!sID) { - _s._wD(_sm+'.mute(): Muting all sounds'); - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].mute(); + + sm2._wD(sm + '.mute(): Muting all sounds'); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].mute(); } - _s.muted = true; + sm2.muted = true; + } else { - if (!_idCheck(sID)) { + + if (!idCheck(sID)) { return false; } - _s._wD(_sm+'.mute(): Muting "' + sID + '"'); - return _s.sounds[sID].mute(); + sm2._wD(sm + '.mute(): Muting "' + sID + '"'); + return sm2.sounds[sID].mute(); + } return true; @@ -843,7 +830,7 @@ function SoundManager(smURL, smID) { this.muteAll = function() { - _s.mute(); + sm2.mute(); }; @@ -857,25 +844,25 @@ function SoundManager(smURL, smID) { var i; - if (typeof sID !== 'string') { + if (sID instanceof String) { sID = null; } if (!sID) { - _s._wD(_sm+'.unmute(): Unmuting all sounds'); - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].unmute(); + sm2._wD(sm + '.unmute(): Unmuting all sounds'); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].unmute(); } - _s.muted = false; + sm2.muted = false; } else { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - _s._wD(_sm+'.unmute(): Unmuting "' + sID + '"'); - return _s.sounds[sID].unmute(); + sm2._wD(sm + '.unmute(): Unmuting "' + sID + '"'); + return sm2.sounds[sID].unmute(); } @@ -889,7 +876,7 @@ function SoundManager(smURL, smID) { this.unmuteAll = function() { - _s.unmute(); + sm2.unmute(); }; @@ -902,10 +889,10 @@ function SoundManager(smURL, smID) { this.toggleMute = function(sID) { - if (!_idCheck(sID)) { + if (!idCheck(sID)) { return false; } - return _s.sounds[sID].toggleMute(); + return sm2.sounds[sID].toggleMute(); }; @@ -920,8 +907,8 @@ function SoundManager(smURL, smID) { // flash-only var ram = 0; - if (_flash && _fV !== 8) { - ram = parseInt(_flash._getMemoryUse(), 10); + if (flash && fV !== 8) { + ram = parseInt(flash._getMemoryUse(), 10); } return ram; @@ -937,24 +924,24 @@ function SoundManager(smURL, smID) { // destroy all functions var i; - if (typeof bNoDisable === 'undefined') { + if (bNoDisable === _undefined) { bNoDisable = false; } - if (_disabled) { + if (disabled) { return false; } - _disabled = true; + disabled = true; _wDS('shutdown', 1); - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _disableObject(_s.sounds[_s.soundIDs[i]]); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + disableObject(sm2.sounds[sm2.soundIDs[i]]); } // fire "complete", despite fail - _initComplete(bNoDisable); - _event.remove(_win, 'load', _initUserOnload); + initComplete(bNoDisable); + event.remove(window, 'load', initUserOnload); return true; @@ -968,13 +955,13 @@ function SoundManager(smURL, smID) { var result; - if (_s.hasHTML5) { - result = _html5CanPlay({type:sMIME}); + if (sm2.hasHTML5) { + result = html5CanPlay({type:sMIME}); } - if (!result && _needsFlash) { + if (!result && needsFlash) { // if flash 9, test netStream (movieStar) types as well. - result = (sMIME && _s.ok() ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null); + result = (sMIME && sm2.ok() ? !!((fV > 8 ? sMIME.match(netStreamMimeTypes) : null) || sMIME.match(sm2.mimePattern)) : null); } return result; @@ -992,12 +979,12 @@ function SoundManager(smURL, smID) { var result; - if (_s.hasHTML5) { - result = _html5CanPlay({url: sURL}); + if (sm2.hasHTML5) { + result = html5CanPlay({url: sURL}); } - if (!result && _needsFlash) { - result = (sURL && _s.ok() ? !!(sURL.match(_s.filePattern)) : null); + if (!result && needsFlash) { + result = (sURL && sm2.ok() ? !!(sURL.match(sm2.filePattern)) : null); } return result; @@ -1013,13 +1000,13 @@ function SoundManager(smURL, smID) { this.canPlayLink = function(oLink) { - if (typeof oLink.type !== 'undefined' && oLink.type) { - if (_s.canPlayMIME(oLink.type)) { + if (oLink.type !== _undefined && oLink.type) { + if (sm2.canPlayMIME(oLink.type)) { return true; } } - return _s.canPlayURL(oLink.href); + return sm2.canPlayURL(oLink.href); }; @@ -1033,14 +1020,14 @@ function SoundManager(smURL, smID) { this.getSoundById = function(sID, _suppressDebug) { if (!sID) { - throw new Error(_sm+'.getSoundById(): sID is null/undefined'); + throw new Error(sm + '.getSoundById(): sID is null/_undefined'); } - var result = _s.sounds[sID]; + var result = sm2.sounds[sID]; // if (!result && !_suppressDebug) { - _s._wD('"' + sID + '" is an invalid sound ID.', 2); + sm2._wD('"' + sID + '" is an invalid sound ID.', 2); } // @@ -1063,23 +1050,23 @@ function SoundManager(smURL, smID) { if (typeof oMethod === 'function') { // - if (_didInit) { - _s._wD(_str('queue', sType)); + if (didInit) { + sm2._wD(str('queue', sType)); } // if (!oScope) { - oScope = _win; + oScope = window; } - _addOnEvent(sType, oMethod, oScope); - _processOnEvents(); + addOnEvent(sType, oMethod, oScope); + processOnEvents(); result = true; } else { - throw _str('needFunction', sType); + throw str('needFunction', sType); } @@ -1102,23 +1089,23 @@ function SoundManager(smURL, smID) { if (typeof oMethod === 'function') { // - if (_didInit) { - _s._wD(_str('queue', sType)); + if (didInit) { + sm2._wD(str('queue', sType)); } // if (!oScope) { - oScope = _win; + oScope = window; } - _addOnEvent(sType, oMethod, oScope); - _processOnEvents({type:sType}); + addOnEvent(sType, oMethod, oScope); + processOnEvents({type:sType}); result = true; } else { - throw _str('needFunction', sType); + throw str('needFunction', sType); } @@ -1131,78 +1118,69 @@ function SoundManager(smURL, smID) { * Applies when debugMode = true * * @param {string} sText The console message - * @param {string} sType Optional: Log type of 'info', 'warn' or 'error' - * @param {object} Optional: The scope to apply to the callback + * @param {object} sType Optional string: Log type of 'info', 'warn' or 'error', or object (to be dumped) */ - this._writeDebug = function(sText, sType, _bTimestamp) { + this._writeDebug = function(sText, sType) { // pseudo-private console.log()-style output // - var sDID = 'soundmanager-debug', o, oItem, sMethod; + var sDID = 'soundmanager-debug', o, oItem; - if (!_s.debugMode) { + if (!sm2.debugMode) { return false; } - if (typeof _bTimestamp !== 'undefined' && _bTimestamp) { - sText = sText + ' | ' + new Date().getTime(); - } - - if (_hasConsole && _s.useConsole) { - sMethod = _debugLevels[sType]; - if (typeof console[sMethod] !== 'undefined') { - console[sMethod](sText); + if (hasConsole && sm2.useConsole) { + if (sType && typeof sType === 'object') { + // object passed; dump to console. + console.log(sText, sType); + } else if (debugLevels[sType] !== _undefined) { + console[debugLevels[sType]](sText); } else { console.log(sText); } - if (_s.consoleOnly) { + if (sm2.consoleOnly) { return true; } } - try { + o = id(sDID); - o = _id(sDID); - - if (!o) { - return false; - } - - oItem = _doc.createElement('div'); - - if (++_wdCount % 2 === 0) { - oItem.className = 'sm2-alt'; - } - - if (typeof sType === 'undefined') { - sType = 0; - } else { - sType = parseInt(sType, 10); - } - - oItem.appendChild(_doc.createTextNode(sText)); - - if (sType) { - if (sType >= 2) { - oItem.style.fontWeight = 'bold'; - } - if (sType === 3) { - oItem.style.color = '#ff3333'; - } - } - - // top-to-bottom - // o.appendChild(oItem); - - // bottom-to-top - o.insertBefore(oItem, o.firstChild); - - } catch(e) { - // oh well + if (!o) { + return false; } + oItem = doc.createElement('div'); + + if (++wdCount % 2 === 0) { + oItem.className = 'sm2-alt'; + } + + if (sType === _undefined) { + sType = 0; + } else { + sType = parseInt(sType, 10); + } + + oItem.appendChild(doc.createTextNode(sText)); + + if (sType) { + if (sType >= 2) { + oItem.style.fontWeight = 'bold'; + } + if (sType === 3) { + oItem.style.color = '#ff3333'; + } + } + + // top-to-bottom + // o.appendChild(oItem); + + // bottom-to-top + o.insertBefore(oItem, o.firstChild); + o = null; // @@ -1210,6 +1188,15 @@ function SoundManager(smURL, smID) { }; + // + // last-resort debugging option + if (wl.indexOf('sm2-debug=alert') !== -1) { + this._writeDebug = function(sText) { + window.alert(sText); + }; + } + // + // alias this._wD = this._writeDebug; @@ -1223,8 +1210,8 @@ function SoundManager(smURL, smID) { var i, j; _wDS('currentObj', 1); - for (i = 0, j = _s.soundIDs.length; i < j; i++) { - _s.sounds[_s.soundIDs[i]]._debug(); + for (i = 0, j = sm2.soundIDs.length; i < j; i++) { + sm2.sounds[sm2.soundIDs[i]]._debug(); } // @@ -1232,58 +1219,120 @@ function SoundManager(smURL, smID) { /** * Restarts and re-initializes the SoundManager instance. + * + * @param {boolean} resetEvents Optional: When true, removes all registered onready and ontimeout event callbacks. + * @param {boolean} excludeInit Options: When true, does not call beginDelayedInit() (which would restart SM2). + * @return {object} soundManager The soundManager instance. */ - this.reboot = function() { + this.reboot = function(resetEvents, excludeInit) { - // attempt to reset and init SM2 - _s._wD(_sm+'.reboot()'); + // reset some (or all) state, and re-init unless otherwise specified. // - if (_s.soundIDs.length) { - _s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...'); + if (sm2.soundIDs.length) { + sm2._wD('Destroying ' + sm2.soundIDs.length + ' SMSound objects...'); } // - var i, j; + var i, j, k; - for (i = _s.soundIDs.length-1; i >= 0; i--) { - _s.sounds[_s.soundIDs[i]].destruct(); + for (i = sm2.soundIDs.length-1; i >= 0; i--) { + sm2.sounds[sm2.soundIDs[i]].destruct(); } // trash ze flash - if (_flash) { + if (flash) { + try { - if (_isIE) { - _oRemovedHTML = _flash.innerHTML; + + if (isIE) { + oRemovedHTML = flash.innerHTML; } - _oRemoved = _flash.parentNode.removeChild(_flash); - _s._wD('Flash movie removed.'); + + oRemoved = flash.parentNode.removeChild(flash); + + _wDS('flRemoved'); + } catch(e) { - // uh-oh. + + // Remove failed? May be due to flash blockers silently removing the SWF object/embed node from the DOM. Warn and continue. + _wDS('badRemove', 2); + } + } // actually, force recreate of movie. - _oRemovedHTML = _oRemoved = _needsFlash = null; - _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; - _s.soundIDs = []; - _s.sounds = {}; - _flash = null; + oRemovedHTML = oRemoved = needsFlash = flash = null; - for (i in _on_queue) { - if (_on_queue.hasOwnProperty(i)) { - for (j = _on_queue[i].length-1; j >= 0; j--) { - _on_queue[i][j].fired = false; + sm2.enabled = didDCLoaded = didInit = waitingForEI = initPending = didAppend = appendSuccess = disabled = useGlobalHTML5Audio = sm2.swfLoaded = false; + + sm2.soundIDs = []; + sm2.sounds = {}; + + if (!resetEvents) { + // reset callbacks for onready, ontimeout etc. so that they will fire again on re-init + for (i in on_queue) { + if (on_queue.hasOwnProperty(i)) { + for (j = 0, k = on_queue[i].length; j < k; j++) { + on_queue[i][j].fired = false; + } } } + } else { + // remove all callbacks entirely + on_queue = []; } - _s._wD(_sm + ': Rebooting...'); - _win.setTimeout(_s.beginDelayedInit, 20); + // + if (!excludeInit) { + sm2._wD(sm + ': Rebooting...'); + } + // + + // reset HTML5 and flash canPlay test results + + sm2.html5 = { + 'usingFlash': null + }; + + sm2.flash = {}; + + // reset device-specific HTML/flash mode switches + + sm2.html5Only = false; + sm2.ignoreFlash = false; + + window.setTimeout(function() { + + preInit(); + + // by default, re-init + + if (!excludeInit) { + sm2.beginDelayedInit(); + } + + }, 20); + + return sm2; + + }; + + this.reset = function() { + + /** + * Shuts down and restores the SoundManager instance to its original loaded state, without an explicit reboot. All onready/ontimeout handlers are removed. + * After this call, SM2 may be re-initialized via soundManager.beginDelayedInit(). + * @return {object} soundManager The soundManager instance. + */ + + _wDS('reset'); + return sm2.reboot(true, true); }; @@ -1295,8 +1344,15 @@ function SoundManager(smURL, smID) { this.getMoviePercent = function() { - // interesting note: flash/ExternalInterface bridge methods are not typeof "function" nor instanceof Function, but are still valid. - return (_flash && typeof _flash.PercentLoaded !== 'undefined' ? _flash.PercentLoaded() : null); + /** + * Interesting syntax notes... + * Flash/ExternalInterface (ActiveX/NPAPI) bridge methods are not typeof "function" nor instanceof Function, but are still valid. + * Additionally, JSLint dislikes ('PercentLoaded' in flash)-style syntax and recommends hasOwnProperty(), which does not work in this case. + * Furthermore, using (flash && flash.PercentLoaded) causes IE to throw "object doesn't support this property or method". + * Thus, 'in' syntax must be used. + */ + + return (flash && 'PercentLoaded' in flash ? flash.PercentLoaded() : null); // Yes, JSLint. See nearby comment in source for explanation. }; @@ -1306,24 +1362,24 @@ function SoundManager(smURL, smID) { this.beginDelayedInit = function() { - _windowLoaded = true; - _domContentLoaded(); + windowLoaded = true; + domContentLoaded(); setTimeout(function() { - if (_initPending) { + if (initPending) { return false; } - _createMovie(); - _initMovie(); - _initPending = true; + createMovie(); + initMovie(); + initPending = true; return true; }, 20); - _delayWaitForEI(); + delayWaitForEI(); }; @@ -1333,8 +1389,8 @@ function SoundManager(smURL, smID) { this.destruct = function() { - _s._wD(_sm+'.destruct()'); - _s.disable(true); + sm2._wD(sm + '.destruct()'); + sm2.disable(true); }; @@ -1348,9 +1404,9 @@ function SoundManager(smURL, smID) { SMSound = function(oOptions) { - var _t = this, _resetProperties, _add_html5_events, _remove_html5_events, _stop_html5_timer, _start_html5_timer, _attachOnPosition, _onplay_called = false, _onPositionItems = [], _onPositionFired = 0, _detachOnPosition, _applyFromTo, _lastURL = null, _lastHTML5State; + var s = this, resetProperties, add_html5_events, remove_html5_events, stop_html5_timer, start_html5_timer, attachOnPosition, onplay_called = false, onPositionItems = [], onPositionFired = 0, detachOnPosition, applyFromTo, lastURL = null, lastHTML5State; - _lastHTML5State = { + lastHTML5State = { // tracks duration + position (time) duration: null, time: null @@ -1362,7 +1418,7 @@ function SoundManager(smURL, smID) { this.sID = this.id; this.url = oOptions.url; - this.options = _mixin(oOptions); + this.options = mixin(oOptions); // per-play-instance-specific options this.instanceOptions = this.options; @@ -1394,38 +1450,11 @@ function SoundManager(smURL, smID) { this._debug = function() { // - // pseudo-private console.log()-style output - - if (_s.debugMode) { - - var stuff = null, msg = [], sF, sfBracket, maxLength = 64; - - for (stuff in _t.options) { - if (_t.options[stuff] !== null) { - if (typeof _t.options[stuff] === 'function') { - // handle functions specially - sF = _t.options[stuff].toString(); - // normalize spaces - sF = sF.replace(/\s\s+/g, ' '); - sfBracket = sF.indexOf('{'); - msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }'); - } else { - msg.push(' ' + stuff + ': ' + _t.options[stuff]); - } - } - } - - _s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}'); - - } + sm2._wD(s.id + ': Merged options:', s.options); // }; - // - this._debug(); - // - /** * Begins loading a sound per its *url*. * @@ -1435,127 +1464,122 @@ function SoundManager(smURL, smID) { this.load = function(oOptions) { - var oS = null, _iO; + var oSound = null, instanceOptions; - if (typeof oOptions !== 'undefined') { - _t._iO = _mixin(oOptions, _t.options); - _t.instanceOptions = _t._iO; + if (oOptions !== _undefined) { + s._iO = mixin(oOptions, s.options); } else { - oOptions = _t.options; - _t._iO = oOptions; - _t.instanceOptions = _t._iO; - if (_lastURL && _lastURL !== _t.url) { + oOptions = s.options; + s._iO = oOptions; + if (lastURL && lastURL !== s.url) { _wDS('manURL'); - _t._iO.url = _t.url; - _t.url = null; + s._iO.url = s.url; + s.url = null; } } - if (!_t._iO.url) { - _t._iO.url = _t.url; + if (!s._iO.url) { + s._iO.url = s.url; } - _t._iO.url = _parseURL(_t._iO.url); + s._iO.url = parseURL(s._iO.url); - _s._wD('SMSound.load(): ' + _t._iO.url, 1); - - if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { - _wDS('onURL', 1); - // if loaded and an onload() exists, fire immediately. - if (_t.readyState === 3 && _t._iO.onload) { - // assume success based on truthy duration. - _t._iO.onload.apply(_t, [(!!_t.duration)]); - } - return _t; - } + // ensure we're in sync + s.instanceOptions = s._iO; // local shortcut - _iO = _t._iO; + instanceOptions = s._iO; - // make a local copy of the old url before we re-assign it - _lastURL = (_t.url && _t.url.toString ? _t.url.toString() : null); + sm2._wD(s.id + ': load (' + instanceOptions.url + ')'); + + if (instanceOptions.url === s.url && s.readyState !== 0 && s.readyState !== 2) { + _wDS('onURL', 1); + // if loaded and an onload() exists, fire immediately. + if (s.readyState === 3 && instanceOptions.onload) { + // assume success based on truthy duration. + instanceOptions.onload.apply(s, [(!!s.duration)]); + } + return s; + } // reset a few state properties - _t.loaded = false; - _t.readyState = 1; - _t.playState = 0; - _t.id3 = {}; + s.loaded = false; + s.readyState = 1; + s.playState = 0; + s.id3 = {}; // TODO: If switching from HTML5 -> flash (or vice versa), stop currently-playing audio. - if (_html5OK(_iO)) { + if (html5OK(instanceOptions)) { - oS = _t._setup_html5(_iO); + oSound = s._setup_html5(instanceOptions); - if (!oS._called_load) { + if (!oSound._called_load) { - _s._wD(_h5+'load: '+_t.id); - - _t._html5_canplay = false; + s._html5_canplay = false; // TODO: review called_load / html5_canplay logic // if url provided directly to load(), assign it here. - if (_t._a.src !== _iO.url) { + if (s.url !== instanceOptions.url) { - _s._wD(_wDS('manURL') + ': ' + _iO.url); + sm2._wD(_wDS('manURL') + ': ' + instanceOptions.url); - _t._a.src = _iO.url; + s._a.src = instanceOptions.url; // TODO: review / re-apply all relevant options (volume, loop, onposition etc.) // reset position for new URL - _t.setPosition(0); + s.setPosition(0); } // given explicit load call, try to preload. // early HTML5 implementation (non-standard) - _t._a.autobuffer = 'auto'; + s._a.autobuffer = 'auto'; // standard - _t._a.preload = 'auto'; + s._a.preload = 'auto'; - oS._called_load = true; + s._a._called_load = true; - if (_iO.autoPlay) { - _t.play(); + if (instanceOptions.autoPlay) { + s.play(); } } else { - _s._wD(_h5+'ignoring request to load again: '+_t.id); + sm2._wD(s.id + ': Ignoring request to load again'); } } else { try { - _t.isHTML5 = false; - _t._iO = _policyFix(_loopFix(_iO)); + s.isHTML5 = false; + s._iO = policyFix(loopFix(instanceOptions)); // re-assign local shortcut - _iO = _t._iO; - if (_fV === 8) { - _flash._load(_t.id, _iO.url, _iO.stream, _iO.autoPlay, (_iO.whileloading?1:0), _iO.loops||1, _iO.usePolicyFile); + instanceOptions = s._iO; + if (fV === 8) { + flash._load(s.id, instanceOptions.url, instanceOptions.stream, instanceOptions.autoPlay, instanceOptions.usePolicyFile); } else { - _flash._load(_t.id, _iO.url, !!(_iO.stream), !!(_iO.autoPlay), _iO.loops||1, !!(_iO.autoLoad), _iO.usePolicyFile); + flash._load(s.id, instanceOptions.url, !!(instanceOptions.stream), !!(instanceOptions.autoPlay), instanceOptions.loops||1, !!(instanceOptions.autoLoad), instanceOptions.usePolicyFile); } } catch(e) { _wDS('smError', 2); - _debugTS('onload', false); - _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true}); - + debugTS('onload', false); + catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true}); } } // after all of this, ensure sound url is up to date. - _t.url = _iO.url; + s.url = instanceOptions.url; - return _t; + return s; }; @@ -1571,40 +1595,40 @@ function SoundManager(smURL, smID) { // Flash 9/AS3: Close stream, preventing further load // HTML5: Most UAs will use empty URL - if (_t.readyState !== 0) { + if (s.readyState !== 0) { - _s._wD('SMSound.unload(): "' + _t.id + '"'); + sm2._wD(s.id + ': unload()'); - if (!_t.isHTML5) { + if (!s.isHTML5) { - if (_fV === 8) { - _flash._unload(_t.id, _emptyURL); + if (fV === 8) { + flash._unload(s.id, emptyURL); } else { - _flash._unload(_t.id); + flash._unload(s.id); } } else { - _stop_html5_timer(); + stop_html5_timer(); - if (_t._a) { + if (s._a) { - _t._a.pause(); - _html5Unload(_t._a, _emptyURL); + s._a.pause(); + html5Unload(s._a, emptyURL); - // reset local URL for next load / play call, too - _t.url = _emptyURL; + // update empty URL, too + lastURL = emptyURL; } } // reset load/status flags - _resetProperties(); + resetProperties(); } - return _t; + return s; }; @@ -1614,35 +1638,35 @@ function SoundManager(smURL, smID) { this.destruct = function(_bFromSM) { - _s._wD('SMSound.destruct(): "' + _t.id + '"'); + sm2._wD(s.id + ': Destruct'); - if (!_t.isHTML5) { + if (!s.isHTML5) { // kill sound within Flash // Disable the onfailure handler - _t._iO.onfailure = null; - _flash._destroySound(_t.id); + s._iO.onfailure = null; + flash._destroySound(s.id); } else { - _stop_html5_timer(); + stop_html5_timer(); - if (_t._a) { - _t._a.pause(); - _html5Unload(_t._a); - if (!_useGlobalHTML5Audio) { - _remove_html5_events(); + if (s._a) { + s._a.pause(); + html5Unload(s._a); + if (!useGlobalHTML5Audio) { + remove_html5_events(); } // break obvious circular reference - _t._a._t = null; - _t._a = null; + s._a._s = null; + s._a = null; } } if (!_bFromSM) { // ensure deletion from controller - _s.destroySound(_t.id, true); + sm2.destroySound(s.id, true); } @@ -1661,53 +1685,53 @@ function SoundManager(smURL, smID) { exit = null; // - fN = 'SMSound.play(): '; + fN = s.id + ': play(): '; // // default to true - _updatePlayState = (typeof _updatePlayState === 'undefined' ? true : _updatePlayState); + _updatePlayState = (_updatePlayState === _undefined ? true : _updatePlayState); if (!oOptions) { oOptions = {}; } // first, use local URL (if specified) - if (_t.url) { - _t._iO.url = _t.url; + if (s.url) { + s._iO.url = s.url; } // mix in any options defined at createSound() - _t._iO = _mixin(_t._iO, _t.options); + s._iO = mixin(s._iO, s.options); // mix in any options specific to this method - _t._iO = _mixin(oOptions, _t._iO); + s._iO = mixin(oOptions, s._iO); - _t._iO.url = _parseURL(_t._iO.url); + s._iO.url = parseURL(s._iO.url); - _t.instanceOptions = _t._iO; + s.instanceOptions = s._iO; // RTMP-only - if (_t._iO.serverURL && !_t.connected) { - if (!_t.getAutoPlay()) { - _s._wD(fN+' Netstream not connected yet - setting autoPlay'); - _t.setAutoPlay(true); + if (s._iO.serverURL && !s.connected) { + if (!s.getAutoPlay()) { + sm2._wD(fN +' Netstream not connected yet - setting autoPlay'); + s.setAutoPlay(true); } - // play will be called in _onconnect() - return _t; + // play will be called in onconnect() + return s; } - if (_html5OK(_t._iO)) { - _t._setup_html5(_t._iO); - _start_html5_timer(); + if (html5OK(s._iO)) { + s._setup_html5(s._iO); + start_html5_timer(); } - if (_t.playState === 1 && !_t.paused) { - allowMulti = _t._iO.multiShot; + if (s.playState === 1 && !s.paused) { + allowMulti = s._iO.multiShot; if (!allowMulti) { - _s._wD(fN + '"' + _t.id + '" already playing (one-shot)', 1); - exit = _t; + sm2._wD(fN + 'Already playing (one-shot)', 1); + exit = s; } else { - _s._wD(fN + '"' + _t.id + '" already playing (multi-shot)', 1); + sm2._wD(fN + 'Already playing (multi-shot)', 1); } } @@ -1716,41 +1740,44 @@ function SoundManager(smURL, smID) { } // edge case: play() with explicit URL parameter - if (oOptions.url && oOptions.url !== _t.url) { + if (oOptions.url && oOptions.url !== s.url) { // load using merged options - _t.load(_t._iO); + s.load(s._iO); } - if (!_t.loaded) { + if (!s.loaded) { - if (_t.readyState === 0) { + if (s.readyState === 0) { - _s._wD(fN + 'Attempting to load "' + _t.id + '"', 1); + sm2._wD(fN + 'Attempting to load'); // try to get this sound playing ASAP - if (!_t.isHTML5) { + if (!s.isHTML5) { // assign directly because setAutoPlay() increments the instanceCount - _t._iO.autoPlay = true; - _t.load(_t._iO); + s._iO.autoPlay = true; + s.load(s._iO); } else { // iOS needs this when recycling sounds, loading a new URL on an existing object. - _t.load(_t._iO); + s.load(s._iO); } - } else if (_t.readyState === 2) { + // HTML5 hack - re-set instanceOptions? + s.instanceOptions = s._iO; - _s._wD(fN + 'Could not load "' + _t.id + '" - exiting', 2); - exit = _t; + } else if (s.readyState === 2) { + + sm2._wD(fN + 'Could not load - exiting', 2); + exit = s; } else { - _s._wD(fN + '"' + _t.id + '" is loading - attempting to play..', 1); + sm2._wD(fN + 'Loading - attempting to play...'); } } else { - _s._wD(fN + '"' + _t.id + '"'); + sm2._wD(fN); } @@ -1758,9 +1785,9 @@ function SoundManager(smURL, smID) { return exit; } - if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) { + if (!s.isHTML5 && fV === 9 && s.position > 0 && s.position === s.duration) { // flash 9 needs a position reset if play() is called while at the end of a sound. - _s._wD(fN + '"' + _t.id + '": Sound at end, resetting to position:0'); + sm2._wD(fN + 'Sound at end, resetting to position:0'); oOptions.position = 0; } @@ -1773,45 +1800,46 @@ function SoundManager(smURL, smID) { * For normal sounds, just resume. */ - if (_t.paused && _t.position >= 0 && (!_t._iO.serverURL || _t.position > 0)) { + if (s.paused && s.position >= 0 && (!s._iO.serverURL || s.position > 0)) { // https://gist.github.com/37b17df75cc4d7a90bf6 - _s._wD(fN + '"' + _t.id + '" is resuming from paused state',1); - _t.resume(); + sm2._wD(fN + 'Resuming from paused state', 1); + s.resume(); } else { - _t._iO = _mixin(oOptions, _t._iO); + s._iO = mixin(oOptions, s._iO); // apply from/to parameters, if they exist (and not using RTMP) - if (_t._iO.from !== null && _t._iO.to !== null && _t.instanceCount === 0 && _t.playState === 0 && !_t._iO.serverURL) { + if (s._iO.from !== null && s._iO.to !== null && s.instanceCount === 0 && s.playState === 0 && !s._iO.serverURL) { onready = function() { // sound "canplay" or onload() // re-apply from/to to instance options, and start playback - _t._iO = _mixin(oOptions, _t._iO); - _t.play(_t._iO); + s._iO = mixin(oOptions, s._iO); + s.play(s._iO); }; // HTML5 needs to at least have "canplay" fired before seeking. - if (_t.isHTML5 && !_t._html5_canplay) { + if (s.isHTML5 && !s._html5_canplay) { // this hasn't been loaded yet. load it first, and then do this again. - _s._wD(fN+'Beginning load of "'+ _t.id+'" for from/to case'); + sm2._wD(fN + 'Beginning load for from/to case'); - _t.load({ - _oncanplay: onready + s.load({ + // TODO: was _oncanplay. Sounds wrong. + oncanplay: onready }); exit = false; - } else if (!_t.isHTML5 && !_t.loaded && (!_t.readyState || _t.readyState !== 2)) { + } else if (!s.isHTML5 && !s.loaded && (!s.readyState || s.readyState !== 2)) { // to be safe, preload the whole thing in Flash. - _s._wD(fN+'Preloading "'+ _t.id+'" for from/to case'); + sm2._wD(fN + 'Preloading for from/to case'); - _t.load({ + s.load({ onload: onready }); @@ -1825,60 +1853,60 @@ function SoundManager(smURL, smID) { // otherwise, we're ready to go. re-apply local options, and continue - _t._iO = _applyFromTo(); + s._iO = applyFromTo(); } - _s._wD(fN+'"'+ _t.id+'" is starting to play'); + sm2._wD(fN + 'Starting to play'); - if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) { - _t.instanceCount++; + if (!s.instanceCount || s._iO.multiShotEvents || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) { + s.instanceCount++; } // if first play and onposition parameters exist, apply them now - if (_t._iO.onposition && _t.playState === 0) { - _attachOnPosition(_t); + if (s._iO.onposition && s.playState === 0) { + attachOnPosition(s); } - _t.playState = 1; - _t.paused = false; + s.playState = 1; + s.paused = false; - _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position) ? _t._iO.position : 0); + s.position = (s._iO.position !== _undefined && !isNaN(s._iO.position) ? s._iO.position : 0); - if (!_t.isHTML5) { - _t._iO = _policyFix(_loopFix(_t._iO)); + if (!s.isHTML5) { + s._iO = policyFix(loopFix(s._iO)); } - if (_t._iO.onplay && _updatePlayState) { - _t._iO.onplay.apply(_t); - _onplay_called = true; + if (s._iO.onplay && _updatePlayState) { + s._iO.onplay.apply(s); + onplay_called = true; } - _t.setVolume(_t._iO.volume, true); - _t.setPan(_t._iO.pan, true); + s.setVolume(s._iO.volume, true); + s.setPan(s._iO.pan, true); - if (!_t.isHTML5) { + if (!s.isHTML5) { - startOK = _flash._start(_t.id, _t._iO.loops || 1, (_fV === 9 ? _t._iO.position : _t._iO.position / 1000), _t._iO.multiShot); + startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s._iO.position : s._iO.position / 1000), s._iO.multiShot); - if (_fV === 9 && !startOK) { + if (fV === 9 && !startOK) { // edge case: no sound hardware, or 32-channel flash ceiling hit. // applies only to Flash 9, non-NetStream/MovieStar sounds. // http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#play%28%29 - _s._wD(fN+ _t.id+': No sound hardware, or 32-sound ceiling hit'); - if (_t._iO.onplayerror) { - _t._iO.onplayerror.apply(_t); + sm2._wD(fN + 'No sound hardware, or 32-sound ceiling hit'); + if (s._iO.onplayerror) { + s._iO.onplayerror.apply(s); } } } else { - _start_html5_timer(); + start_html5_timer(); - a = _t._setup_html5(); + a = s._setup_html5(); - _t.setPosition(_t._iO.position); + s.setPosition(s._iO.position); a.play(); @@ -1886,7 +1914,7 @@ function SoundManager(smURL, smID) { } - return _t; + return s; }; @@ -1902,72 +1930,75 @@ function SoundManager(smURL, smID) { this.stop = function(bAll) { - var _iO = _t._iO, _oP; + var instanceOptions = s._iO, + originalPosition; - if (_t.playState === 1) { + if (s.playState === 1) { - _t._onbufferchange(0); - _t._resetOnPosition(0); - _t.paused = false; + sm2._wD(s.id + ': stop()'); - if (!_t.isHTML5) { - _t.playState = 0; + s._onbufferchange(0); + s._resetOnPosition(0); + s.paused = false; + + if (!s.isHTML5) { + s.playState = 0; } // remove onPosition listeners, if any - _detachOnPosition(); + detachOnPosition(); // and "to" position, if set - if (_iO.to) { - _t.clearOnPosition(_iO.to); + if (instanceOptions.to) { + s.clearOnPosition(instanceOptions.to); } - if (!_t.isHTML5) { + if (!s.isHTML5) { - _flash._stop(_t.id, bAll); + flash._stop(s.id, bAll); // hack for netStream: just unload - if (_iO.serverURL) { - _t.unload(); + if (instanceOptions.serverURL) { + s.unload(); } } else { - if (_t._a) { + if (s._a) { - _oP = _t.position; + originalPosition = s.position; // act like Flash, though - _t.setPosition(0); + s.setPosition(0); // hack: reflect old position for onstop() (also like Flash) - _t.position = _oP; + s.position = originalPosition; // html5 has no stop() // NOTE: pausing means iOS requires interaction to resume. - _t._a.pause(); + s._a.pause(); - _t.playState = 0; + s.playState = 0; // and update UI - _t._onTimer(); + s._onTimer(); - _stop_html5_timer(); + stop_html5_timer(); } } - _t.instanceCount = 0; - _t._iO = {}; + s.instanceCount = 0; + s._iO = {}; - if (_iO.onstop) { - _iO.onstop.apply(_t); + if (instanceOptions.onstop) { + instanceOptions.onstop.apply(s); } } - return _t; + return s; }; @@ -1979,16 +2010,16 @@ function SoundManager(smURL, smID) { this.setAutoPlay = function(autoPlay) { - _s._wD('sound '+_t.id+' turned autoplay ' + (autoPlay ? 'on' : 'off')); - _t._iO.autoPlay = autoPlay; + sm2._wD(s.id + ': Autoplay turned ' + (autoPlay ? 'on' : 'off')); + s._iO.autoPlay = autoPlay; - if (!_t.isHTML5) { - _flash._setAutoPlay(_t.id, autoPlay); + if (!s.isHTML5) { + flash._setAutoPlay(s.id, autoPlay); if (autoPlay) { // only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP) - if (!_t.instanceCount && _t.readyState === 1) { - _t.instanceCount++; - _s._wD('sound '+_t.id+' incremented instance count to '+_t.instanceCount); + if (!s.instanceCount && s.readyState === 1) { + s.instanceCount++; + sm2._wD(s.id + ': Incremented instance count to '+s.instanceCount); } } } @@ -2003,7 +2034,7 @@ function SoundManager(smURL, smID) { this.getAutoPlay = function() { - return _t._iO.autoPlay; + return s._iO.autoPlay; }; @@ -2016,7 +2047,7 @@ function SoundManager(smURL, smID) { this.setPosition = function(nMsecOffset) { - if (typeof nMsecOffset === 'undefined') { + if (nMsecOffset === _undefined) { nMsecOffset = 0; } @@ -2024,58 +2055,58 @@ function SoundManager(smURL, smID) { position, position1K, // Use the duration from the instance options, if we don't have a track duration yet. // position >= 0 and <= current available (loaded) duration - offset = (_t.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); + offset = (s.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(s.duration || s._iO.duration, Math.max(nMsecOffset, 0))); - original_pos = _t.position; - _t.position = offset; - position1K = _t.position/1000; - _t._resetOnPosition(_t.position); - _t._iO.position = offset; + original_pos = s.position; + s.position = offset; + position1K = s.position/1000; + s._resetOnPosition(s.position); + s._iO.position = offset; - if (!_t.isHTML5) { + if (!s.isHTML5) { - position = (_fV === 9 ? _t.position : position1K); - if (_t.readyState && _t.readyState !== 2) { + position = (fV === 9 ? s.position : position1K); + if (s.readyState && s.readyState !== 2) { // if paused or not playing, will not resume (by playing) - _flash._setPosition(_t.id, position, (_t.paused || !_t.playState), _t._iO.multiShot); + flash._setPosition(s.id, position, (s.paused || !s.playState), s._iO.multiShot); } - } else if (_t._a) { + } else if (s._a) { // Set the position in the canplay handler if the sound is not ready yet - if (_t._html5_canplay) { - if (_t._a.currentTime !== position1K) { + if (s._html5_canplay) { + if (s._a.currentTime !== position1K) { /** * DOM/JS errors/exceptions to watch out for: * if seek is beyond (loaded?) position, "DOM exception 11" * "INDEX_SIZE_ERR": DOM exception 1 */ - _s._wD('setPosition('+position1K+'): setting position'); + sm2._wD(s.id + ': setPosition('+position1K+')'); try { - _t._a.currentTime = position1K; - if (_t.playState === 0 || _t.paused) { + s._a.currentTime = position1K; + if (s.playState === 0 || s.paused) { // allow seek without auto-play/resume - _t._a.pause(); + s._a.pause(); } } catch(e) { - _s._wD('setPosition('+position1K+'): setting position failed: '+e.message, 2); + sm2._wD(s.id + ': setPosition(' + position1K + ') failed: ' + e.message, 2); } } } else { - _s._wD('setPosition('+position1K+'): delaying, sound not ready'); + sm2._wD(s.id + ': setPosition(' + position1K + '): Cannot seek yet, sound not ready'); } } - if (_t.isHTML5) { - if (_t.paused) { + if (s.isHTML5) { + if (s.paused) { // if paused, refresh UI right away // force update - _t._onTimer(true); + s._onTimer(true); } } - return _t; + return s; }; @@ -2087,27 +2118,27 @@ function SoundManager(smURL, smID) { this.pause = function(_bCallFlash) { - if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { - return _t; + if (s.paused || (s.playState === 0 && s.readyState !== 1)) { + return s; } - _s._wD('SMSound.pause()'); - _t.paused = true; + sm2._wD(s.id + ': pause()'); + s.paused = true; - if (!_t.isHTML5) { - if (_bCallFlash || typeof _bCallFlash === 'undefined') { - _flash._pause(_t.id, _t._iO.multiShot); + if (!s.isHTML5) { + if (_bCallFlash || _bCallFlash === _undefined) { + flash._pause(s.id, s._iO.multiShot); } } else { - _t._setup_html5().pause(); - _stop_html5_timer(); + s._setup_html5().pause(); + stop_html5_timer(); } - if (_t._iO.onpause) { - _t._iO.onpause.apply(_t); + if (s._iO.onpause) { + s._iO.onpause.apply(s); } - return _t; + return s; }; @@ -2127,36 +2158,36 @@ function SoundManager(smURL, smID) { this.resume = function() { - var _iO = _t._iO; + var instanceOptions = s._iO; - if (!_t.paused) { - return _t; + if (!s.paused) { + return s; } - _s._wD('SMSound.resume()'); - _t.paused = false; - _t.playState = 1; + sm2._wD(s.id + ': resume()'); + s.paused = false; + s.playState = 1; - if (!_t.isHTML5) { - if (_iO.isMovieStar && !_iO.serverURL) { + if (!s.isHTML5) { + if (instanceOptions.isMovieStar && !instanceOptions.serverURL) { // Bizarre Webkit bug (Chrome reported via 8tracks.com dudes): AAC content paused for 30+ seconds(?) will not resume without a reposition. - _t.setPosition(_t.position); + s.setPosition(s.position); } // flash method is toggle-based (pause/resume) - _flash._pause(_t.id, _iO.multiShot); + flash._pause(s.id, instanceOptions.multiShot); } else { - _t._setup_html5().play(); - _start_html5_timer(); + s._setup_html5().play(); + start_html5_timer(); } - if (!_onplay_called && _iO.onplay) { - _iO.onplay.apply(_t); - _onplay_called = true; - } else if (_iO.onresume) { - _iO.onresume.apply(_t); + if (!onplay_called && instanceOptions.onplay) { + instanceOptions.onplay.apply(s); + onplay_called = true; + } else if (instanceOptions.onresume) { + instanceOptions.onresume.apply(s); } - return _t; + return s; }; @@ -2168,22 +2199,22 @@ function SoundManager(smURL, smID) { this.togglePause = function() { - _s._wD('SMSound.togglePause()'); + sm2._wD(s.id + ': togglePause()'); - if (_t.playState === 0) { - _t.play({ - position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000) + if (s.playState === 0) { + s.play({ + position: (fV === 9 && !s.isHTML5 ? s.position : s.position / 1000) }); - return _t; + return s; } - if (_t.paused) { - _t.resume(); + if (s.paused) { + s.resume(); } else { - _t.pause(); + s.pause(); } - return _t; + return s; }; @@ -2196,26 +2227,26 @@ function SoundManager(smURL, smID) { this.setPan = function(nPan, bInstanceOnly) { - if (typeof nPan === 'undefined') { + if (nPan === _undefined) { nPan = 0; } - if (typeof bInstanceOnly === 'undefined') { + if (bInstanceOnly === _undefined) { bInstanceOnly = false; } - if (!_t.isHTML5) { - _flash._setPan(_t.id, nPan); + if (!s.isHTML5) { + flash._setPan(s.id, nPan); } // else { no HTML5 pan? } - _t._iO.pan = nPan; + s._iO.pan = nPan; if (!bInstanceOnly) { - _t.pan = nPan; - _t.options.pan = nPan; + s.pan = nPan; + s.options.pan = nPan; } - return _t; + return s; }; @@ -2235,29 +2266,29 @@ function SoundManager(smURL, smID) { * http://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingSoundtoCanvasAnimations/AddingSoundtoCanvasAnimations.html */ - if (typeof nVol === 'undefined') { + if (nVol === _undefined) { nVol = 100; } - if (typeof _bInstanceOnly === 'undefined') { + if (_bInstanceOnly === _undefined) { _bInstanceOnly = false; } - if (!_t.isHTML5) { - _flash._setVolume(_t.id, (_s.muted && !_t.muted) || _t.muted?0:nVol); - } else if (_t._a) { + if (!s.isHTML5) { + flash._setVolume(s.id, (sm2.muted && !s.muted) || s.muted?0:nVol); + } else if (s._a) { // valid range: 0-1 - _t._a.volume = Math.max(0, Math.min(1, nVol/100)); + s._a.volume = Math.max(0, Math.min(1, nVol/100)); } - _t._iO.volume = nVol; + s._iO.volume = nVol; if (!_bInstanceOnly) { - _t.volume = nVol; - _t.options.volume = nVol; + s.volume = nVol; + s.options.volume = nVol; } - return _t; + return s; }; @@ -2269,15 +2300,15 @@ function SoundManager(smURL, smID) { this.mute = function() { - _t.muted = true; + s.muted = true; - if (!_t.isHTML5) { - _flash._setVolume(_t.id, 0); - } else if (_t._a) { - _t._a.muted = true; + if (!s.isHTML5) { + flash._setVolume(s.id, 0); + } else if (s._a) { + s._a.muted = true; } - return _t; + return s; }; @@ -2289,16 +2320,16 @@ function SoundManager(smURL, smID) { this.unmute = function() { - _t.muted = false; - var hasIO = (typeof _t._iO.volume !== 'undefined'); + s.muted = false; + var hasIO = (s._iO.volume !== _undefined); - if (!_t.isHTML5) { - _flash._setVolume(_t.id, hasIO?_t._iO.volume:_t.options.volume); - } else if (_t._a) { - _t._a.muted = false; + if (!s.isHTML5) { + flash._setVolume(s.id, hasIO?s._iO.volume:s.options.volume); + } else if (s._a) { + s._a.muted = false; } - return _t; + return s; }; @@ -2310,7 +2341,7 @@ function SoundManager(smURL, smID) { this.toggleMute = function() { - return (_t.muted?_t.unmute():_t.mute()); + return (s.muted?s.unmute():s.mute()); }; @@ -2327,14 +2358,14 @@ function SoundManager(smURL, smID) { // TODO: basic dupe checking? - _onPositionItems.push({ + onPositionItems.push({ position: parseInt(nPosition, 10), method: oMethod, - scope: (typeof oScope !== 'undefined' ? oScope : _t), + scope: (oScope !== _undefined ? oScope : s), fired: false }); - return _t; + return s; }; @@ -2360,16 +2391,16 @@ function SoundManager(smURL, smID) { return false; } - for (i=0; i < _onPositionItems.length; i++) { + for (i=0; i < onPositionItems.length; i++) { - if (nPosition === _onPositionItems[i].position) { + if (nPosition === onPositionItems[i].position) { // remove this item if no method was specified, or, if the method matches - if (!oMethod || (oMethod === _onPositionItems[i].method)) { - if (_onPositionItems[i].fired) { + if (!oMethod || (oMethod === onPositionItems[i].method)) { + if (onPositionItems[i].fired) { // decrement "fired" counter, too - _onPositionFired--; + onPositionFired--; } - _onPositionItems.splice(i, 1); + onPositionItems.splice(i, 1); } } @@ -2379,17 +2410,17 @@ function SoundManager(smURL, smID) { this._processOnPosition = function() { - var i, item, j = _onPositionItems.length; + var i, item, j = onPositionItems.length; - if (!j || !_t.playState || _onPositionFired >= j) { + if (!j || !s.playState || onPositionFired >= j) { return false; } for (i=j-1; i >= 0; i--) { - item = _onPositionItems[i]; - if (!item.fired && _t.position >= item.position) { + item = onPositionItems[i]; + if (!item.fired && s.position >= item.position) { item.fired = true; - _onPositionFired++; + onPositionFired++; item.method.apply(item.scope, [item.position]); } } @@ -2401,17 +2432,17 @@ function SoundManager(smURL, smID) { this._resetOnPosition = function(nPosition) { // reset "fired" for items interested in this position - var i, item, j = _onPositionItems.length; + var i, item, j = onPositionItems.length; if (!j) { return false; } for (i=j-1; i >= 0; i--) { - item = _onPositionItems[i]; + item = onPositionItems[i]; if (item.fired && nPosition <= item.position) { item.fired = false; - _onPositionFired--; + onPositionFired--; } } @@ -2424,33 +2455,33 @@ function SoundManager(smURL, smID) { * -------------------------------- */ - _applyFromTo = function() { + applyFromTo = function() { - var _iO = _t._iO, - f = _iO.from, - t = _iO.to, + var instanceOptions = s._iO, + f = instanceOptions.from, + t = instanceOptions.to, start, end; end = function() { // end has been reached. - _s._wD(_t.id + ': "to" time of ' + t + ' reached.'); + sm2._wD(s.id + ': "To" time of ' + t + ' reached.'); // detach listener - _t.clearOnPosition(t, end); + s.clearOnPosition(t, end); // stop should clear this, too - _t.stop(); + s.stop(); }; start = function() { - _s._wD(_t.id + ': playing "from" ' + f); + sm2._wD(s.id + ': Playing "from" ' + f); // add listener for end if (t !== null && !isNaN(t)) { - _t.onPosition(t, end); + s.onPosition(t, end); } }; @@ -2458,24 +2489,24 @@ function SoundManager(smURL, smID) { if (f !== null && !isNaN(f)) { // apply to instance options, guaranteeing correct start position. - _iO.position = f; + instanceOptions.position = f; // multiShot timing can't be tracked, so prevent that. - _iO.multiShot = false; + instanceOptions.multiShot = false; start(); } // return updated instanceOptions including starting position - return _iO; + return instanceOptions; }; - _attachOnPosition = function() { + attachOnPosition = function() { var item, - op = _t._iO.onposition; + op = s._iO.onposition; // attach onposition things, if any, now. @@ -2483,7 +2514,7 @@ function SoundManager(smURL, smID) { for (item in op) { if (op.hasOwnProperty(item)) { - _t.onPosition(parseInt(item, 10), op[item]); + s.onPosition(parseInt(item, 10), op[item]); } } @@ -2491,10 +2522,10 @@ function SoundManager(smURL, smID) { }; - _detachOnPosition = function() { + detachOnPosition = function() { var item, - op = _t._iO.onposition; + op = s._iO.onposition; // detach any onposition()-style listeners. @@ -2502,7 +2533,7 @@ function SoundManager(smURL, smID) { for (item in op) { if (op.hasOwnProperty(item)) { - _t.clearOnPosition(parseInt(item, 10)); + s.clearOnPosition(parseInt(item, 10)); } } @@ -2510,77 +2541,77 @@ function SoundManager(smURL, smID) { }; - _start_html5_timer = function() { + start_html5_timer = function() { - if (_t.isHTML5) { - _startTimer(_t); + if (s.isHTML5) { + startTimer(s); } }; - _stop_html5_timer = function() { + stop_html5_timer = function() { - if (_t.isHTML5) { - _stopTimer(_t); + if (s.isHTML5) { + stopTimer(s); } }; - _resetProperties = function(retainPosition) { + resetProperties = function(retainPosition) { if (!retainPosition) { - _onPositionItems = []; - _onPositionFired = 0; + onPositionItems = []; + onPositionFired = 0; } - _onplay_called = false; + onplay_called = false; - _t._hasTimer = null; - _t._a = null; - _t._html5_canplay = false; - _t.bytesLoaded = null; - _t.bytesTotal = null; - _t.duration = (_t._iO && _t._iO.duration ? _t._iO.duration : null); - _t.durationEstimate = null; - _t.buffered = []; + s._hasTimer = null; + s._a = null; + s._html5_canplay = false; + s.bytesLoaded = null; + s.bytesTotal = null; + s.duration = (s._iO && s._iO.duration ? s._iO.duration : null); + s.durationEstimate = null; + s.buffered = []; // legacy: 1D array - _t.eqData = []; + s.eqData = []; - _t.eqData.left = []; - _t.eqData.right = []; + s.eqData.left = []; + s.eqData.right = []; - _t.failures = 0; - _t.isBuffering = false; - _t.instanceOptions = {}; - _t.instanceCount = 0; - _t.loaded = false; - _t.metadata = {}; + s.failures = 0; + s.isBuffering = false; + s.instanceOptions = {}; + s.instanceCount = 0; + s.loaded = false; + s.metadata = {}; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success - _t.readyState = 0; + s.readyState = 0; - _t.muted = false; - _t.paused = false; + s.muted = false; + s.paused = false; - _t.peakData = { + s.peakData = { left: 0, right: 0 }; - _t.waveformData = { + s.waveformData = { left: [], right: [] }; - _t.playState = 0; - _t.position = null; + s.playState = 0; + s.position = null; - _t.id3 = {}; + s.id3 = {}; }; - _resetProperties(); + resetProperties(); /** * Pseudo-private SMSound internals @@ -2597,43 +2628,43 @@ function SoundManager(smURL, smID) { var duration, isNew = false, time, x = {}; - if (_t._hasTimer || bForce) { + if (s._hasTimer || bForce) { // TODO: May not need to track readyState (1 = loading) - if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { + if (s._a && (bForce || ((s.playState > 0 || s.readyState === 1) && !s.paused))) { - duration = _t._get_html5_duration(); + duration = s._get_html5_duration(); - if (duration !== _lastHTML5State.duration) { + if (duration !== lastHTML5State.duration) { - _lastHTML5State.duration = duration; - _t.duration = duration; + lastHTML5State.duration = duration; + s.duration = duration; isNew = true; } // TODO: investigate why this goes wack if not set/re-set each time. - _t.durationEstimate = _t.duration; + s.durationEstimate = s.duration; - time = (_t._a.currentTime * 1000 || 0); + time = (s._a.currentTime * 1000 || 0); - if (time !== _lastHTML5State.time) { + if (time !== lastHTML5State.time) { - _lastHTML5State.time = time; + lastHTML5State.time = time; isNew = true; } if (isNew || bForce) { - _t._whileplaying(time,x,x,x,x); + s._whileplaying(time,x,x,x,x); } }/* else { - // _s._wD('_onTimer: Warn for "'+_t.id+'": '+(!_t._a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK')); + // sm2._wD('_onTimer: Warn for "'+s.id+'": '+(!s._a?'Could not find element. ':'')+(s.playState === 0?'playState bad, 0?':'playState = '+s.playState+', OK')); return false; @@ -2647,9 +2678,9 @@ function SoundManager(smURL, smID) { this._get_html5_duration = function() { - var _iO = _t._iO, + var instanceOptions = s._iO, // if audio object exists, use its duration - else, instance option duration (if provided - it's a hack, really, and should be retired) OR null - d = (_t._a && _t._a.duration ? _t._a.duration*1000 : (_iO && _iO.duration ? _iO.duration : null)), + d = (s._a && s._a.duration ? s._a.duration*1000 : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)), result = (d && !isNaN(d) && d !== Infinity ? d : null); return result; @@ -2665,7 +2696,7 @@ function SoundManager(smURL, smID) { // if (!a.loop && nLoops > 1) { - _s._wD('Note: Native HTML5 looping is infinite.'); + sm2._wD('Note: Native HTML5 looping is infinite.', 1); } // @@ -2675,135 +2706,148 @@ function SoundManager(smURL, smID) { this._setup_html5 = function(oOptions) { - var _iO = _mixin(_t._iO, oOptions), d = decodeURI, - _a = _useGlobalHTML5Audio ? _s._global_a : _t._a, - _dURL = d(_iO.url), - _oldIO = (_a && _a._t ? _a._t.instanceOptions : null), - result; + var instanceOptions = mixin(s._iO, oOptions), d = decodeURI, + a = useGlobalHTML5Audio ? globalHTML5Audio : s._a, + dURL = d(instanceOptions.url), + sameURL; - if (_a) { + /** + * "First things first, I, Poppa..." (reset the previous state of the old sound, if playing) + * Fixes case with devices that can only play one sound at a time + * Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state + */ - if (_a._t) { + if (useGlobalHTML5Audio) { - if (!_useGlobalHTML5Audio && _dURL === d(_lastURL)) { + if (dURL === lastGlobalHTML5URL) { + // global HTML5 audio: re-use of URL + sameURL = true; + } - // same url, ignore request - result = _a; + } else if (dURL === lastURL) { - } else if (_useGlobalHTML5Audio && _oldIO.url === _iO.url && (!_lastURL || (_lastURL === _oldIO.url))) { + // options URL is the same as the "last" URL, and we used (loaded) it + sameURL = true; - // iOS-type reuse case - result = _a; + } - } + if (a) { - if (result) { + if (a._s) { - _t._apply_loop(_a, _iO.loops); - return result; + if (useGlobalHTML5Audio) { + + if (a._s && a._s.playState && !sameURL) { + + // global HTML5 audio case, and loading a new URL. stop the currently-playing one. + a._s.stop(); + + } + + } else if (!useGlobalHTML5Audio && dURL === d(lastURL)) { + + // non-global HTML5 reuse case: same url, ignore request + s._apply_loop(a, instanceOptions.loops); + + return a; } } - _s._wD('setting URL on existing object: ' + _dURL + (_lastURL ? ', old URL: ' + _lastURL : '')); + if (!sameURL) { - /** - * "First things first, I, Poppa.." (reset the previous state of the old sound, if playing) - * Fixes case with devices that can only play one sound at a time - * Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state - */ + // don't retain onPosition() stuff with new URL. - if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) { + resetProperties(false); - _a._t.stop(); + // assign new HTML5 URL + + a.src = instanceOptions.url; + + s.url = instanceOptions.url; + + lastURL = instanceOptions.url; + + lastGlobalHTML5URL = instanceOptions.url; + + a._called_load = false; } - // reset load/playstate, onPosition etc. if the URL is new. - // somewhat-tricky object re-use vs. new SMSound object, old vs. new URL comparisons - _resetProperties((_oldIO && _oldIO.url ? _iO.url === _oldIO.url : (_lastURL ? _lastURL === _iO.url : false))); - - _a.src = _iO.url; - _t.url = _iO.url; - _lastURL = _iO.url; - _a._called_load = false; - } else { - _wDS('h5a'); + if (instanceOptions.autoLoad || instanceOptions.autoPlay) { - if (_iO.autoLoad || _iO.autoPlay) { - - _t._a = new Audio(_iO.url); + s._a = new Audio(instanceOptions.url); } else { // null for stupid Opera 9.64 case - _t._a = (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()); + s._a = (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()); } // assign local reference - _a = _t._a; + a = s._a; - _a._called_load = false; + a._called_load = false; - if (_useGlobalHTML5Audio) { + if (useGlobalHTML5Audio) { - _s._global_a = _a; + globalHTML5Audio = a; } } - _t.isHTML5 = true; + s.isHTML5 = true; // store a ref on the track - _t._a = _a; + s._a = a; // store a ref on the audio - _a._t = _t; + a._s = s; - _add_html5_events(); + add_html5_events(); - _t._apply_loop(_a, _iO.loops); + s._apply_loop(a, instanceOptions.loops); - if (_iO.autoLoad || _iO.autoPlay) { + if (instanceOptions.autoLoad || instanceOptions.autoPlay) { - _t.load(); + s.load(); } else { // early HTML5 implementation (non-standard) - _a.autobuffer = false; + a.autobuffer = false; // standard ('none' is also an option.) - _a.preload = 'auto'; + a.preload = 'auto'; } - return _a; + return a; }; - _add_html5_events = function() { + add_html5_events = function() { - if (_t._a._added_events) { + if (s._a._added_events) { return false; } var f; function add(oEvt, oFn, bCapture) { - return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null; + return s._a ? s._a.addEventListener(oEvt, oFn, bCapture||false) : null; } - _t._a._added_events = true; + s._a._added_events = true; - for (f in _html5_events) { - if (_html5_events.hasOwnProperty(f)) { - add(f, _html5_events[f]); + for (f in html5_events) { + if (html5_events.hasOwnProperty(f)) { + add(f, html5_events[f]); } } @@ -2811,22 +2855,22 @@ function SoundManager(smURL, smID) { }; - _remove_html5_events = function() { + remove_html5_events = function() { // Remove event listeners var f; function remove(oEvt, oFn, bCapture) { - return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null); + return (s._a ? s._a.removeEventListener(oEvt, oFn, bCapture||false) : null); } - _s._wD(_h5+'removing event listeners: '+_t.id); - _t._a._added_events = false; + sm2._wD(s.id + ': Removing event listeners'); + s._a._added_events = false; - for (f in _html5_events) { - if (_html5_events.hasOwnProperty(f)) { - remove(f, _html5_events[f]); + for (f in html5_events) { + if (html5_events.hasOwnProperty(f)) { + remove(f, html5_events[f]); } } @@ -2839,30 +2883,29 @@ function SoundManager(smURL, smID) { this._onload = function(nSuccess) { - var fN, // check for duration to prevent false positives from flash 8 when loading from cache. - loadOK = (!!(nSuccess) || (!_t.isHTML5 && _fV === 8 && _t.duration)); + loadOK = !!nSuccess || (!s.isHTML5 && fV === 8 && s.duration); // - fN = 'SMSound._onload(): '; - _s._wD(fN + '"' + _t.id + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2)); - if (!loadOK && !_t.isHTML5) { - if (_s.sandbox.noRemote === true) { - _s._wD(fN + _str('noNet'), 1); + fN = s.id + ': '; + sm2._wD(fN + (loadOK ? 'onload()' : 'Failed to load? - ' + s.url), (loadOK ? 1 : 2)); + if (!loadOK && !s.isHTML5) { + if (sm2.sandbox.noRemote === true) { + sm2._wD(fN + str('noNet'), 1); } - if (_s.sandbox.noLocal === true) { - _s._wD(fN + _str('noLocal'), 1); + if (sm2.sandbox.noLocal === true) { + sm2._wD(fN + str('noLocal'), 1); } } // - _t.loaded = loadOK; - _t.readyState = loadOK?3:2; - _t._onbufferchange(0); + s.loaded = loadOK; + s.readyState = loadOK?3:2; + s._onbufferchange(0); - if (_t._iO.onload) { - _t._iO.onload.apply(_t, [loadOK]); + if (s._iO.onload) { + s._iO.onload.apply(s, [loadOK]); } return true; @@ -2871,19 +2914,19 @@ function SoundManager(smURL, smID) { this._onbufferchange = function(nIsBuffering) { - if (_t.playState === 0) { + if (s.playState === 0) { // ignore if not playing return false; } - if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { + if ((nIsBuffering && s.isBuffering) || (!nIsBuffering && !s.isBuffering)) { return false; } - _t.isBuffering = (nIsBuffering === 1); - if (_t._iO.onbufferchange) { - _s._wD('SMSound._onbufferchange(): ' + nIsBuffering); - _t._iO.onbufferchange.apply(_t); + s.isBuffering = (nIsBuffering === 1); + if (s._iO.onbufferchange) { + sm2._wD(s.id + ': Buffer state change: ' + nIsBuffering); + s._iO.onbufferchange.apply(s); } return true; @@ -2891,15 +2934,15 @@ function SoundManager(smURL, smID) { }; /** - * Notify Mobile Safari that user action is required - * to continue playing / loading the audio file. + * Playback may have stopped due to buffering, or related reason. + * This state can be encountered on iOS < 6 when auto-play is blocked. */ this._onsuspend = function() { - if (_t._iO.onsuspend) { - _s._wD('SMSound._onsuspend()'); - _t._iO.onsuspend.apply(_t); + if (s._iO.onsuspend) { + sm2._wD(s.id + ': Playback suspended'); + s._iO.onsuspend.apply(s); } return true; @@ -2913,55 +2956,55 @@ function SoundManager(smURL, smID) { this._onfailure = function(msg, level, code) { - _t.failures++; - _s._wD('SMSound._onfailure(): "'+_t.id+'" count '+_t.failures); + s.failures++; + sm2._wD(s.id + ': Failures = ' + s.failures); - if (_t._iO.onfailure && _t.failures === 1) { - _t._iO.onfailure(_t, msg, level, code); + if (s._iO.onfailure && s.failures === 1) { + s._iO.onfailure(s, msg, level, code); } else { - _s._wD('SMSound._onfailure(): ignoring'); + sm2._wD(s.id + ': Ignoring failure'); } }; this._onfinish = function() { - // store local copy before it gets trashed.. - var _io_onfinish = _t._iO.onfinish; + // store local copy before it gets trashed... + var io_onfinish = s._iO.onfinish; - _t._onbufferchange(0); - _t._resetOnPosition(0); + s._onbufferchange(0); + s._resetOnPosition(0); // reset some state items - if (_t.instanceCount) { + if (s.instanceCount) { - _t.instanceCount--; + s.instanceCount--; - if (!_t.instanceCount) { + if (!s.instanceCount) { // remove onPosition listeners, if any - _detachOnPosition(); + detachOnPosition(); // reset instance options - _t.playState = 0; - _t.paused = false; - _t.instanceCount = 0; - _t.instanceOptions = {}; - _t._iO = {}; - _stop_html5_timer(); + s.playState = 0; + s.paused = false; + s.instanceCount = 0; + s.instanceOptions = {}; + s._iO = {}; + stop_html5_timer(); // reset position, too - if (_t.isHTML5) { - _t.position = 0; + if (s.isHTML5) { + s.position = 0; } } - if (!_t.instanceCount || _t._iO.multiShotEvents) { + if (!s.instanceCount || s._iO.multiShotEvents) { // fire onfinish for last, or every instance - if (_io_onfinish) { - _s._wD('SMSound._onfinish(): "' + _t.id + '"'); - _io_onfinish.apply(_t); + if (io_onfinish) { + sm2._wD(s.id + ': onfinish()'); + io_onfinish.apply(s); } } @@ -2971,46 +3014,46 @@ function SoundManager(smURL, smID) { this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { - var _iO = _t._iO; + var instanceOptions = s._iO; - _t.bytesLoaded = nBytesLoaded; - _t.bytesTotal = nBytesTotal; - _t.duration = Math.floor(nDuration); - _t.bufferLength = nBufferLength; + s.bytesLoaded = nBytesLoaded; + s.bytesTotal = nBytesTotal; + s.duration = Math.floor(nDuration); + s.bufferLength = nBufferLength; - if (!_t.isHTML5 && !_iO.isMovieStar) { + if (!s.isHTML5 && !instanceOptions.isMovieStar) { - if (_iO.duration) { + if (instanceOptions.duration) { // use duration from options, if specified and larger. nobody should be specifying duration in options, actually, and it should be retired. - _t.durationEstimate = (_t.duration > _iO.duration) ? _t.duration : _iO.duration; + s.durationEstimate = (s.duration > instanceOptions.duration) ? s.duration : instanceOptions.duration; } else { - _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); + s.durationEstimate = parseInt((s.bytesTotal / s.bytesLoaded) * s.duration, 10); } } else { - _t.durationEstimate = _t.duration; + s.durationEstimate = s.duration; } // for flash, reflect sequential-load-style buffering - if (!_t.isHTML5) { - _t.buffered = [{ + if (!s.isHTML5) { + s.buffered = [{ 'start': 0, - 'end': _t.duration + 'end': s.duration }]; } // allow whileloading to fire even if "load" fired under HTML5, due to HTTP range/partials - if ((_t.readyState !== 3 || _t.isHTML5) && _iO.whileloading) { - _iO.whileloading.apply(_t); + if ((s.readyState !== 3 || s.isHTML5) && instanceOptions.whileloading) { + instanceOptions.whileloading.apply(s); } }; this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { - var _iO = _t._iO, + var instanceOptions = s._iO, eqLeft; if (isNaN(nPosition) || nPosition === null) { @@ -3019,49 +3062,49 @@ function SoundManager(smURL, smID) { } // Safari HTML5 play() may return small -ve values when starting from position: 0, eg. -50.120396875. Unexpected/invalid per W3, I think. Normalize to 0. - _t.position = Math.max(0, nPosition); + s.position = Math.max(0, nPosition); - _t._processOnPosition(); + s._processOnPosition(); - if (!_t.isHTML5 && _fV > 8) { + if (!s.isHTML5 && fV > 8) { - if (_iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { - _t.peakData = { + if (instanceOptions.usePeakData && oPeakData !== _undefined && oPeakData) { + s.peakData = { left: oPeakData.leftPeak, right: oPeakData.rightPeak }; } - if (_iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { - _t.waveformData = { + if (instanceOptions.useWaveformData && oWaveformDataLeft !== _undefined && oWaveformDataLeft) { + s.waveformData = { left: oWaveformDataLeft.split(','), right: oWaveformDataRight.split(',') }; } - if (_iO.useEQData) { - if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { + if (instanceOptions.useEQData) { + if (oEQData !== _undefined && oEQData && oEQData.leftEQ) { eqLeft = oEQData.leftEQ.split(','); - _t.eqData = eqLeft; - _t.eqData.left = eqLeft; - if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { - _t.eqData.right = oEQData.rightEQ.split(','); + s.eqData = eqLeft; + s.eqData.left = eqLeft; + if (oEQData.rightEQ !== _undefined && oEQData.rightEQ) { + s.eqData.right = oEQData.rightEQ.split(','); } } } } - if (_t.playState === 1) { + if (s.playState === 1) { // special case/hack: ensure buffering is false if loading from cache (and not yet started) - if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) { - _t._onbufferchange(0); + if (!s.isHTML5 && fV === 8 && !s.position && s.isBuffering) { + s._onbufferchange(0); } - if (_iO.whileplaying) { + if (instanceOptions.whileplaying) { // flash may call after actual finish - _iO.whileplaying.apply(_t); + instanceOptions.whileplaying.apply(s); } } @@ -3078,15 +3121,15 @@ function SoundManager(smURL, smID) { * @param {object} oData */ - _s._wD('SMSound._oncaptiondata(): "' + this.id + '" caption data received.'); + sm2._wD(s.id + ': Caption data received.'); - _t.captiondata = oData; + s.captiondata = oData; - if (_t._iO.oncaptiondata) { - _t._iO.oncaptiondata.apply(_t, [oData]); + if (s._iO.oncaptiondata) { + s._iO.oncaptiondata.apply(s, [oData]); } - }; + }; this._onmetadata = function(oMDProps, oMDData) { @@ -3098,20 +3141,20 @@ function SoundManager(smURL, smID) { * @param {array} oMDData (values) */ - _s._wD('SMSound._onmetadata(): "' + this.id + '" metadata received.'); + sm2._wD(s.id + ': Metadata received.'); var oData = {}, i, j; for (i = 0, j = oMDProps.length; i < j; i++) { oData[oMDProps[i]] = oMDData[i]; } - _t.metadata = oData; + s.metadata = oData; - if (_t._iO.onmetadata) { - _t._iO.onmetadata.apply(_t); + if (s._iO.onmetadata) { + s._iO.onmetadata.apply(s); } - }; + }; this._onid3 = function(oID3Props, oID3Data) { @@ -3123,17 +3166,17 @@ function SoundManager(smURL, smID) { * @param {array} oID3Data (values) */ - _s._wD('SMSound._onid3(): "' + this.id + '" ID3 data received.'); + sm2._wD(s.id + ': ID3 data received.'); var oData = [], i, j; for (i = 0, j = oID3Props.length; i < j; i++) { oData[oID3Props[i]] = oID3Data[i]; } - _t.id3 = _mixin(_t.id3, oData); + s.id3 = mixin(s.id3, oData); - if (_t._iO.onid3) { - _t._iO.onid3.apply(_t); + if (s._iO.onid3) { + s._iO.onid3.apply(s); } }; @@ -3143,24 +3186,24 @@ function SoundManager(smURL, smID) { this._onconnect = function(bSuccess) { bSuccess = (bSuccess === 1); - _s._wD('SMSound._onconnect(): "'+_t.id+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2)); - _t.connected = bSuccess; + sm2._wD(s.id + ': ' + (bSuccess ? 'Connected.' : 'Failed to connect? - ' + s.url), (bSuccess ? 1 : 2)); + s.connected = bSuccess; if (bSuccess) { - _t.failures = 0; + s.failures = 0; - if (_idCheck(_t.id)) { - if (_t.getAutoPlay()) { + if (idCheck(s.id)) { + if (s.getAutoPlay()) { // only update the play state if auto playing - _t.play(undefined, _t.getAutoPlay()); - } else if (_t._iO.autoLoad) { - _t.load(); + s.play(_undefined, s.getAutoPlay()); + } else if (s._iO.autoLoad) { + s.load(); } } - if (_t._iO.onconnect) { - _t._iO.onconnect.apply(_t, [bSuccess]); + if (s._iO.onconnect) { + s._iO.onconnect.apply(s, [bSuccess]); } } @@ -3171,15 +3214,19 @@ function SoundManager(smURL, smID) { // flash 9 wave/eq data handler // hack: called at start, and end from flash at/after onfinish() - if (_t.playState > 0) { - _s._wD('SMSound._ondataerror(): ' + sError); - if (_t._iO.ondataerror) { - _t._iO.ondataerror.apply(_t); + if (s.playState > 0) { + sm2._wD(s.id + ': Data error: ' + sError); + if (s._iO.ondataerror) { + s._iO.ondataerror.apply(s); } } }; + // + this._debug(); + // + }; // SMSound() /** @@ -3187,29 +3234,29 @@ function SoundManager(smURL, smID) { * ------------------------------ */ - _getDocument = function() { + getDocument = function() { - return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]); + return (doc.body || doc._docElement || doc.getElementsByTagName('div')[0]); }; - _id = function(sID) { + id = function(sID) { - return _doc.getElementById(sID); + return doc.getElementById(sID); }; - _mixin = function(oMain, oAdd) { + mixin = function(oMain, oAdd) { // non-destructive merge var o1 = (oMain || {}), o2, o; // if unspecified, o2 is the default options object - o2 = (typeof oAdd === 'undefined' ? _s.defaultOptions : oAdd); + o2 = (oAdd === _undefined ? sm2.defaultOptions : oAdd); for (o in o2) { - if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { + if (o2.hasOwnProperty(o) && o1[o] === _undefined) { if (typeof o2[o] !== 'object' || o2[o] === null) { @@ -3219,7 +3266,7 @@ function SoundManager(smURL, smID) { } else { // recurse through o2 - o1[o] = _mixin(o1[o], o2[o]); + o1[o] = mixin(o1[o], o2[o]); } @@ -3233,7 +3280,7 @@ function SoundManager(smURL, smID) { // additional soundManager properties that soundManager.setup() will accept - _extraOptions = { + extraOptions = { 'onready': 1, 'ontimeout': 1, 'defaultOptions': 1, @@ -3241,7 +3288,7 @@ function SoundManager(smURL, smID) { 'movieStarOptions': 1 }; - _assign = function(o, oParent) { + assign = function(o, oParent) { /** * recursive assignment of properties, soundManager.setup() helper @@ -3250,15 +3297,15 @@ function SoundManager(smURL, smID) { var i, result = true, - hasParent = (typeof oParent !== 'undefined'), - setupOptions = _s.setupOptions, - extraOptions = _extraOptions; + hasParent = (oParent !== _undefined), + setupOptions = sm2.setupOptions, + bonusOptions = extraOptions; // // if soundManager.setup() called, show accepted parameters. - if (typeof o === 'undefined') { + if (o === _undefined) { result = []; @@ -3270,15 +3317,15 @@ function SoundManager(smURL, smID) { } - for (i in extraOptions) { + for (i in bonusOptions) { - if (extraOptions.hasOwnProperty(i)) { + if (bonusOptions.hasOwnProperty(i)) { - if (typeof _s[i] === 'object') { + if (typeof sm2[i] === 'object') { result.push(i+': {...}'); - } else if (_s[i] instanceof Function) { + } else if (sm2[i] instanceof Function) { result.push(i+': function() {...}'); @@ -3292,7 +3339,7 @@ function SoundManager(smURL, smID) { } - _s._wD(_str('setup', result.join(', '))); + sm2._wD(str('setup', result.join(', '))); return false; @@ -3306,46 +3353,46 @@ function SoundManager(smURL, smID) { // if not an {object} we want to recurse through... - if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array) { + if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array || o[i] instanceof RegExp) { // check "allowed" options - if (hasParent && typeof extraOptions[oParent] !== 'undefined') { + if (hasParent && bonusOptions[oParent] !== _undefined) { // valid recursive / nested object option, eg., { defaultOptions: { volume: 50 } } - _s[oParent][i] = o[i]; + sm2[oParent][i] = o[i]; - } else if (typeof setupOptions[i] !== 'undefined') { + } else if (setupOptions[i] !== _undefined) { // special case: assign to setupOptions object, which soundManager property references - _s.setupOptions[i] = o[i]; + sm2.setupOptions[i] = o[i]; // assign directly to soundManager, too - _s[i] = o[i]; + sm2[i] = o[i]; - } else if (typeof extraOptions[i] === 'undefined') { + } else if (bonusOptions[i] === _undefined) { // invalid or disallowed parameter. complain. - _complain(_str((typeof _s[i] === 'undefined' ? 'setupUndef' : 'setupError'), i), 2); + complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2); result = false; } else { /** - * valid extraOptions parameter. + * valid extraOptions (bonusOptions) parameter. * is it a method, like onready/ontimeout? call it. * multiple parameters should be in an array, eg. soundManager.setup({onready: [myHandler, myScope]}); */ - if (_s[i] instanceof Function) { + if (sm2[i] instanceof Function) { - _s[i].apply(_s, (o[i] instanceof Array? o[i] : [o[i]])); + sm2[i].apply(sm2, (o[i] instanceof Array? o[i] : [o[i]])); } else { // good old-fashioned direct assignment - _s[i] = o[i]; + sm2[i] = o[i]; } @@ -3355,17 +3402,17 @@ function SoundManager(smURL, smID) { // recursion case, eg., { defaultOptions: { ... } } - if (typeof extraOptions[i] === 'undefined') { + if (bonusOptions[i] === _undefined) { // invalid or disallowed parameter. complain. - _complain(_str((typeof _s[i] === 'undefined' ? 'setupUndef' : 'setupError'), i), 2); + complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2); result = false; } else { // recurse through object - return _assign(o[i], i); + return assign(o[i], i); } @@ -3379,10 +3426,10 @@ function SoundManager(smURL, smID) { }; - function _preferFlashCheck(kind) { + function preferFlashCheck(kind) { // whether flash should play a given type - return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind])); + return (sm2.preferFlash && hasFlash && !sm2.ignoreFlash && (sm2.flash[kind] !== _undefined && sm2.flash[kind])); } @@ -3391,17 +3438,19 @@ function SoundManager(smURL, smID) { * --------------------------------- */ - _event = (function() { + event = (function() { - var old = (_win.attachEvent), + // normalize event methods + var old = (window.attachEvent), evt = { add: (old?'attachEvent':'addEventListener'), remove: (old?'detachEvent':'removeEventListener') }; + // normalize "on" event prefix, optional capture argument function getArgs(oArgs) { - var args = _slice.call(oArgs), + var args = slice.call(oArgs), len = args.length; if (old) { @@ -3421,10 +3470,12 @@ function SoundManager(smURL, smID) { function apply(args, sType) { + // normalize and call the event method, with the proper arguments var element = args.shift(), method = [evt[sType]]; if (old) { + // old IE can't do apply(). element[method](args[0], args[1]); } else { element[method].apply(element, args); @@ -3456,21 +3507,21 @@ function SoundManager(smURL, smID) { * ----------------------------- */ - function _html5_event(oFn) { + function html5_event(oFn) { - // wrap html5 event handlers so we don't call them on destroyed sounds + // wrap html5 event handlers so we don't call them on destroyed and/or unloaded sounds return function(e) { - var t = this._t, + var s = this._s, result; - if (!t || !t._a) { + if (!s || !s._a) { // - if (t && t.id) { - _s._wD(_h5+'ignoring '+e.type+': '+t.id); + if (s && s.id) { + sm2._wD(s.id + ': Ignoring ' + e.type); } else { - _s._wD(_h5+'ignoring '+e.type); + sm2._wD(h5 + 'Ignoring ' + e.type); } // result = null; @@ -3484,139 +3535,139 @@ function SoundManager(smURL, smID) { } - _html5_events = { + html5_events = { // HTML5 event-name-to-handler map - abort: _html5_event(function() { + abort: html5_event(function() { - _s._wD(_h5+'abort: '+this._t.id); + sm2._wD(this._s.id + ': abort'); }), // enough has loaded to play - canplay: _html5_event(function() { + canplay: html5_event(function() { - var t = this._t, + var s = this._s, position1K; - if (t._html5_canplay) { + if (s._html5_canplay) { // this event has already fired. ignore. return true; } - t._html5_canplay = true; - _s._wD(_h5+'canplay: '+t.id+', '+t.url); - t._onbufferchange(0); + s._html5_canplay = true; + sm2._wD(s.id + ': canplay'); + s._onbufferchange(0); // position according to instance options - position1K = (typeof t._iO.position !== 'undefined' && !isNaN(t._iO.position)?t._iO.position/1000:null); + position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/1000:null); // set the position if position was set before the sound loaded - if (t.position && this.currentTime !== position1K) { - _s._wD(_h5+'canplay: setting position to '+position1K); + if (s.position && this.currentTime !== position1K) { + sm2._wD(s.id + ': canplay: Setting position to ' + position1K); try { this.currentTime = position1K; } catch(ee) { - _s._wD(_h5+'setting position of ' + position1K + ' failed: '+ee.message, 2); + sm2._wD(s.id + ': canplay: Setting position of ' + position1K + ' failed: ' + ee.message, 2); } } // hack for HTML5 from/to case - if (t._iO._oncanplay) { - t._iO._oncanplay(); + if (s._iO._oncanplay) { + s._iO._oncanplay(); } }), - canplaythrough: _html5_event(function() { + canplaythrough: html5_event(function() { - var t = this._t; + var s = this._s; - if (!t.loaded) { - t._onbufferchange(0); - t._whileloading(t.bytesLoaded, t.bytesTotal, t._get_html5_duration()); - t._onload(true); + if (!s.loaded) { + s._onbufferchange(0); + s._whileloading(s.bytesLoaded, s.bytesTotal, s._get_html5_duration()); + s._onload(true); } }), // TODO: Reserved for potential use /* - emptied: _html5_event(function() { + emptied: html5_event(function() { - _s._wD(_h5+'emptied: '+this._t.id); + sm2._wD(this._s.id + ': emptied'); }), */ - ended: _html5_event(function() { + ended: html5_event(function() { - var t = this._t; + var s = this._s; - _s._wD(_h5+'ended: '+t.id); - t._onfinish(); + sm2._wD(s.id + ': ended'); + + s._onfinish(); }), - error: _html5_event(function() { + error: html5_event(function() { - _s._wD(_h5+'error: '+this.error.code); + sm2._wD(this._s.id + ': HTML5 error, code ' + this.error.code); // call load with error state? - this._t._onload(false); + this._s._onload(false); }), - loadeddata: _html5_event(function() { + loadeddata: html5_event(function() { - var t = this._t; + var s = this._s; - _s._wD(_h5+'loadeddata: '+this._t.id); + sm2._wD(s.id + ': loadeddata'); // safari seems to nicely report progress events, eventually totalling 100% - if (!t._loaded && !_isSafari) { - t.duration = t._get_html5_duration(); + if (!s._loaded && !isSafari) { + s.duration = s._get_html5_duration(); } }), - loadedmetadata: _html5_event(function() { + loadedmetadata: html5_event(function() { - _s._wD(_h5+'loadedmetadata: '+this._t.id); + sm2._wD(this._s.id + ': loadedmetadata'); }), - loadstart: _html5_event(function() { + loadstart: html5_event(function() { - _s._wD(_h5+'loadstart: '+this._t.id); + sm2._wD(this._s.id + ': loadstart'); // assume buffering at first - this._t._onbufferchange(1); + this._s._onbufferchange(1); }), - play: _html5_event(function() { + play: html5_event(function() { - _s._wD(_h5+'play: '+this._t.id+', '+this._t.url); + sm2._wD(this._s.id + ': play()'); // once play starts, no buffering - this._t._onbufferchange(0); + this._s._onbufferchange(0); }), - playing: _html5_event(function() { - - _s._wD(_h5+'playing: '+this._t.id); + playing: html5_event(function() { + sm2._wD(this._s.id + ': playing'); // once play starts, no buffering - this._t._onbufferchange(0); + this._s._onbufferchange(0); }), - progress: _html5_event(function(e) { + progress: html5_event(function(e) { // note: can fire repeatedly after "loaded" event, due to use of HTTP range/partials - var t = this._t, + var s = this._s, i, j, str, buffered = 0, isProgress = (e.type === 'progress'), ranges = e.target.buffered, @@ -3627,7 +3678,7 @@ function SoundManager(smURL, smID) { scale = 1000; // reset the "buffered" (loaded byte ranges) array - t.buffered = []; + s.buffered = []; if (ranges && ranges.length) { @@ -3636,7 +3687,7 @@ function SoundManager(smURL, smID) { // re-build "buffered" array for (i=0, j=ranges.length; i @@ -3668,68 +3719,68 @@ function SoundManager(smURL, smID) { if (!isNaN(loaded)) { // if progress, likely not buffering - t._onbufferchange(0); + s._onbufferchange(0); // TODO: prevent calls with duplicate values. - t._whileloading(loaded, total, t._get_html5_duration()); + s._whileloading(loaded, total, s._get_html5_duration()); if (loaded && total && loaded === total) { // in case "onload" doesn't fire (eg. gecko 1.9.2) - _html5_events.canplaythrough.call(this, e); + html5_events.canplaythrough.call(this, e); } } }), - ratechange: _html5_event(function() { + ratechange: html5_event(function() { - _s._wD(_h5+'ratechange: '+this._t.id); + sm2._wD(this._s.id + ': ratechange'); }), - suspend: _html5_event(function(e) { + suspend: html5_event(function(e) { // download paused/stopped, may have finished (eg. onload) - var t = this._t; + var s = this._s; - _s._wD(_h5+'suspend: '+t.id); - _html5_events.progress.call(this, e); - t._onsuspend(); + sm2._wD(this._s.id + ': suspend'); + html5_events.progress.call(this, e); + s._onsuspend(); }), - stalled: _html5_event(function() { + stalled: html5_event(function() { - _s._wD(_h5+'stalled: '+this._t.id); + sm2._wD(this._s.id + ': stalled'); }), - timeupdate: _html5_event(function() { + timeupdate: html5_event(function() { - this._t._onTimer(); + this._s._onTimer(); }), - waiting: _html5_event(function() { + waiting: html5_event(function() { - var t = this._t; + var s = this._s; // see also: seeking - _s._wD(_h5+'waiting: '+t.id); + sm2._wD(this._s.id + ': waiting'); // playback faster than download rate, etc. - t._onbufferchange(1); + s._onbufferchange(1); }) }; - _html5OK = function(iO) { + html5OK = function(iO) { // playability test based on URL or MIME type var result; - if (iO.serverURL || (iO.type && _preferFlashCheck(iO.type))) { + if (iO.serverURL || (iO.type && preferFlashCheck(iO.type))) { // RTMP, or preferring flash result = false; @@ -3737,7 +3788,7 @@ function SoundManager(smURL, smID) { } else { // Use type, if specified. If HTML5-only mode, no other options, so just give 'er - result = ((iO.type ? _html5CanPlay({type:iO.type}) : _html5CanPlay({url:iO.url}) || _s.html5Only)); + result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only)); } @@ -3745,7 +3796,7 @@ function SoundManager(smURL, smID) { }; - _html5Unload = function(oAudio, url) { + html5Unload = function(oAudio, url) { /** * Internal method: Unload media, and cancel any current/pending network requests. @@ -3756,13 +3807,25 @@ function SoundManager(smURL, smID) { */ if (oAudio) { + // Firefox likes '' for unload (used to work?) - however, may request hosting page URL (bad.) Most other UAs dislike '' and fail to unload. oAudio.src = url; + + // reset some state, too + oAudio._called_load = false; + + } + + if (useGlobalHTML5Audio) { + + // ensure URL state is trashed, also + lastGlobalHTML5URL = null; + } }; - _html5CanPlay = function(o) { + html5CanPlay = function(o) { /** * Try to find MIME, test and return truthiness @@ -3772,13 +3835,13 @@ function SoundManager(smURL, smID) { * } */ - if (!_s.useHTML5Audio || !_s.hasHTML5) { + if (!sm2.useHTML5Audio || !sm2.hasHTML5) { return false; } var url = (o.url || null), mime = (o.type || null), - aF = _s.audioFormats, + aF = sm2.audioFormats, result, offset, fileExt, @@ -3786,25 +3849,25 @@ function SoundManager(smURL, smID) { // account for known cases like audio/mp3 - if (mime && typeof _s.html5[mime] !== 'undefined') { - return (_s.html5[mime] && !_preferFlashCheck(mime)); + if (mime && sm2.html5[mime] !== _undefined) { + return (sm2.html5[mime] && !preferFlashCheck(mime)); } - if (!_html5Ext) { - _html5Ext = []; + if (!html5Ext) { + html5Ext = []; for (item in aF) { if (aF.hasOwnProperty(item)) { - _html5Ext.push(item); + html5Ext.push(item); if (aF[item].related) { - _html5Ext = _html5Ext.concat(aF[item].related); + html5Ext = html5Ext.concat(aF[item].related); } } } - _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')(\\?.*)?$','i'); + html5Ext = new RegExp('\\.('+html5Ext.join('|')+')(\\?.*)?$','i'); } // TODO: Strip URL queries, etc. - fileExt = (url ? url.toLowerCase().match(_html5Ext) : null); + fileExt = (url ? url.toLowerCase().match(html5Ext) : null); if (!fileExt || !fileExt.length) { if (!mime) { @@ -3812,7 +3875,7 @@ function SoundManager(smURL, smID) { } else { // audio/mp3 -> mp3, result should be known offset = mime.indexOf(';'); - // strip "audio/X; codecs.." + // strip "audio/X; codecs..." fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6); } } else { @@ -3820,37 +3883,37 @@ function SoundManager(smURL, smID) { fileExt = fileExt[1]; } - if (fileExt && typeof _s.html5[fileExt] !== 'undefined') { + if (fileExt && sm2.html5[fileExt] !== _undefined) { // result known - result = (_s.html5[fileExt] && !_preferFlashCheck(fileExt)); + result = (sm2.html5[fileExt] && !preferFlashCheck(fileExt)); } else { mime = 'audio/'+fileExt; - result = _s.html5.canPlayType({type:mime}); - _s.html5[fileExt] = result; - // _s._wD('canPlayType, found result: '+result); - result = (result && _s.html5[mime] && !_preferFlashCheck(mime)); + result = sm2.html5.canPlayType({type:mime}); + sm2.html5[fileExt] = result; + // sm2._wD('canPlayType, found result: ' + result); + result = (result && sm2.html5[mime] && !preferFlashCheck(mime)); } return result; }; - _testHTML5 = function() { + testHTML5 = function() { /** * Internal: Iterates over audioFormats, determining support eg. audio/mp3, audio/mpeg and so on * assigns results to html5[] and flash[]. */ - if (!_s.useHTML5Audio || !_s.hasHTML5) { + if (!sm2.useHTML5Audio || !sm2.hasHTML5) { return false; } // double-whammy: Opera 9.64 throws WRONG_ARGUMENTS_ERR if no parameter passed to Audio(), and Webkit + iOS happily tries to load "null" as a URL. :/ - var a = (typeof Audio !== 'undefined' ? (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null), + var a = (Audio !== _undefined ? (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null), item, lookup, support = {}, aF, i; - function _cp(m) { + function cp(m) { var canPlay, i, j, result = false, @@ -3863,17 +3926,17 @@ function SoundManager(smURL, smID) { if (m instanceof Array) { // iterate through all mime types, return any successes for (i=0, j=m.length; i - notReady: 'Not loaded yet - wait for soundManager.onready()', + notReady: 'Unavailable - wait until onready() has fired.', notOK: 'Audio support is not available.', - domError: _smc + 'createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.', - spcWmode: _smc + 'createMovie(): Removing wmode, preventing known SWF loading issue(s)', - swf404: _sm + ': Verify that %s is a valid path.', - tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)', + domError: sm + 'exception caught while appending SWF to DOM.', + spcWmode: 'Removing wmode, preventing known SWF loading issue(s)', + swf404: smc + 'Verify that %s is a valid path.', + tryDebug: 'Try ' + sm + '.debugFlash = true for more security details (output goes to SWF.)', checkSWF: 'See SWF output for more debug info.', - localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/', - waitFocus: _sm + ': Special case: Waiting for SWF to load with window focus...', - waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...', - waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...', - waitSWF: _sm + ': Retrying, waiting for 100% SWF load...', - needFunction: _sm + ': Function object expected for %s', + localFail: smc + 'Non-HTTP page (' + doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/', + waitFocus: smc + 'Special case: Waiting for SWF to load with window focus...', + waitForever: smc + 'Waiting indefinitely for Flash (will recover if unblocked)...', + waitSWF: smc + 'Waiting for 100% SWF load...', + needFunction: smc + 'Function object expected for %s', badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', - currentObj: '--- ' + _sm + '._debug(): Current sound objects ---', - waitEI: _smc + 'initMovie(): Waiting for ExternalInterface call from Flash...', - waitOnload: _sm + ': Waiting for window.onload()', - docLoaded: _sm + ': Document already loaded', - onload: _smc + 'initComplete(): calling soundManager.onload()', - onloadOK: _sm + '.onload() complete', - init: _smc + 'init()', - didInit: _smc + 'init(): Already called?', - flashJS: _sm + ': Attempting JS to Flash call...', + currentObj: smc + '_debug(): Current sound objects', + waitOnload: smc + 'Waiting for window.onload()', + docLoaded: smc + 'Document already loaded', + onload: smc + 'initComplete(): calling soundManager.onload()', + onloadOK: sm + '.onload() complete', + didInit: smc + 'init(): Already called?', 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', - badRemove: 'Warning: Failed to remove flash movie.', - shutdown: _sm + '.disable(): Shutting down', - queue: _sm + ': Queueing %s handler', - smFail: _sm + ': Failed to initialise.', + badRemove: smc + 'Failed to remove Flash node.', + shutdown: sm + '.disable(): Shutting down', + queue: smc + 'Queueing %s handler', smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', - fbTimeout: 'No flash response, applying .'+_swfCSS.swfTimedout+' CSS...', + fbTimeout: 'No flash response, applying .'+swfCSS.swfTimedout+' CSS...', fbLoaded: 'Flash loaded', - fbHandler: _smc+'flashBlockHandler()', + flRemoved: smc + 'Flash movie removed.', + fbHandler: smc + 'flashBlockHandler()', manURL: 'SMSound.load(): Using manually-assigned URL', - onURL: _sm + '.load(): current URL already assigned.', - badFV: _sm + '.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.', + onURL: sm + '.load(): current URL already assigned.', + badFV: sm + '.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.', as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)', noNSLoop: 'Note: Looping not implemented for MovieStar formats', needfl9: 'Note: Switching to flash 9, required for MP4 formats.', mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case', - needFlash: _sm + ': Fatal error: Flash is needed to play some required formats, but is not available.', - gotFocus: _sm + ': Got window focus.', - mfOn: 'mobileFlash::enabling on-screen flash repositioning', + needFlash: smc + 'Fatal error: Flash is needed to play some required formats, but is not available.', + gotFocus: smc + 'Got window focus.', policy: 'Enabling usePolicyFile for data access', - setup: _sm + '.setup(): allowed parameters: %s', - setupError: _sm + '.setup(): "%s" cannot be assigned with this method.', - setupUndef: _sm + '.setup(): Could not find option "%s"', - setupLate: _sm + '.setup(): url + flashVersion changes will not take effect until reboot().', - h5a: 'creating HTML5 Audio() object', - noURL: _sm + ': Flash URL required. Call soundManager.setup({url:...}) to get started.' + setup: sm + '.setup(): allowed parameters: %s', + setupError: sm + '.setup(): "%s" cannot be assigned with this method.', + setupUndef: sm + '.setup(): Could not find option "%s"', + setupLate: sm + '.setup(): url, flashVersion and html5Test property changes will not take effect until reboot().', + noURL: smc + 'Flash URL required. Call soundManager.setup({url:...}) to get started.', + sm2Loaded: 'SoundManager 2: Ready.', + reset: sm + '.reset(): Removing event callbacks', + mobileUA: 'Mobile UA detected, preferring HTML5 by default.', + globalHTML5: 'Using singleton HTML5 Audio() pattern for this device.' // }; - _str = function() { + str = function() { // internal string replace helper. // arguments: o [,items to replace] // // real array, please - var args = _slice.call(arguments), + var args = slice.call(arguments), // first arg o = args.shift(), - str = (_strings && _strings[o]?_strings[o]:''), i, j; + str = (strings && strings[o]?strings[o]:''), i, j; if (str && args && args.length) { for (i = 0, j = args.length; i < j; i++) { str = str.replace('%s', args[i]); @@ -4014,10 +4075,10 @@ function SoundManager(smURL, smID) { }; - _loopFix = function(sOpt) { + loopFix = function(sOpt) { // flash 8 requires stream = false for looping to work - if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { + if (fV === 8 && sOpt.loops > 1 && sOpt.stream) { _wDS('as2loop'); sOpt.stream = false; } @@ -4026,10 +4087,10 @@ function SoundManager(smURL, smID) { }; - _policyFix = function(sOpt, sPre) { + policyFix = function(sOpt, sPre) { if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { - _s._wD((sPre || '') + _str('policy')); + sm2._wD((sPre || '') + str('policy')); sOpt.usePolicyFile = true; } @@ -4037,31 +4098,31 @@ function SoundManager(smURL, smID) { }; - _complain = function(sMsg) { + complain = function(sMsg) { // - if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') { + if (console !== _undefined && console.warn !== _undefined) { console.warn(sMsg); } else { - _s._wD(sMsg); + sm2._wD(sMsg); } // }; - _doNothing = function() { + doNothing = function() { return false; }; - _disableObject = function(o) { + disableObject = function(o) { var oProp; for (oProp in o) { if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { - o[oProp] = _doNothing; + o[oProp] = doNothing; } } @@ -4069,22 +4130,21 @@ function SoundManager(smURL, smID) { }; - _failSafely = function(bNoDisable) { + failSafely = function(bNoDisable) { // general failure exception handler - if (typeof bNoDisable === 'undefined') { + if (bNoDisable === _undefined) { bNoDisable = false; } - if (_disabled || bNoDisable) { - _wDS('smFail', 2); - _s.disable(bNoDisable); + if (disabled || bNoDisable) { + sm2.disable(bNoDisable); } }; - _normalizeMovieURL = function(smURL) { + normalizeMovieURL = function(smURL) { var urlParams = null, url; @@ -4101,9 +4161,9 @@ function SoundManager(smURL, smID) { } } - url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL; + url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + sm2.movieURL; - if (_s.noSWFCache) { + if (sm2.noSWFCache) { url += ('?ts=' + new Date().getTime()); } @@ -4111,81 +4171,81 @@ function SoundManager(smURL, smID) { }; - _setVersionInfo = function() { + setVersionInfo = function() { // short-hand for internal use - _fV = parseInt(_s.flashVersion, 10); + fV = parseInt(sm2.flashVersion, 10); - if (_fV !== 8 && _fV !== 9) { - _s._wD(_str('badFV', _fV, _defaultFlashVersion)); - _s.flashVersion = _fV = _defaultFlashVersion; + if (fV !== 8 && fV !== 9) { + sm2._wD(str('badFV', fV, defaultFlashVersion)); + sm2.flashVersion = fV = defaultFlashVersion; } // debug flash movie, if applicable - var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); + var isDebug = (sm2.debugMode || sm2.debugFlash?'_debug.swf':'.swf'); - if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) { - _s._wD(_str('needfl9')); - _s.flashVersion = _fV = 9; + if (sm2.useHTML5Audio && !sm2.html5Only && sm2.audioFormats.mp4.required && fV < 9) { + sm2._wD(str('needfl9')); + sm2.flashVersion = fV = 9; } - _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); + sm2.version = sm2.versionNumber + (sm2.html5Only?' (HTML5-only mode)':(fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); // set up default options - if (_fV > 8) { + if (fV > 8) { // +flash 9 base options - _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); - _s.features.buffering = true; + sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.flash9Options); + sm2.features.buffering = true; // +moviestar support - _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); - _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); - _s.features.movieStar = true; + sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.movieStarOptions); + sm2.filePatterns.flash9 = new RegExp('\\.(mp3|' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); + sm2.features.movieStar = true; } else { - _s.features.movieStar = false; + sm2.features.movieStar = false; } // regExp for flash canPlay(), etc. - _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; + sm2.filePattern = sm2.filePatterns[(fV !== 8?'flash9':'flash8')]; // if applicable, use _debug versions of SWFs - _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug); + sm2.movieURL = (fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug); - _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); + sm2.features.peakData = sm2.features.waveformData = sm2.features.eqData = (fV > 8); }; - _setPolling = function(bPolling, bHighPerformance) { + setPolling = function(bPolling, bHighPerformance) { - if (!_flash) { + if (!flash) { return false; } - _flash._setPolling(bPolling, bHighPerformance); + flash._setPolling(bPolling, bHighPerformance); }; - _initDebug = function() { + initDebug = function() { // starts debug mode, creating output
for UAs without console object // allow force of debug mode via URL - if (_s.debugURLParam.test(_wl)) { - _s.debugMode = true; + if (sm2.debugURLParam.test(wl)) { + sm2.debugMode = true; } // - if (_id(_s.debugID)) { + if (id(sm2.debugID)) { return false; } var oD, oDebug, oTarget, oToggle, tmp; - if (_s.debugMode && !_id(_s.debugID) && (!_hasConsole || !_s.useConsole || !_s.consoleOnly)) { + if (sm2.debugMode && !id(sm2.debugID) && (!hasConsole || !sm2.useConsole || !sm2.consoleOnly)) { - oD = _doc.createElement('div'); - oD.id = _s.debugID + '-toggle'; + oD = doc.createElement('div'); + oD.id = sm2.debugID + '-toggle'; oToggle = { 'position': 'fixed', @@ -4203,11 +4263,11 @@ function SoundManager(smURL, smID) { 'zIndex': 10001 }; - oD.appendChild(_doc.createTextNode('-')); - oD.onclick = _toggleDebug; + oD.appendChild(doc.createTextNode('-')); + oD.onclick = toggleDebug; oD.title = 'Toggle SM2 debug console'; - if (_ua.match(/msie 6/i)) { + if (ua.match(/msie 6/i)) { oD.style.position = 'absolute'; oD.style.cursor = 'hand'; } @@ -4218,16 +4278,16 @@ function SoundManager(smURL, smID) { } } - oDebug = _doc.createElement('div'); - oDebug.id = _s.debugID; - oDebug.style.display = (_s.debugMode?'block':'none'); + oDebug = doc.createElement('div'); + oDebug.id = sm2.debugID; + oDebug.style.display = (sm2.debugMode?'block':'none'); - if (_s.debugMode && !_id(oD.id)) { + if (sm2.debugMode && !id(oD.id)) { try { - oTarget = _getDocument(); + oTarget = getDocument(); oTarget.appendChild(oD); } catch(e2) { - throw new Error(_str('domError')+' \n'+e2.toString()); + throw new Error(str('domError')+' \n'+e2.toString()); } oTarget.appendChild(oDebug); } @@ -4239,31 +4299,25 @@ function SoundManager(smURL, smID) { }; - _idCheck = this.getSoundById; + idCheck = this.getSoundById; // _wDS = function(o, errorLevel) { - return (!o ? '' : _s._wD(_str(o), errorLevel)); + return (!o ? '' : sm2._wD(str(o), errorLevel)); }; - // last-resort debugging option + toggleDebug = function() { - if (_wl.indexOf('sm2-debug=alert') + 1 && _s.debugMode) { - _s._wD = function(sText) {window.alert(sText);}; - } - - _toggleDebug = function() { - - var o = _id(_s.debugID), - oT = _id(_s.debugID + '-toggle'); + var o = id(sm2.debugID), + oT = id(sm2.debugID + '-toggle'); if (!o) { return false; } - if (_debugOpen) { + if (debugOpen) { // minimize oT.innerHTML = '+'; o.style.display = 'none'; @@ -4272,15 +4326,15 @@ function SoundManager(smURL, smID) { o.style.display = 'block'; } - _debugOpen = !_debugOpen; + debugOpen = !debugOpen; }; - _debugTS = function(sEventType, bSuccess, sMessage) { + debugTS = function(sEventType, bSuccess, sMessage) { // troubleshooter debug hooks - if (typeof sm2Debugger !== 'undefined') { + if (window.sm2Debugger !== _undefined) { try { sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); } catch(e) { @@ -4293,78 +4347,78 @@ function SoundManager(smURL, smID) { }; // - _getSWFCSS = function() { + getSWFCSS = function() { var css = []; - if (_s.debugMode) { - css.push(_swfCSS.sm2Debug); + if (sm2.debugMode) { + css.push(swfCSS.sm2Debug); } - if (_s.debugFlash) { - css.push(_swfCSS.flashDebug); + if (sm2.debugFlash) { + css.push(swfCSS.flashDebug); } - if (_s.useHighPerformance) { - css.push(_swfCSS.highPerf); + if (sm2.useHighPerformance) { + css.push(swfCSS.highPerf); } return css.join(' '); }; - _flashBlockHandler = function() { + flashBlockHandler = function() { // *possible* flash block situation. - var name = _str('fbHandler'), - p = _s.getMoviePercent(), - css = _swfCSS, + var name = str('fbHandler'), + p = sm2.getMoviePercent(), + css = swfCSS, error = {type:'FLASHBLOCK'}; - if (_s.html5Only) { + if (sm2.html5Only) { return false; } - if (!_s.ok()) { + if (!sm2.ok()) { - if (_needsFlash) { + if (needsFlash) { // make the movie more visible, so user can fix - _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError); - _s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':'')); + sm2.oMC.className = getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError); + sm2._wD(name + ': ' + str('fbTimeout') + (p ? ' (' + str('fbLoaded') + ')' : '')); } - _s.didFlashBlock = true; + sm2.didFlashBlock = true; // fire onready(), complain lightly - _processOnEvents({type:'ontimeout', ignoreInit:true, error:error}); - _catchError(error); + processOnEvents({type:'ontimeout', ignoreInit:true, error:error}); + catchError(error); } else { // SM2 loaded OK (or recovered) // - if (_s.didFlashBlock) { - _s._wD(name+': Unblocked'); + if (sm2.didFlashBlock) { + sm2._wD(name + ': Unblocked'); } // - if (_s.oMC) { - _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' '); + if (sm2.oMC) { + sm2.oMC.className = [getSWFCSS(), css.swfDefault, css.swfLoaded + (sm2.didFlashBlock?' '+css.swfUnblocked:'')].join(' '); } } }; - _addOnEvent = function(sType, oMethod, oScope) { + addOnEvent = function(sType, oMethod, oScope) { - if (typeof _on_queue[sType] === 'undefined') { - _on_queue[sType] = []; + if (on_queue[sType] === _undefined) { + on_queue[sType] = []; } - _on_queue[sType].push({ + on_queue[sType].push({ 'method': oMethod, 'scope': (oScope || null), 'fired': false @@ -4372,36 +4426,36 @@ function SoundManager(smURL, smID) { }; - _processOnEvents = function(oOptions) { + processOnEvents = function(oOptions) { // if unspecified, assume OK/error if (!oOptions) { oOptions = { - type: (_s.ok() ? 'onready' : 'ontimeout') + type: (sm2.ok() ? 'onready' : 'ontimeout') }; } - if (!_didInit && oOptions && !oOptions.ignoreInit) { + if (!didInit && oOptions && !oOptions.ignoreInit) { // not ready yet. return false; } - if (oOptions.type === 'ontimeout' && (_s.ok() || (_disabled && !oOptions.ignoreInit))) { + if (oOptions.type === 'ontimeout' && (sm2.ok() || (disabled && !oOptions.ignoreInit))) { // invalid case return false; } var status = { - success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled) + success: (oOptions && oOptions.ignoreInit?sm2.ok():!disabled) }, // queue specified by type, or none - srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]), + srcQueue = (oOptions && oOptions.type?on_queue[oOptions.type]||[]:[]), queue = [], i, j, args = [status], - canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok()); + canRetry = (needsFlash && !sm2.ok()); if (oOptions.error) { args[0].error = oOptions.error; @@ -4414,7 +4468,7 @@ function SoundManager(smURL, smID) { } if (queue.length) { - _s._wD(_sm + ': Firing ' + queue.length + ' '+oOptions.type+'() item' + (queue.length === 1?'':'s')); + // sm2._wD(sm + ': Firing ' + queue.length + ' ' + oOptions.type + '() item' + (queue.length === 1 ? '' : 's')); for (i = 0, j = queue.length; i < j; i++) { if (queue[i].scope) { queue[i].method.apply(queue[i].scope, args); @@ -4422,7 +4476,7 @@ function SoundManager(smURL, smID) { queue[i].method.apply(this, args); } if (!canRetry) { - // flashblock case doesn't count here + // useFlashBlock and SWF timeout case doesn't count here. queue[i].fired = true; } } @@ -4432,42 +4486,42 @@ function SoundManager(smURL, smID) { }; - _initUserOnload = function() { + initUserOnload = function() { - _win.setTimeout(function() { + window.setTimeout(function() { - if (_s.useFlashBlock) { - _flashBlockHandler(); + if (sm2.useFlashBlock) { + flashBlockHandler(); } - _processOnEvents(); + processOnEvents(); // call user-defined "onload", scoped to window - if (typeof _s.onload === 'function') { + if (typeof sm2.onload === 'function') { _wDS('onload', 1); - _s.onload.apply(_win); + sm2.onload.apply(window); _wDS('onloadOK', 1); } - if (_s.waitForWindowLoad) { - _event.add(_win, 'load', _initUserOnload); + if (sm2.waitForWindowLoad) { + event.add(window, 'load', initUserOnload); } },1); }; - _detectFlash = function() { + detectFlash = function() { // hat tip: Flash Detect library (BSD, (C) 2007) by Carl "DocYes" S. Yestrau - http://featureblend.com/javascript-flash-detection-library.html / http://featureblend.com/license.txt - if (typeof _hasFlash !== 'undefined') { + if (hasFlash !== _undefined) { // this work has already been done. - return _hasFlash; + return hasFlash; } - var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject; + var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = window.ActiveXObject; if (nP && nP.length) { type = 'application/x-shockwave-flash'; @@ -4475,56 +4529,59 @@ function SoundManager(smURL, smID) { if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) { hasPlugin = true; } - } else if (typeof AX !== 'undefined') { + } else if (AX !== _undefined && !ua.match(/MSAppHost/i)) { + // Windows 8 Store Apps (MSAppHost) are weird (compatibility?) and won't complain here, but will barf if Flash/ActiveX object is appended to the DOM. try { obj = new AX('ShockwaveFlash.ShockwaveFlash'); } catch(e) { // oh well } hasPlugin = (!!obj); + // cleanup, because it is ActiveX after all + obj = null; } - _hasFlash = hasPlugin; + hasFlash = hasPlugin; return hasPlugin; }; - _featureCheck = function() { + featureCheck = function() { var needsFlash, item, result = true, - formats = _s.audioFormats, + formats = sm2.audioFormats, // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (original iPad) + iOS4 works. - isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i))); + isSpecial = (is_iDevice && !!(ua.match(/os (1|2|3_0|3_1)/i))); if (isSpecial) { // has Audio(), but is broken; let it load links directly. - _s.hasHTML5 = false; + sm2.hasHTML5 = false; // ignore flash case, however - _s.html5Only = true; + sm2.html5Only = true; - if (_s.oMC) { - _s.oMC.style.display = 'none'; + if (sm2.oMC) { + sm2.oMC.style.display = 'none'; } result = false; } else { - if (_s.useHTML5Audio) { + if (sm2.useHTML5Audio) { - if (!_s.html5 || !_s.html5.canPlayType) { - _s._wD('SoundManager: No HTML5 Audio() support detected.'); - _s.hasHTML5 = false; + if (!sm2.html5 || !sm2.html5.canPlayType) { + sm2._wD('SoundManager: No HTML5 Audio() support detected.'); + sm2.hasHTML5 = false; } // - if (_isBadSafari) { - _s._wD(_smc+'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - '+(!_hasFlash?' would use flash fallback for MP3/MP4, but none detected.':'will use flash fallback for MP3/MP4, if available'),1); + if (isBadSafari) { + sm2._wD(smc + 'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - ' + (!hasFlash ?' would use flash fallback for MP3/MP4, but none detected.' : 'will use flash fallback for MP3/MP4, if available'), 1); } // @@ -4532,11 +4589,11 @@ function SoundManager(smURL, smID) { } - if (_s.useHTML5Audio && _s.hasHTML5) { + if (sm2.useHTML5Audio && sm2.hasHTML5) { for (item in formats) { if (formats.hasOwnProperty(item)) { - if ((formats[item].required && !_s.html5.canPlayType(formats[item].type)) || (_s.preferFlash && (_s.flash[item] || _s.flash[formats[item].type]))) { + if ((formats[item].required && !sm2.html5.canPlayType(formats[item].type)) || (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type]))) { // flash may be required, or preferred for this format needsFlash = true; } @@ -4546,17 +4603,17 @@ function SoundManager(smURL, smID) { } // sanity check... - if (_s.ignoreFlash) { + if (sm2.ignoreFlash) { needsFlash = false; } - _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash); + sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !needsFlash); - return (!_s.html5Only); + return (!sm2.html5Only); }; - _parseURL = function(url) { + parseURL = function(url) { /** * Internal: Finds and returns the first playable URL (or failing that, the first URL.) @@ -4572,12 +4629,12 @@ function SoundManager(smURL, smID) { if (url[i] instanceof Object) { // MIME check - if (_s.canPlayMIME(url[i].type)) { + if (sm2.canPlayMIME(url[i].type)) { urlResult = i; break; } - } else if (_s.canPlayURL(url[i])) { + } else if (sm2.canPlayURL(url[i])) { // URL string check urlResult = i; break; @@ -4604,7 +4661,7 @@ function SoundManager(smURL, smID) { }; - _startTimer = function(oSound) { + startTimer = function(oSound) { /** * attach a timer to this sound, and start an interval if needed @@ -4614,15 +4671,15 @@ function SoundManager(smURL, smID) { oSound._hasTimer = true; - if (!_mobileHTML5 && _s.html5PollingInterval) { + if (!mobileHTML5 && sm2.html5PollingInterval) { - if (_h5IntervalTimer === null && _h5TimerCount === 0) { + if (h5IntervalTimer === null && h5TimerCount === 0) { - _h5IntervalTimer = _win.setInterval(_timerExecute, _s.html5PollingInterval); + h5IntervalTimer = window.setInterval(timerExecute, sm2.html5PollingInterval); } - _h5TimerCount++; + h5TimerCount++; } @@ -4630,7 +4687,7 @@ function SoundManager(smURL, smID) { }; - _stopTimer = function(oSound) { + stopTimer = function(oSound) { /** * detach a timer @@ -4640,11 +4697,11 @@ function SoundManager(smURL, smID) { oSound._hasTimer = false; - if (!_mobileHTML5 && _s.html5PollingInterval) { + if (!mobileHTML5 && sm2.html5PollingInterval) { // interval will stop itself at next execution. - _h5TimerCount--; + h5TimerCount--; } @@ -4652,7 +4709,7 @@ function SoundManager(smURL, smID) { }; - _timerExecute = function() { + timerExecute = function() { /** * manual polling for HTML5 progress events, ie., whileplaying() (can achieve greater precision than conservative default HTML5 interval) @@ -4660,13 +4717,13 @@ function SoundManager(smURL, smID) { var i; - if (_h5IntervalTimer !== null && !_h5TimerCount) { + if (h5IntervalTimer !== null && !h5TimerCount) { // no active timers, stop polling interval. - _win.clearInterval(_h5IntervalTimer); + window.clearInterval(h5IntervalTimer); - _h5IntervalTimer = null; + h5IntervalTimer = null; return false; @@ -4674,11 +4731,11 @@ function SoundManager(smURL, smID) { // check all HTML5 sounds with timers - for (i = _s.soundIDs.length-1; i >= 0; i--) { + for (i = sm2.soundIDs.length-1; i >= 0; i--) { - if (_s.sounds[_s.soundIDs[i]].isHTML5 && _s.sounds[_s.soundIDs[i]]._hasTimer) { + if (sm2.sounds[sm2.soundIDs[i]].isHTML5 && sm2.sounds[sm2.soundIDs[i]]._hasTimer) { - _s.sounds[_s.soundIDs[i]]._onTimer(); + sm2.sounds[sm2.soundIDs[i]]._onTimer(); } @@ -4686,39 +4743,39 @@ function SoundManager(smURL, smID) { }; - _catchError = function(options) { + catchError = function(options) { - options = (typeof options !== 'undefined' ? options : {}); + options = (options !== _undefined ? options : {}); - if (typeof _s.onerror === 'function') { - _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]); + if (typeof sm2.onerror === 'function') { + sm2.onerror.apply(window, [{type:(options.type !== _undefined ? options.type : null)}]); } - if (typeof options.fatal !== 'undefined' && options.fatal) { - _s.disable(); + if (options.fatal !== _undefined && options.fatal) { + sm2.disable(); } }; - _badSafariFix = function() { + badSafariFix = function() { // special case: "bad" Safari (OS X 10.3 - 10.7) must fall back to flash for MP3/MP4 - if (!_isBadSafari || !_detectFlash()) { + if (!isBadSafari || !detectFlash()) { // doesn't apply return false; } - var aF = _s.audioFormats, i, item; + var aF = sm2.audioFormats, i, item; for (item in aF) { if (aF.hasOwnProperty(item)) { if (item === 'mp3' || item === 'mp4') { - _s._wD(_sm+': Using flash fallback for '+item+' format'); - _s.html5[item] = false; + sm2._wD(sm + ': Using flash fallback for ' + item + ' format'); + sm2.html5[item] = false; // assign result to related formats, too if (aF[item] && aF[item].related) { for (i = aF[item].related.length-1; i >= 0; i--) { - _s.html5[aF[item].related[i]] = false; + sm2.html5[aF[item].related[i]] = false; } } } @@ -4735,12 +4792,10 @@ function SoundManager(smURL, smID) { this._setSandboxType = function(sandboxType) { // - var sb = _s.sandbox; + var sb = sm2.sandbox; sb.type = sandboxType; - sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')]; - - _s._wD('Flash security sandbox type: ' + sb.type); + sb.description = sb.types[(sb.types[sandboxType] !== _undefined?sandboxType:'unknown')]; if (sb.type === 'localWithFile') { @@ -4769,27 +4824,26 @@ function SoundManager(smURL, smID) { // flashDate = approx. timing/delay info for JS/flash bridge // swfVersion: SWF build string - if (_s.swfLoaded) { + if (sm2.swfLoaded) { return false; } - var e, eiTime = new Date().getTime(); + var e; - _s._wD(_smc+'externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':'')); - _debugTS('swf', true); - _debugTS('flashtojs', true); - _s.swfLoaded = true; - _tryInitOnFocus = false; + debugTS('swf', true); + debugTS('flashtojs', true); + sm2.swfLoaded = true; + tryInitOnFocus = false; - if (_isBadSafari) { - _badSafariFix(); + if (isBadSafari) { + badSafariFix(); } // complain if JS + SWF build/version strings don't match, excluding +DEV builds // - if (!swfVersion || swfVersion.replace(/\+dev/i,'') !== _s.versionNumber.replace(/\+dev/i, '')) { + if (!swfVersion || swfVersion.replace(/\+dev/i,'') !== sm2.versionNumber.replace(/\+dev/i, '')) { - e = _sm + ': Fatal: JavaScript file build "' + _s.versionNumber + '" does not match Flash SWF build "' + swfVersion + '" at ' + _s.url + '. Ensure both are up-to-date.'; + e = sm + ': Fatal: JavaScript file build "' + sm2.versionNumber + '" does not match Flash SWF build "' + swfVersion + '" at ' + sm2.url + '. Ensure both are up-to-date.'; // escape flash -> JS stack so this error fires in window. setTimeout(function versionMismatch() { @@ -4803,7 +4857,7 @@ function SoundManager(smURL, smID) { // // slight delay before init - setTimeout(_init, _isIE ? 100 : 1); + setTimeout(init, isIE ? 100 : 1); }; @@ -4812,67 +4866,121 @@ function SoundManager(smURL, smID) { * ------------------------------ */ - _createMovie = function(smID, smURL) { + createMovie = function(smID, smURL) { - if (_didAppend && _appendSuccess) { + if (didAppend && appendSuccess) { // ignore if already succeeded return false; } - function _initMsg() { - _s._wD('-- SoundManager 2 ' + _s.version + (!_s.html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (!_s.html5Only ? (_s.useHighPerformance?', high performance mode, ':', ') + (( _s.flashPollingInterval ? 'custom (' + _s.flashPollingInterval + 'ms)' : 'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') : '') + ' --', 1); + function initMsg() { + + // + + var options = [], title, str = [], delimiter = ' + '; + + title = 'SoundManager ' + sm2.version + (!sm2.html5Only && sm2.useHTML5Audio ? (sm2.hasHTML5 ? ' + HTML5 audio' : ', no HTML5 audio support') : ''); + + if (!sm2.html5Only) { + + if (sm2.preferFlash) { + options.push('preferFlash'); + } + + if (sm2.useHighPerformance) { + options.push('useHighPerformance'); + } + + if (sm2.flashPollingInterval) { + options.push('flashPollingInterval (' + sm2.flashPollingInterval + 'ms)'); + } + + if (sm2.html5PollingInterval) { + options.push('html5PollingInterval (' + sm2.html5PollingInterval + 'ms)'); + } + + if (sm2.wmode) { + options.push('wmode (' + sm2.wmode + ')'); + } + + if (sm2.debugFlash) { + options.push('debugFlash'); + } + + if (sm2.useFlashBlock) { + options.push('flashBlock'); + } + + } else { + + if (sm2.html5PollingInterval) { + options.push('html5PollingInterval (' + sm2.html5PollingInterval + 'ms)'); + } + + } + + if (options.length) { + str = str.concat([options.join(delimiter)]); + } + + sm2._wD(title + (str.length ? delimiter + str.join(', ') : ''), 1); + + showSupport(); + + // + } - if (_s.html5Only) { + if (sm2.html5Only) { // 100% HTML5 mode - _setVersionInfo(); + setVersionInfo(); - _initMsg(); - _s.oMC = _id(_s.movieID); - _init(); + initMsg(); + sm2.oMC = id(sm2.movieID); + init(); // prevent multiple init attempts - _didAppend = true; + didAppend = true; - _appendSuccess = true; + appendSuccess = true; return false; } // flash path - var remoteURL = (smURL || _s.url), - localURL = (_s.altURL || remoteURL), + var remoteURL = (smURL || sm2.url), + localURL = (sm2.altURL || remoteURL), swfTitle = 'JS/Flash audio component (SoundManager 2)', - oTarget = _getDocument(), - extraClass = _getSWFCSS(), + oTarget = getDocument(), + extraClass = getSWFCSS(), isRTL = null, - html = _doc.getElementsByTagName('html')[0], + html = doc.getElementsByTagName('html')[0], oEmbed, oMovie, tmp, movieHTML, oEl, s, x, sClass; isRTL = (html && html.dir && html.dir.match(/rtl/i)); - smID = (typeof smID === 'undefined'?_s.id:smID); + smID = (smID === _undefined?sm2.id:smID); function param(name, value) { return ''; } // safety check for legacy (change to Flash 9 URL) - _setVersionInfo(); - _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL); - smURL = _s.url; + setVersionInfo(); + sm2.url = normalizeMovieURL(overHTTP?remoteURL:localURL); + smURL = sm2.url; - _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode); + sm2.wmode = (!sm2.wmode && sm2.useHighPerformance ? 'transparent' : sm2.wmode); - if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) { + if (sm2.wmode !== null && (ua.match(/msie 8/i) || (!isIE && !sm2.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) { /** * extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here * does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout * wmode breaks IE 8 on Vista + Win7 too in some cases, as of January 2011 (?) */ - _wDS('spcWmode'); - _s.wmode = null; + messages.push(strings.spcWmode); + sm2.wmode = null; } oEmbed = { @@ -4880,44 +4988,44 @@ function SoundManager(smURL, smID) { 'id': smID, 'src': smURL, 'quality': 'high', - 'allowScriptAccess': _s.allowScriptAccess, - 'bgcolor': _s.bgColor, - 'pluginspage': _http+'www.macromedia.com/go/getflashplayer', + 'allowScriptAccess': sm2.allowScriptAccess, + 'bgcolor': sm2.bgColor, + 'pluginspage': http+'www.macromedia.com/go/getflashplayer', 'title': swfTitle, 'type': 'application/x-shockwave-flash', - 'wmode': _s.wmode, + 'wmode': sm2.wmode, // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html 'hasPriority': 'true' }; - if (_s.debugFlash) { + if (sm2.debugFlash) { oEmbed.FlashVars = 'debug=1'; } - if (!_s.wmode) { + if (!sm2.wmode) { // don't write empty attribute delete oEmbed.wmode; } - if (_isIE) { + if (isIE) { // IE is "special". - oMovie = _doc.createElement('div'); + oMovie = doc.createElement('div'); movieHTML = [ - '', + '', param('movie', smURL), - param('AllowScriptAccess', _s.allowScriptAccess), + param('AllowScriptAccess', sm2.allowScriptAccess), param('quality', oEmbed.quality), - (_s.wmode? param('wmode', _s.wmode): ''), - param('bgcolor', _s.bgColor), + (sm2.wmode? param('wmode', sm2.wmode): ''), + param('bgcolor', sm2.bgColor), param('hasPriority', 'true'), - (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''), + (sm2.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''), '' ].join(''); } else { - oMovie = _doc.createElement('embed'); + oMovie = doc.createElement('embed'); for (tmp in oEmbed) { if (oEmbed.hasOwnProperty(tmp)) { oMovie.setAttribute(tmp, oEmbed[tmp]); @@ -4926,23 +5034,23 @@ function SoundManager(smURL, smID) { } - _initDebug(); - extraClass = _getSWFCSS(); - oTarget = _getDocument(); + initDebug(); + extraClass = getSWFCSS(); + oTarget = getDocument(); if (oTarget) { - _s.oMC = (_id(_s.movieID) || _doc.createElement('div')); + sm2.oMC = (id(sm2.movieID) || doc.createElement('div')); - if (!_s.oMC.id) { + if (!sm2.oMC.id) { - _s.oMC.id = _s.movieID; - _s.oMC.className = _swfCSS.swfDefault + ' ' + extraClass; + sm2.oMC.id = sm2.movieID; + sm2.oMC.className = swfCSS.swfDefault + ' ' + extraClass; s = null; oEl = null; - if (!_s.useFlashBlock) { - if (_s.useHighPerformance) { + if (!sm2.useFlashBlock) { + if (sm2.useHighPerformance) { // on-screen at all times s = { 'position': 'fixed', @@ -4968,72 +5076,72 @@ function SoundManager(smURL, smID) { } } - if (_isWebkit) { + if (isWebkit) { // soundcloud-reported render/crash fix, safari 5 - _s.oMC.style.zIndex = 10000; + sm2.oMC.style.zIndex = 10000; } - if (!_s.debugFlash) { + if (!sm2.debugFlash) { for (x in s) { if (s.hasOwnProperty(x)) { - _s.oMC.style[x] = s[x]; + sm2.oMC.style[x] = s[x]; } } } try { - if (!_isIE) { - _s.oMC.appendChild(oMovie); + if (!isIE) { + sm2.oMC.appendChild(oMovie); } - oTarget.appendChild(_s.oMC); - if (_isIE) { - oEl = _s.oMC.appendChild(_doc.createElement('div')); - oEl.className = _swfCSS.swfBox; + oTarget.appendChild(sm2.oMC); + if (isIE) { + oEl = sm2.oMC.appendChild(doc.createElement('div')); + oEl.className = swfCSS.swfBox; oEl.innerHTML = movieHTML; } - _appendSuccess = true; + appendSuccess = true; } catch(e) { - throw new Error(_str('domError')+' \n'+e.toString()); + throw new Error(str('domError')+' \n'+e.toString()); } } else { // SM2 container is already in the document (eg. flashblock use case) - sClass = _s.oMC.className; - _s.oMC.className = (sClass?sClass+' ':_swfCSS.swfDefault) + (extraClass?' '+extraClass:''); - _s.oMC.appendChild(oMovie); - if (_isIE) { - oEl = _s.oMC.appendChild(_doc.createElement('div')); - oEl.className = _swfCSS.swfBox; + sClass = sm2.oMC.className; + sm2.oMC.className = (sClass?sClass+' ':swfCSS.swfDefault) + (extraClass?' '+extraClass:''); + sm2.oMC.appendChild(oMovie); + if (isIE) { + oEl = sm2.oMC.appendChild(doc.createElement('div')); + oEl.className = swfCSS.swfBox; oEl.innerHTML = movieHTML; } - _appendSuccess = true; + appendSuccess = true; } } - _didAppend = true; - _initMsg(); - _s._wD(_smc+'createMovie(): Trying to load ' + smURL + (!_overHTTP && _s.altURL?' (alternate URL)':''), 1); + didAppend = true; + initMsg(); + // sm2._wD(sm + ': Trying to load ' + smURL + (!overHTTP && sm2.altURL ? ' (alternate URL)' : ''), 1); return true; }; - _initMovie = function() { + initMovie = function() { - if (_s.html5Only) { - _createMovie(); + if (sm2.html5Only) { + createMovie(); return false; } // attempt to get, or create, movie (may already exist) - if (_flash) { + if (flash) { return false; } - if (!_s.url) { + if (!sm2.url) { /** * Something isn't right - we've reached init, but the soundManager url property has not been set. @@ -5047,71 +5155,68 @@ function SoundManager(smURL, smID) { } // inline markup case - _flash = _s.getMovie(_s.id); + flash = sm2.getMovie(sm2.id); - if (!_flash) { - if (!_oRemoved) { + if (!flash) { + if (!oRemoved) { // try to create - _createMovie(_s.id, _s.url); + createMovie(sm2.id, sm2.url); } else { // try to re-append removed movie after reboot() - if (!_isIE) { - _s.oMC.appendChild(_oRemoved); + if (!isIE) { + sm2.oMC.appendChild(oRemoved); } else { - _s.oMC.innerHTML = _oRemovedHTML; + sm2.oMC.innerHTML = oRemovedHTML; } - _oRemoved = null; - _didAppend = true; + oRemoved = null; + didAppend = true; } - _flash = _s.getMovie(_s.id); + flash = sm2.getMovie(sm2.id); + } + + if (typeof sm2.oninitmovie === 'function') { + setTimeout(sm2.oninitmovie, 1); } // - if (_flash) { - _wDS('waitEI'); - } + flushMessages(); // - if (typeof _s.oninitmovie === 'function') { - setTimeout(_s.oninitmovie, 1); - } - return true; }; - _delayWaitForEI = function() { + delayWaitForEI = function() { - setTimeout(_waitForEI, 1000); + setTimeout(waitForEI, 1000); }; - _waitForEI = function() { + waitForEI = function() { var p, loadIncomplete = false; - if (!_s.url) { + if (!sm2.url) { // No SWF url to load (noURL case) - exit for now. Will be retried when url is set. return false; } - if (_waitingForEI) { + if (waitingForEI) { return false; } - _waitingForEI = true; - _event.remove(_win, 'load', _delayWaitForEI); + waitingForEI = true; + event.remove(window, 'load', delayWaitForEI); - if (_tryInitOnFocus && !_isFocused) { + if (tryInitOnFocus && !isFocused) { // Safari won't load flash in background tabs, only when focused. _wDS('waitFocus'); return false; } - if (!_didInit) { - p = _s.getMoviePercent(); - _s._wD(_str('waitImpatient', (p > 0 ? ' (SWF ' + p + '% loaded)' : ''))); + if (!didInit) { + p = sm2.getMoviePercent(); if (p > 0 && p < 100) { loadIncomplete = true; } @@ -5119,158 +5224,176 @@ function SoundManager(smURL, smID) { setTimeout(function() { - p = _s.getMoviePercent(); + p = sm2.getMoviePercent(); if (loadIncomplete) { // special case: if movie *partially* loaded, retry until it's 100% before assuming failure. - _waitingForEI = false; - _s._wD(_str('waitSWF')); - _win.setTimeout(_delayWaitForEI, 1); + waitingForEI = false; + sm2._wD(str('waitSWF')); + window.setTimeout(delayWaitForEI, 1); return false; } // - if (!_didInit) { - _s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2); - if (!_overHTTP && p) { + if (!didInit) { + sm2._wD(sm + ': No Flash response within expected time. Likely causes: ' + (p === 0 ? 'SWF load failed, ':'') + 'Flash blocked or JS-Flash security error.' + (sm2.debugFlash?' ' + str('checkSWF'):''), 2); + if (!overHTTP && p) { _wDS('localFail', 2); - if (!_s.debugFlash) { + if (!sm2.debugFlash) { _wDS('tryDebug', 2); } } if (p === 0) { // if 0 (not null), probably a 404. - _s._wD(_str('swf404', _s.url)); + sm2._wD(str('swf404', sm2.url), 1); } - _debugTS('flashtojs', false, ': Timed out' + _overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); + debugTS('flashtojs', false, ': Timed out' + overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); } // // give up / time-out, depending - if (!_didInit && _okToDisable) { + if (!didInit && okToDisable) { if (p === null) { // SWF failed. Maybe blocked. - if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { - if (_s.useFlashBlock) { - _flashBlockHandler(); + if (sm2.useFlashBlock || sm2.flashLoadTimeout === 0) { + if (sm2.useFlashBlock) { + flashBlockHandler(); } _wDS('waitForever'); } else { - // old SM2 behaviour, simply fail - _failSafely(true); + // no custom flash block handling, but SWF has timed out. Will recover if user unblocks / allows SWF load. + _wDS('waitForever'); + // fire any regular registered ontimeout() listeners. + processOnEvents({type:'ontimeout', ignoreInit: true}); } } else { // flash loaded? Shouldn't be a blocking issue, then. - if (_s.flashLoadTimeout === 0) { + if (sm2.flashLoadTimeout === 0) { _wDS('waitForever'); } else { - _failSafely(true); + failSafely(true); } } } - }, _s.flashLoadTimeout); + }, sm2.flashLoadTimeout); }; - _handleFocus = function() { + handleFocus = function() { function cleanup() { - _event.remove(_win, 'focus', _handleFocus); + event.remove(window, 'focus', handleFocus); } - if (_isFocused || !_tryInitOnFocus) { + if (isFocused || !tryInitOnFocus) { // already focused, or not special Safari background tab case cleanup(); return true; } - _okToDisable = true; - _isFocused = true; + okToDisable = true; + isFocused = true; _wDS('gotFocus'); // allow init to restart - _waitingForEI = false; + waitingForEI = false; // kick off ExternalInterface timeout, now that the SWF has started - _delayWaitForEI(); + delayWaitForEI(); cleanup(); return true; }; - _showSupport = function() { + flushMessages = function() { // - var item, tests = []; - - if (_s.useHTML5Audio && _s.hasHTML5) { - for (item in _s.audioFormats) { - if (_s.audioFormats.hasOwnProperty(item)) { - tests.push(item + ': ' + _s.html5[item] + (!_s.html5[item] && _hasFlash && _s.flash[item] ? ' (using flash)' : (_s.preferFlash && _s.flash[item] && _hasFlash ? ' (preferring flash)': (!_s.html5[item] ? ' (' + (_s.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : '')))); - } - } - _s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1); + // SM2 pre-init debug messages + if (messages.length) { + sm2._wD('SoundManager 2: ' + messages.join(' '), 1); + messages = []; } // }; - _initComplete = function(bNoDisable) { + showSupport = function() { - if (_didInit) { + // + + flushMessages(); + + var item, tests = []; + + if (sm2.useHTML5Audio && sm2.hasHTML5) { + for (item in sm2.audioFormats) { + if (sm2.audioFormats.hasOwnProperty(item)) { + tests.push(item + ' = ' + sm2.html5[item] + (!sm2.html5[item] && hasFlash && sm2.flash[item] ? ' (using flash)' : (sm2.preferFlash && sm2.flash[item] && hasFlash ? ' (preferring flash)': (!sm2.html5[item] ? ' (' + (sm2.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : '')))); + } + } + sm2._wD('SoundManager 2 HTML5 support: ' + tests.join(', '), 1); + } + + // + + }; + + initComplete = function(bNoDisable) { + + if (didInit) { return false; } - if (_s.html5Only) { + if (sm2.html5Only) { // all good. - _s._wD('-- SoundManager 2: loaded --'); - _didInit = true; - _initUserOnload(); - _debugTS('onload', true); + _wDS('sm2Loaded'); + didInit = true; + initUserOnload(); + debugTS('onload', true); return true; } - var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()), + var wasTimeout = (sm2.useFlashBlock && sm2.flashLoadTimeout && !sm2.getMoviePercent()), result = true, error; if (!wasTimeout) { - _didInit = true; - if (_disabled) { - error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')}; + didInit = true; + if (disabled) { + error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')}; } } - _s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'Flash security/load error':'OK') + ') --', 1); + sm2._wD('SoundManager 2 ' + (disabled ? 'failed to load' : 'loaded') + ' (' + (disabled ? 'Flash security/load error' : 'OK') + ')', disabled ? 2: 1); - if (_disabled || bNoDisable) { - if (_s.useFlashBlock && _s.oMC) { - _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_swfCSS.swfTimedout:_swfCSS.swfError); + if (disabled || bNoDisable) { + if (sm2.useFlashBlock && sm2.oMC) { + sm2.oMC.className = getSWFCSS() + ' ' + (sm2.getMoviePercent() === null?swfCSS.swfTimedout:swfCSS.swfError); } - _processOnEvents({type:'ontimeout', error:error, ignoreInit: true}); - _debugTS('onload', false); - _catchError(error); + processOnEvents({type:'ontimeout', error:error, ignoreInit: true}); + debugTS('onload', false); + catchError(error); result = false; } else { - _debugTS('onload', true); + debugTS('onload', true); } - if (!_disabled) { - if (_s.waitForWindowLoad && !_windowLoaded) { + if (!disabled) { + if (sm2.waitForWindowLoad && !windowLoaded) { _wDS('waitOnload'); - _event.add(_win, 'load', _initUserOnload); + event.add(window, 'load', initUserOnload); } else { // - if (_s.waitForWindowLoad && _windowLoaded) { + if (sm2.waitForWindowLoad && windowLoaded) { _wDS('docLoaded'); } // - _initUserOnload(); + initUserOnload(); } } @@ -5283,10 +5406,10 @@ function SoundManager(smURL, smID) { * this maintains backward compatibility, and allows properties to be defined separately for use by soundManager.setup(). */ - _setProperties = function() { + setProperties = function() { var i, - o = _s.setupOptions; + o = sm2.setupOptions; for (i in o) { @@ -5294,14 +5417,14 @@ function SoundManager(smURL, smID) { // assign local property if not already defined - if (typeof _s[i] === 'undefined') { + if (sm2[i] === _undefined) { - _s[i] = o[i]; + sm2[i] = o[i]; - } else if (_s[i] !== o[i]) { + } else if (sm2[i] !== o[i]) { // legacy support: write manually-assigned property (eg., soundManager.url) back to setupOptions to keep things in sync - _s.setupOptions[i] = _s[i]; + sm2.setupOptions[i] = sm2[i]; } @@ -5312,93 +5435,89 @@ function SoundManager(smURL, smID) { }; - _init = function() { - - _wDS('init'); + init = function() { // called after onload() - if (_didInit) { + if (didInit) { _wDS('didInit'); return false; } - function _cleanup() { - _event.remove(_win, 'load', _s.beginDelayedInit); + function cleanup() { + event.remove(window, 'load', sm2.beginDelayedInit); } - if (_s.html5Only) { - if (!_didInit) { + if (sm2.html5Only) { + if (!didInit) { // we don't need no steenking flash! - _cleanup(); - _s.enabled = true; - _initComplete(); + cleanup(); + sm2.enabled = true; + initComplete(); } return true; } // flash path - _initMovie(); + initMovie(); try { - _wDS('flashJS'); - // attempt to talk to Flash - _flash._externalInterfaceTest(false); + flash._externalInterfaceTest(false); // apply user-specified polling interval, OR, if "high performance" set, faster vs. default polling // (determines frequency of whileloading/whileplaying callbacks, effectively driving UI framerates) - _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50))); + setPolling(true, (sm2.flashPollingInterval || (sm2.useHighPerformance ? 10 : 50))); - if (!_s.debugMode) { + if (!sm2.debugMode) { // stop the SWF from making debug output calls to JS - _flash._disableDebug(); + flash._disableDebug(); } - _s.enabled = true; - _debugTS('jstoflash', true); + sm2.enabled = true; + debugTS('jstoflash', true); - if (!_s.html5Only) { + if (!sm2.html5Only) { // prevent browser from showing cached page state (or rather, restoring "suspended" page state) via back button, because flash may be dead // http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ - _event.add(_win, 'unload', _doNothing); + event.add(window, 'unload', doNothing); } } catch(e) { - _s._wD('js/flash exception: ' + e.toString()); - _debugTS('jstoflash', false); - _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true}); + sm2._wD('js/flash exception: ' + e.toString()); + debugTS('jstoflash', false); + catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true}); // don't disable, for reboot() - _failSafely(true); - _initComplete(); + failSafely(true); + initComplete(); return false; } - _initComplete(); + initComplete(); // disconnect events - _cleanup(); + cleanup(); return true; }; - _domContentLoaded = function() { + domContentLoaded = function() { - if (_didDCLoaded) { + if (didDCLoaded) { return false; } - _didDCLoaded = true; + didDCLoaded = true; // assign top-level soundManager properties eg. soundManager.url - _setProperties(); + setProperties(); - _initDebug(); + initDebug(); /** * Temporary feature: allow force of HTML5 via URL params: sm2-usehtml5audio=0 or 1 @@ -5411,15 +5530,15 @@ function SoundManager(smURL, smID) { a2 = 'sm2-preferflash=', b = null, b2 = null, - hasCon = (typeof console !== 'undefined' && typeof console.log === 'function'), - l = _wl.toLowerCase(); + hasCon = (window.console !== _undefined && typeof console.log === 'function'), + l = wl.toLowerCase(); if (l.indexOf(a) !== -1) { b = (l.charAt(l.indexOf(a)+a.length) === '1'); if (hasCon) { console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter'); } - _s.setup({ + sm2.setup({ 'useHTML5Audio': b }); } @@ -5429,7 +5548,7 @@ function SoundManager(smURL, smID) { if (hasCon) { console.log((b2?'Enabling ':'Disabling ')+'preferFlash via URL parameter'); } - _s.setup({ + sm2.setup({ 'preferFlash': b2 }); } @@ -5437,9 +5556,9 @@ function SoundManager(smURL, smID) { }()); // - if (!_hasFlash && _s.hasHTML5) { - _s._wD('SoundManager: No Flash detected'+(!_s.useHTML5Audio?', enabling HTML5.':'. Trying HTML5-only mode.')); - _s.setup({ + if (!hasFlash && sm2.hasHTML5) { + sm2._wD('SoundManager: No Flash detected' + (!sm2.useHTML5Audio ? ', enabling HTML5.' : '. Trying HTML5-only mode.'), 1); + sm2.setup({ 'useHTML5Audio': true, // make sure we aren't preferring flash, either // TODO: preferFlash should not matter if flash is not installed. Currently, stuff breaks without the below tweak. @@ -5447,67 +5566,107 @@ function SoundManager(smURL, smID) { }); } - _testHTML5(); - _s.html5.usingFlash = _featureCheck(); - _needsFlash = _s.html5.usingFlash; - _showSupport(); + testHTML5(); + sm2.html5.usingFlash = featureCheck(); + needsFlash = sm2.html5.usingFlash; - if (!_hasFlash && _needsFlash) { - _wDS('needFlash'); + if (!hasFlash && needsFlash) { + messages.push(strings.needFlash); // TODO: Fatal here vs. timeout approach, etc. // hack: fail sooner. - _s.setup({ + sm2.setup({ 'flashLoadTimeout': 1 }); } - if (_doc.removeEventListener) { - _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false); + if (doc.removeEventListener) { + doc.removeEventListener('DOMContentLoaded', domContentLoaded, false); } - _initMovie(); + initMovie(); + return true; }; - _domContentLoadedIE = function() { + domContentLoadedIE = function() { - if (_doc.readyState === 'complete') { - _domContentLoaded(); - _doc.detachEvent('onreadystatechange', _domContentLoadedIE); + if (doc.readyState === 'complete') { + domContentLoaded(); + doc.detachEvent('onreadystatechange', domContentLoadedIE); } return true; }; - _winOnLoad = function() { - // catch edge case of _initComplete() firing after window.load() - _windowLoaded = true; - _event.remove(_win, 'load', _winOnLoad); + winOnLoad = function() { + + // catch edge case of initComplete() firing after window.load() + windowLoaded = true; + event.remove(window, 'load', winOnLoad); + }; + /** + * miscellaneous run-time, pre-init stuff + */ + + preInit = function() { + + if (mobileHTML5) { + + // prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point. + + // + if (!sm2.setupOptions.useHTML5Audio || sm2.setupOptions.preferFlash) { + // notify that defaults are being changed. + messages.push(strings.mobileUA); + } + // + + sm2.setupOptions.useHTML5Audio = true; + sm2.setupOptions.preferFlash = false; + + if (is_iDevice || (isAndroid && !ua.match(/android\s2\.3/i))) { + // iOS and Android devices tend to work better with a single audio instance, specifically for chained playback of sounds in sequence. + // common use case: exiting sound onfinish() -> createSound() -> play() + // + messages.push(strings.globalHTML5); + // + if (is_iDevice) { + sm2.ignoreFlash = true; + } + useGlobalHTML5Audio = true; + } + + } + + }; + + preInit(); + // sniff up-front - _detectFlash(); + detectFlash(); // focus and window load, init (primarily flash-driven) - _event.add(_win, 'focus', _handleFocus); - _event.add(_win, 'load', _delayWaitForEI); - _event.add(_win, 'load', _winOnLoad); + event.add(window, 'focus', handleFocus); + event.add(window, 'load', delayWaitForEI); + event.add(window, 'load', winOnLoad); - if (_doc.addEventListener) { + if (doc.addEventListener) { - _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false); + doc.addEventListener('DOMContentLoaded', domContentLoaded, false); - } else if (_doc.attachEvent) { + } else if (doc.attachEvent) { - _doc.attachEvent('onreadystatechange', _domContentLoadedIE); + doc.attachEvent('onreadystatechange', domContentLoadedIE); } else { // no add/attachevent support - safe to assume no JS -> Flash either - _debugTS('onload', false); - _catchError({type:'NO_DOM2_EVENTS', fatal:true}); + debugTS('onload', false); + catchError({type:'NO_DOM2_EVENTS', fatal:true}); } @@ -5515,7 +5674,7 @@ function SoundManager(smURL, smID) { // SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading -if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { +if (window.SM2_DEFER === undefined || !SM2_DEFER) { soundManager = new SoundManager(); } diff --git a/static/js/libs/socket.io.js b/static/js/libs/socket.io.js new file mode 100644 index 0000000..f81fa5f --- /dev/null +++ b/static/js/libs/socket.io.js @@ -0,0 +1,3818 @@ +/*! Socket.IO.js build:0.9.6, development. Copyright(c) 2011 LearnBoost MIT Licensed */ + +var io = ('undefined' === typeof module ? {} : module.exports); +(function() { + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, global) { + + /** + * IO namespace. + * + * @namespace + */ + + var io = exports; + + /** + * Socket.IO version + * + * @api public + */ + + io.version = '0.9.6'; + + /** + * Protocol implemented. + * + * @api public + */ + + io.protocol = 1; + + /** + * Available transports, these will be populated with the available transports + * + * @api public + */ + + io.transports = []; + + /** + * Keep track of jsonp callbacks. + * + * @api private + */ + + io.j = []; + + /** + * Keep track of our io.Sockets + * + * @api private + */ + io.sockets = {}; + + + /** + * Manages connections to hosts. + * + * @param {String} uri + * @Param {Boolean} force creation of new socket (defaults to false) + * @api public + */ + + io.connect = function (host, details) { + var uri = io.util.parseUri(host) + , uuri + , socket; + + if (global && global.location) { + uri.protocol = uri.protocol || global.location.protocol.slice(0, -1); + uri.host = uri.host || (global.document + ? global.document.domain : global.location.hostname); + uri.port = uri.port || global.location.port; + } + + uuri = io.util.uniqueUri(uri); + + var options = { + host: uri.host + , secure: 'https' == uri.protocol + , port: uri.port || ('https' == uri.protocol ? 443 : 80) + , query: uri.query || '' + }; + + io.util.merge(options, details); + + if (options['force new connection'] || !io.sockets[uuri]) { + socket = new io.Socket(options); + } + + if (!options['force new connection'] && socket) { + io.sockets[uuri] = socket; + } + + socket = socket || io.sockets[uuri]; + + // if path is different from '' or / + return socket.of(uri.path.length > 1 ? uri.path : ''); + }; + +})('object' === typeof module ? module.exports : (this.io = {}), this); +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, global) { + + /** + * Utilities namespace. + * + * @namespace + */ + + var util = exports.util = {}; + + /** + * Parses an URI + * + * @author Steven Levithan (MIT license) + * @api public + */ + + var re = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; + + var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', + 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', + 'anchor']; + + util.parseUri = function (str) { + var m = re.exec(str || '') + , uri = {} + , i = 14; + + while (i--) { + uri[parts[i]] = m[i] || ''; + } + + return uri; + }; + + /** + * Produces a unique url that identifies a Socket.IO connection. + * + * @param {Object} uri + * @api public + */ + + util.uniqueUri = function (uri) { + var protocol = uri.protocol + , host = uri.host + , port = uri.port; + + if ('document' in global) { + host = host || document.domain; + port = port || (protocol == 'https' + && document.location.protocol !== 'https:' ? 443 : document.location.port); + } else { + host = host || 'localhost'; + + if (!port && protocol == 'https') { + port = 443; + } + } + + return (protocol || 'http') + '://' + host + ':' + (port || 80); + }; + + /** + * Mergest 2 query strings in to once unique query string + * + * @param {String} base + * @param {String} addition + * @api public + */ + + util.query = function (base, addition) { + var query = util.chunkQuery(base || '') + , components = []; + + util.merge(query, util.chunkQuery(addition || '')); + for (var part in query) { + if (query.hasOwnProperty(part)) { + components.push(part + '=' + query[part]); + } + } + + return components.length ? '?' + components.join('&') : ''; + }; + + /** + * Transforms a querystring in to an object + * + * @param {String} qs + * @api public + */ + + util.chunkQuery = function (qs) { + var query = {} + , params = qs.split('&') + , i = 0 + , l = params.length + , kv; + + for (; i < l; ++i) { + kv = params[i].split('='); + if (kv[0]) { + query[kv[0]] = kv[1]; + } + } + + return query; + }; + + /** + * Executes the given function when the page is loaded. + * + * io.util.load(function () { console.log('page loaded'); }); + * + * @param {Function} fn + * @api public + */ + + var pageLoaded = false; + + util.load = function (fn) { + if ('document' in global && document.readyState === 'complete' || pageLoaded) { + return fn(); + } + + util.on(global, 'load', fn, false); + }; + + /** + * Adds an event. + * + * @api private + */ + + util.on = function (element, event, fn, capture) { + if (element.attachEvent) { + element.attachEvent('on' + event, fn); + } else if (element.addEventListener) { + element.addEventListener(event, fn, capture); + } + }; + + /** + * Generates the correct `XMLHttpRequest` for regular and cross domain requests. + * + * @param {Boolean} [xdomain] Create a request that can be used cross domain. + * @returns {XMLHttpRequest|false} If we can create a XMLHttpRequest. + * @api private + */ + + util.request = function (xdomain) { + + if (xdomain && 'undefined' != typeof XDomainRequest) { + return new XDomainRequest(); + } + + if ('undefined' != typeof XMLHttpRequest && (!xdomain || util.ua.hasCORS)) { + return new XMLHttpRequest(); + } + + if (!xdomain) { + try { + return new window[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP'); + } catch(e) { } + } + + return null; + }; + + /** + * XHR based transport constructor. + * + * @constructor + * @api public + */ + + /** + * Change the internal pageLoaded value. + */ + + if ('undefined' != typeof window) { + util.load(function () { + pageLoaded = true; + }); + } + + /** + * Defers a function to ensure a spinner is not displayed by the browser + * + * @param {Function} fn + * @api public + */ + + util.defer = function (fn) { + if (!util.ua.webkit || 'undefined' != typeof importScripts) { + return fn(); + } + + util.load(function () { + setTimeout(fn, 100); + }); + }; + + /** + * Merges two objects. + * + * @api public + */ + + util.merge = function merge (target, additional, deep, lastseen) { + var seen = lastseen || [] + , depth = typeof deep == 'undefined' ? 2 : deep + , prop; + + for (prop in additional) { + if (additional.hasOwnProperty(prop) && util.indexOf(seen, prop) < 0) { + if (typeof target[prop] !== 'object' || !depth) { + target[prop] = additional[prop]; + seen.push(additional[prop]); + } else { + util.merge(target[prop], additional[prop], depth - 1, seen); + } + } + } + + return target; + }; + + /** + * Merges prototypes from objects + * + * @api public + */ + + util.mixin = function (ctor, ctor2) { + util.merge(ctor.prototype, ctor2.prototype); + }; + + /** + * Shortcut for prototypical and static inheritance. + * + * @api private + */ + + util.inherit = function (ctor, ctor2) { + function f() {}; + f.prototype = ctor2.prototype; + ctor.prototype = new f; + }; + + /** + * Checks if the given object is an Array. + * + * io.util.isArray([]); // true + * io.util.isArray({}); // false + * + * @param Object obj + * @api public + */ + + util.isArray = Array.isArray || function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; + + /** + * Intersects values of two arrays into a third + * + * @api public + */ + + util.intersect = function (arr, arr2) { + var ret = [] + , longest = arr.length > arr2.length ? arr : arr2 + , shortest = arr.length > arr2.length ? arr2 : arr; + + for (var i = 0, l = shortest.length; i < l; i++) { + if (~util.indexOf(longest, shortest[i])) + ret.push(shortest[i]); + } + + return ret; + } + + /** + * Array indexOf compatibility. + * + * @see bit.ly/a5Dxa2 + * @api public + */ + + util.indexOf = function (arr, o, i) { + + for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0; + i < j && arr[i] !== o; i++) {} + + return j <= i ? -1 : i; + }; + + /** + * Converts enumerables to array. + * + * @api public + */ + + util.toArray = function (enu) { + var arr = []; + + for (var i = 0, l = enu.length; i < l; i++) + arr.push(enu[i]); + + return arr; + }; + + /** + * UA / engines detection namespace. + * + * @namespace + */ + + util.ua = {}; + + /** + * Whether the UA supports CORS for XHR. + * + * @api public + */ + + util.ua.hasCORS = 'undefined' != typeof XMLHttpRequest && (function () { + try { + var a = new XMLHttpRequest(); + } catch (e) { + return false; + } + + return a.withCredentials != undefined; + })(); + + /** + * Detect webkit. + * + * @api public + */ + + util.ua.webkit = 'undefined' != typeof navigator + && /webkit/i.test(navigator.userAgent); + + /** + * Detect iPad/iPhone/iPod. + * + * @api public + */ + + util.ua.iDevice = 'undefined' != typeof navigator + && /iPad|iPhone|iPod/i.test(navigator.userAgent); + +})('undefined' != typeof io ? io : module.exports, this); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io) { + + /** + * Expose constructor. + */ + + exports.EventEmitter = EventEmitter; + + /** + * Event emitter constructor. + * + * @api public. + */ + + function EventEmitter () {}; + + /** + * Adds a listener + * + * @api public + */ + + EventEmitter.prototype.on = function (name, fn) { + if (!this.$events) { + this.$events = {}; + } + + if (!this.$events[name]) { + this.$events[name] = fn; + } else if (io.util.isArray(this.$events[name])) { + this.$events[name].push(fn); + } else { + this.$events[name] = [this.$events[name], fn]; + } + + return this; + }; + + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + /** + * Adds a volatile listener. + * + * @api public + */ + + EventEmitter.prototype.once = function (name, fn) { + var self = this; + + function on () { + self.removeListener(name, on); + fn.apply(this, arguments); + }; + + on.listener = fn; + this.on(name, on); + + return this; + }; + + /** + * Removes a listener. + * + * @api public + */ + + EventEmitter.prototype.removeListener = function (name, fn) { + if (this.$events && this.$events[name]) { + var list = this.$events[name]; + + if (io.util.isArray(list)) { + var pos = -1; + + for (var i = 0, l = list.length; i < l; i++) { + if (list[i] === fn || (list[i].listener && list[i].listener === fn)) { + pos = i; + break; + } + } + + if (pos < 0) { + return this; + } + + list.splice(pos, 1); + + if (!list.length) { + delete this.$events[name]; + } + } else if (list === fn || (list.listener && list.listener === fn)) { + delete this.$events[name]; + } + } + + return this; + }; + + /** + * Removes all listeners for an event. + * + * @api public + */ + + EventEmitter.prototype.removeAllListeners = function (name) { + // TODO: enable this when node 0.5 is stable + //if (name === undefined) { + //this.$events = {}; + //return this; + //} + + if (this.$events && this.$events[name]) { + this.$events[name] = null; + } + + return this; + }; + + /** + * Gets all listeners for a certain event. + * + * @api publci + */ + + EventEmitter.prototype.listeners = function (name) { + if (!this.$events) { + this.$events = {}; + } + + if (!this.$events[name]) { + this.$events[name] = []; + } + + if (!io.util.isArray(this.$events[name])) { + this.$events[name] = [this.$events[name]]; + } + + return this.$events[name]; + }; + + /** + * Emits an event. + * + * @api public + */ + + EventEmitter.prototype.emit = function (name) { + if (!this.$events) { + return false; + } + + var handler = this.$events[name]; + + if (!handler) { + return false; + } + + var args = Array.prototype.slice.call(arguments, 1); + + if ('function' == typeof handler) { + handler.apply(this, args); + } else if (io.util.isArray(handler)) { + var listeners = handler.slice(); + + for (var i = 0, l = listeners.length; i < l; i++) { + listeners[i].apply(this, args); + } + } else { + return false; + } + + return true; + }; + +})( + 'undefined' != typeof io ? io : module.exports + , 'undefined' != typeof io ? io : module.parent.exports +); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +/** + * Based on JSON2 (http://www.JSON.org/js.html). + */ + +(function (exports, nativeJSON) { + "use strict"; + + // use native JSON if it's available + if (nativeJSON && nativeJSON.parse){ + return exports.JSON = { + parse: nativeJSON.parse + , stringify: nativeJSON.stringify + } + } + + var JSON = exports.JSON = {}; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + function date(d, key) { + return isFinite(d.valueOf()) ? + d.getUTCFullYear() + '-' + + f(d.getUTCMonth() + 1) + '-' + + f(d.getUTCDate()) + 'T' + + f(d.getUTCHours()) + ':' + + f(d.getUTCMinutes()) + ':' + + f(d.getUTCSeconds()) + 'Z' : null; + }; + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value instanceof Date) { + value = date(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : gap ? + '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : gap ? + '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : + '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + +// If the JSON object does not yet have a parse method, give it one. + + JSON.parse = function (text, reviver) { + // The parse method takes a text and an optional reviver function, and returns + // a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + + // The walk method is used to recursively walk the resulting structure so + // that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + + // Parsing happens in four stages. In the first stage, we replace certain + // Unicode characters with escape sequences. JavaScript handles many characters + // incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + + // In the second stage, we run the text against regular expressions that look + // for non-JSON patterns. We are especially concerned with '()' and 'new' + // because they can cause invocation, and '=' because it can cause mutation. + // But just to be safe, we want to reject all unexpected forms. + + // We split the second stage into 4 regexp operations in order to work around + // crippling inefficiencies in IE's and Safari's regexp engines. First we + // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we + // replace all simple value tokens with ']' characters. Third, we delete all + // open brackets that follow a colon or comma or that begin the text. Finally, + // we look to see that the remaining characters are only whitespace or ']' or + // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + + // In the third stage we use the eval function to compile the text into a + // JavaScript structure. The '{' operator is subject to a syntactic ambiguity + // in JavaScript: it can begin a block or an object literal. We wrap the text + // in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + + // In the optional fourth stage, we recursively walk the new structure, passing + // each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + + // If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + +})( + 'undefined' != typeof io ? io : module.exports + , typeof JSON !== 'undefined' ? JSON : undefined +); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io) { + + /** + * Parser namespace. + * + * @namespace + */ + + var parser = exports.parser = {}; + + /** + * Packet types. + */ + + var packets = parser.packets = [ + 'disconnect' + , 'connect' + , 'heartbeat' + , 'message' + , 'json' + , 'event' + , 'ack' + , 'error' + , 'noop' + ]; + + /** + * Errors reasons. + */ + + var reasons = parser.reasons = [ + 'transport not supported' + , 'client not handshaken' + , 'unauthorized' + ]; + + /** + * Errors advice. + */ + + var advice = parser.advice = [ + 'reconnect' + ]; + + /** + * Shortcuts. + */ + + var JSON = io.JSON + , indexOf = io.util.indexOf; + + /** + * Encodes a packet. + * + * @api private + */ + + parser.encodePacket = function (packet) { + var type = indexOf(packets, packet.type) + , id = packet.id || '' + , endpoint = packet.endpoint || '' + , ack = packet.ack + , data = null; + + switch (packet.type) { + case 'error': + var reason = packet.reason ? indexOf(reasons, packet.reason) : '' + , adv = packet.advice ? indexOf(advice, packet.advice) : ''; + + if (reason !== '' || adv !== '') + data = reason + (adv !== '' ? ('+' + adv) : ''); + + break; + + case 'message': + if (packet.data !== '') + data = packet.data; + break; + + case 'event': + var ev = { name: packet.name }; + + if (packet.args && packet.args.length) { + ev.args = packet.args; + } + + data = JSON.stringify(ev); + break; + + case 'json': + data = JSON.stringify(packet.data); + break; + + case 'connect': + if (packet.qs) + data = packet.qs; + break; + + case 'ack': + data = packet.ackId + + (packet.args && packet.args.length + ? '+' + JSON.stringify(packet.args) : ''); + break; + } + + // construct packet with required fragments + var encoded = [ + type + , id + (ack == 'data' ? '+' : '') + , endpoint + ]; + + // data fragment is optional + if (data !== null && data !== undefined) + encoded.push(data); + + return encoded.join(':'); + }; + + /** + * Encodes multiple messages (payload). + * + * @param {Array} messages + * @api private + */ + + parser.encodePayload = function (packets) { + var decoded = ''; + + if (packets.length == 1) + return packets[0]; + + for (var i = 0, l = packets.length; i < l; i++) { + var packet = packets[i]; + decoded += '\ufffd' + packet.length + '\ufffd' + packets[i]; + } + + return decoded; + }; + + /** + * Decodes a packet + * + * @api private + */ + + var regexp = /([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/; + + parser.decodePacket = function (data) { + var pieces = data.match(regexp); + + if (!pieces) return {}; + + var id = pieces[2] || '' + , data = pieces[5] || '' + , packet = { + type: packets[pieces[1]] + , endpoint: pieces[4] || '' + }; + + // whether we need to acknowledge the packet + if (id) { + packet.id = id; + if (pieces[3]) + packet.ack = 'data'; + else + packet.ack = true; + } + + // handle different packet types + switch (packet.type) { + case 'error': + var pieces = data.split('+'); + packet.reason = reasons[pieces[0]] || ''; + packet.advice = advice[pieces[1]] || ''; + break; + + case 'message': + packet.data = data || ''; + break; + + case 'event': + try { + var opts = JSON.parse(data); + packet.name = opts.name; + packet.args = opts.args; + } catch (e) { } + + packet.args = packet.args || []; + break; + + case 'json': + try { + packet.data = JSON.parse(data); + } catch (e) { } + break; + + case 'connect': + packet.qs = data || ''; + break; + + case 'ack': + var pieces = data.match(/^([0-9]+)(\+)?(.*)/); + if (pieces) { + packet.ackId = pieces[1]; + packet.args = []; + + if (pieces[3]) { + try { + packet.args = pieces[3] ? JSON.parse(pieces[3]) : []; + } catch (e) { } + } + } + break; + + case 'disconnect': + case 'heartbeat': + break; + }; + + return packet; + }; + + /** + * Decodes data payload. Detects multiple messages + * + * @return {Array} messages + * @api public + */ + + parser.decodePayload = function (data) { + // IE doesn't like data[i] for unicode chars, charAt works fine + if (data.charAt(0) == '\ufffd') { + var ret = []; + + for (var i = 1, length = ''; i < data.length; i++) { + if (data.charAt(i) == '\ufffd') { + ret.push(parser.decodePacket(data.substr(i + 1).substr(0, length))); + i += Number(length) + 1; + length = ''; + } else { + length += data.charAt(i); + } + } + + return ret; + } else { + return [parser.decodePacket(data)]; + } + }; + +})( + 'undefined' != typeof io ? io : module.exports + , 'undefined' != typeof io ? io : module.parent.exports +); +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io) { + + /** + * Expose constructor. + */ + + exports.Transport = Transport; + + /** + * This is the transport template for all supported transport methods. + * + * @constructor + * @api public + */ + + function Transport (socket, sessid) { + this.socket = socket; + this.sessid = sessid; + }; + + /** + * Apply EventEmitter mixin. + */ + + io.util.mixin(Transport, io.EventEmitter); + + /** + * Handles the response from the server. When a new response is received + * it will automatically update the timeout, decode the message and + * forwards the response to the onMessage function for further processing. + * + * @param {String} data Response from the server. + * @api private + */ + + Transport.prototype.onData = function (data) { + this.clearCloseTimeout(); + + // If the connection in currently open (or in a reopening state) reset the close + // timeout since we have just received data. This check is necessary so + // that we don't reset the timeout on an explicitly disconnected connection. + if (this.socket.connected || this.socket.connecting || this.socket.reconnecting) { + this.setCloseTimeout(); + } + + if (data !== '') { + // todo: we should only do decodePayload for xhr transports + var msgs = io.parser.decodePayload(data); + + if (msgs && msgs.length) { + for (var i = 0, l = msgs.length; i < l; i++) { + this.onPacket(msgs[i]); + } + } + } + + return this; + }; + + /** + * Handles packets. + * + * @api private + */ + + Transport.prototype.onPacket = function (packet) { + this.socket.setHeartbeatTimeout(); + + if (packet.type == 'heartbeat') { + return this.onHeartbeat(); + } + + if (packet.type == 'connect' && packet.endpoint == '') { + this.onConnect(); + } + + if (packet.type == 'error' && packet.advice == 'reconnect') { + this.open = false; + } + + this.socket.onPacket(packet); + + return this; + }; + + /** + * Sets close timeout + * + * @api private + */ + + Transport.prototype.setCloseTimeout = function () { + if (!this.closeTimeout) { + var self = this; + + this.closeTimeout = setTimeout(function () { + self.onDisconnect(); + }, this.socket.closeTimeout); + } + }; + + /** + * Called when transport disconnects. + * + * @api private + */ + + Transport.prototype.onDisconnect = function () { + if (this.close && this.open) this.close(); + this.clearTimeouts(); + this.socket.onDisconnect(); + return this; + }; + + /** + * Called when transport connects + * + * @api private + */ + + Transport.prototype.onConnect = function () { + this.socket.onConnect(); + return this; + } + + /** + * Clears close timeout + * + * @api private + */ + + Transport.prototype.clearCloseTimeout = function () { + if (this.closeTimeout) { + clearTimeout(this.closeTimeout); + this.closeTimeout = null; + } + }; + + /** + * Clear timeouts + * + * @api private + */ + + Transport.prototype.clearTimeouts = function () { + this.clearCloseTimeout(); + + if (this.reopenTimeout) { + clearTimeout(this.reopenTimeout); + } + }; + + /** + * Sends a packet + * + * @param {Object} packet object. + * @api private + */ + + Transport.prototype.packet = function (packet) { + this.send(io.parser.encodePacket(packet)); + }; + + /** + * Send the received heartbeat message back to server. So the server + * knows we are still connected. + * + * @param {String} heartbeat Heartbeat response from the server. + * @api private + */ + + Transport.prototype.onHeartbeat = function (heartbeat) { + this.packet({ type: 'heartbeat' }); + }; + + /** + * Called when the transport opens. + * + * @api private + */ + + Transport.prototype.onOpen = function () { + this.open = true; + this.clearCloseTimeout(); + this.socket.onOpen(); + }; + + /** + * Notifies the base when the connection with the Socket.IO server + * has been disconnected. + * + * @api private + */ + + Transport.prototype.onClose = function () { + var self = this; + + /* FIXME: reopen delay causing a infinit loop + this.reopenTimeout = setTimeout(function () { + self.open(); + }, this.socket.options['reopen delay']);*/ + + this.open = false; + this.socket.onClose(); + this.onDisconnect(); + }; + + /** + * Generates a connection url based on the Socket.IO URL Protocol. + * See for more details. + * + * @returns {String} Connection url + * @api private + */ + + Transport.prototype.prepareUrl = function () { + var options = this.socket.options; + + return this.scheme() + '://' + + options.host + ':' + options.port + '/' + + options.resource + '/' + io.protocol + + '/' + this.name + '/' + this.sessid; + }; + + /** + * Checks if the transport is ready to start a connection. + * + * @param {Socket} socket The socket instance that needs a transport + * @param {Function} fn The callback + * @api private + */ + + Transport.prototype.ready = function (socket, fn) { + fn.call(this); + }; +})( + 'undefined' != typeof io ? io : module.exports + , 'undefined' != typeof io ? io : module.parent.exports +); +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io, global) { + + /** + * Expose constructor. + */ + + exports.Socket = Socket; + + /** + * Create a new `Socket.IO client` which can establish a persistent + * connection with a Socket.IO enabled server. + * + * @api public + */ + + function Socket (options) { + this.options = { + port: 80 + , secure: false + , document: 'document' in global ? document : false + , resource: 'socket.io' + , transports: io.transports + , 'connect timeout': 10000 + , 'try multiple transports': true + , 'reconnect': true + , 'reconnection delay': 500 + , 'reconnection limit': Infinity + , 'reopen delay': 3000 + , 'max reconnection attempts': 10 + , 'sync disconnect on unload': true + , 'auto connect': true + , 'flash policy port': 10843 + }; + + io.util.merge(this.options, options); + + this.connected = false; + this.open = false; + this.connecting = false; + this.reconnecting = false; + this.namespaces = {}; + this.buffer = []; + this.doBuffer = false; + + if (this.options['sync disconnect on unload'] && + (!this.isXDomain() || io.util.ua.hasCORS)) { + var self = this; + + io.util.on(global, 'unload', function () { + self.disconnectSync(); + }, false); + } + + if (this.options['auto connect']) { + this.connect(); + } +}; + + /** + * Apply EventEmitter mixin. + */ + + io.util.mixin(Socket, io.EventEmitter); + + /** + * Returns a namespace listener/emitter for this socket + * + * @api public + */ + + Socket.prototype.of = function (name) { + if (!this.namespaces[name]) { + this.namespaces[name] = new io.SocketNamespace(this, name); + + if (name !== '') { + this.namespaces[name].packet({ type: 'connect' }); + } + } + + return this.namespaces[name]; + }; + + /** + * Emits the given event to the Socket and all namespaces + * + * @api private + */ + + Socket.prototype.publish = function () { + this.emit.apply(this, arguments); + + var nsp; + + for (var i in this.namespaces) { + if (this.namespaces.hasOwnProperty(i)) { + nsp = this.of(i); + nsp.$emit.apply(nsp, arguments); + } + } + }; + + /** + * Performs the handshake + * + * @api private + */ + + function empty () { }; + + Socket.prototype.handshake = function (fn) { + var self = this + , options = this.options; + + function complete (data) { + if (data instanceof Error) { + self.connecting = false; + self.onError(data.message); + } else { + fn.apply(null, data.split(':')); + } + }; + + var url = [ + 'http' + (options.secure ? 's' : '') + ':/' + , options.host + ':' + options.port + , options.resource + , io.protocol + , io.util.query(this.options.query, 't=' + +new Date) + ].join('/'); + + if (this.isXDomain() && !io.util.ua.hasCORS) { + var insertAt = document.getElementsByTagName('script')[0] + , script = document.createElement('script'); + + script.src = url + '&jsonp=' + io.j.length; + insertAt.parentNode.insertBefore(script, insertAt); + + io.j.push(function (data) { + complete(data); + script.parentNode.removeChild(script); + }); + } else { + var xhr = io.util.request(); + + xhr.open('GET', url, true); + xhr.withCredentials = true; + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + xhr.onreadystatechange = empty; + + if (xhr.status == 200) { + complete(xhr.responseText); + } else { + self.connecting = false; + !self.reconnecting && self.onError(xhr.responseText); + } + } + }; + xhr.send(null); + } + }; + + /** + * Find an available transport based on the options supplied in the constructor. + * + * @api private + */ + + Socket.prototype.getTransport = function (override) { + var transports = override || this.transports, match; + + for (var i = 0, transport; transport = transports[i]; i++) { + if (io.Transport[transport] + && io.Transport[transport].check(this) + && (!this.isXDomain() || io.Transport[transport].xdomainCheck())) { + return new io.Transport[transport](this, this.sessionid); + } + } + + return null; + }; + + /** + * Connects to the server. + * + * @param {Function} [fn] Callback. + * @returns {io.Socket} + * @api public + */ + + Socket.prototype.connect = function (fn) { + if (this.connecting) { + return this; + } + + var self = this; + self.connecting = true; + + this.handshake(function (sid, heartbeat, close, transports) { + self.sessionid = sid; + self.closeTimeout = close * 1000; + self.heartbeatTimeout = heartbeat * 1000; + self.transports = transports ? io.util.intersect( + transports.split(',') + , self.options.transports + ) : self.options.transports; + + self.setHeartbeatTimeout(); + + function connect (transports){ + if (self.transport) self.transport.clearTimeouts(); + + self.transport = self.getTransport(transports); + if (!self.transport) return self.publish('connect_failed'); + + // once the transport is ready + self.transport.ready(self, function () { + self.connecting = true; + self.publish('connecting', self.transport.name); + self.transport.open(); + + if (self.options['connect timeout']) { + self.connectTimeoutTimer = setTimeout(function () { + if (!self.connected) { + self.connecting = false; + + if (self.options['try multiple transports']) { + if (!self.remainingTransports) { + self.remainingTransports = self.transports.slice(0); + } + + var remaining = self.remainingTransports; + + while (remaining.length > 0 && remaining.splice(0,1)[0] != + self.transport.name) {} + + if (remaining.length){ + connect(remaining); + } else { + self.publish('connect_failed'); + } + } + } + }, self.options['connect timeout']); + } + }); + } + + connect(self.transports); + + self.once('connect', function (){ + clearTimeout(self.connectTimeoutTimer); + + fn && typeof fn == 'function' && fn(); + }); + }); + + return this; + }; + + /** + * Clears and sets a new heartbeat timeout using the value given by the + * server during the handshake. + * + * @api private + */ + + Socket.prototype.setHeartbeatTimeout = function () { + clearTimeout(this.heartbeatTimeoutTimer); + + var self = this; + this.heartbeatTimeoutTimer = setTimeout(function () { + self.transport.onClose(); + }, this.heartbeatTimeout); + }; + + /** + * Sends a message. + * + * @param {Object} data packet. + * @returns {io.Socket} + * @api public + */ + + Socket.prototype.packet = function (data) { + if (this.connected && !this.doBuffer) { + this.transport.packet(data); + } else { + this.buffer.push(data); + } + + return this; + }; + + /** + * Sets buffer state + * + * @api private + */ + + Socket.prototype.setBuffer = function (v) { + this.doBuffer = v; + + if (!v && this.connected && this.buffer.length) { + this.transport.payload(this.buffer); + this.buffer = []; + } + }; + + /** + * Disconnect the established connect. + * + * @returns {io.Socket} + * @api public + */ + + Socket.prototype.disconnect = function () { + if (this.connected || this.connecting) { + if (this.open) { + this.of('').packet({ type: 'disconnect' }); + } + + // handle disconnection immediately + this.onDisconnect('booted'); + } + + return this; + }; + + /** + * Disconnects the socket with a sync XHR. + * + * @api private + */ + + Socket.prototype.disconnectSync = function () { + // ensure disconnection + var xhr = io.util.request() + , uri = this.resource + '/' + io.protocol + '/' + this.sessionid; + + xhr.open('GET', uri, true); + + // handle disconnection immediately + this.onDisconnect('booted'); + }; + + /** + * Check if we need to use cross domain enabled transports. Cross domain would + * be a different port or different domain name. + * + * @returns {Boolean} + * @api private + */ + + Socket.prototype.isXDomain = function () { + + var port = global.location.port || + ('https:' == global.location.protocol ? 443 : 80); + + return this.options.host !== global.location.hostname + || this.options.port != port; + }; + + /** + * Called upon handshake. + * + * @api private + */ + + Socket.prototype.onConnect = function () { + if (!this.connected) { + this.connected = true; + this.connecting = false; + if (!this.doBuffer) { + // make sure to flush the buffer + this.setBuffer(false); + } + this.emit('connect'); + } + }; + + /** + * Called when the transport opens + * + * @api private + */ + + Socket.prototype.onOpen = function () { + this.open = true; + }; + + /** + * Called when the transport closes. + * + * @api private + */ + + Socket.prototype.onClose = function () { + this.open = false; + clearTimeout(this.heartbeatTimeoutTimer); + }; + + /** + * Called when the transport first opens a connection + * + * @param text + */ + + Socket.prototype.onPacket = function (packet) { + this.of(packet.endpoint).onPacket(packet); + }; + + /** + * Handles an error. + * + * @api private + */ + + Socket.prototype.onError = function (err) { + if (err && err.advice) { + if (err.advice === 'reconnect' && (this.connected || this.connecting)) { + this.disconnect(); + if (this.options.reconnect) { + this.reconnect(); + } + } + } + + this.publish('error', err && err.reason ? err.reason : err); + }; + + /** + * Called when the transport disconnects. + * + * @api private + */ + + Socket.prototype.onDisconnect = function (reason) { + var wasConnected = this.connected + , wasConnecting = this.connecting; + + this.connected = false; + this.connecting = false; + this.open = false; + + if (wasConnected || wasConnecting) { + this.transport.close(); + this.transport.clearTimeouts(); + if (wasConnected) { + this.publish('disconnect', reason); + + if ('booted' != reason && this.options.reconnect && !this.reconnecting) { + this.reconnect(); + } + } + } + }; + + /** + * Called upon reconnection. + * + * @api private + */ + + Socket.prototype.reconnect = function () { + this.reconnecting = true; + this.reconnectionAttempts = 0; + this.reconnectionDelay = this.options['reconnection delay']; + + var self = this + , maxAttempts = this.options['max reconnection attempts'] + , tryMultiple = this.options['try multiple transports'] + , limit = this.options['reconnection limit']; + + function reset () { + if (self.connected) { + for (var i in self.namespaces) { + if (self.namespaces.hasOwnProperty(i) && '' !== i) { + self.namespaces[i].packet({ type: 'connect' }); + } + } + self.publish('reconnect', self.transport.name, self.reconnectionAttempts); + } + + clearTimeout(self.reconnectionTimer); + + self.removeListener('connect_failed', maybeReconnect); + self.removeListener('connect', maybeReconnect); + + self.reconnecting = false; + + delete self.reconnectionAttempts; + delete self.reconnectionDelay; + delete self.reconnectionTimer; + delete self.redoTransports; + + self.options['try multiple transports'] = tryMultiple; + }; + + function maybeReconnect () { + if (!self.reconnecting) { + return; + } + + if (self.connected) { + return reset(); + }; + + if (self.connecting && self.reconnecting) { + return self.reconnectionTimer = setTimeout(maybeReconnect, 1000); + } + + if (self.reconnectionAttempts++ >= maxAttempts) { + if (!self.redoTransports) { + self.on('connect_failed', maybeReconnect); + self.options['try multiple transports'] = true; + self.transport = self.getTransport(); + self.redoTransports = true; + self.connect(); + } else { + self.publish('reconnect_failed'); + reset(); + } + } else { + if (self.reconnectionDelay < limit) { + self.reconnectionDelay *= 2; // exponential back off + } + + self.connect(); + self.publish('reconnecting', self.reconnectionDelay, self.reconnectionAttempts); + self.reconnectionTimer = setTimeout(maybeReconnect, self.reconnectionDelay); + } + }; + + this.options['try multiple transports'] = false; + this.reconnectionTimer = setTimeout(maybeReconnect, this.reconnectionDelay); + + this.on('connect', maybeReconnect); + }; + +})( + 'undefined' != typeof io ? io : module.exports + , 'undefined' != typeof io ? io : module.parent.exports + , this +); +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io) { + + /** + * Expose constructor. + */ + + exports.SocketNamespace = SocketNamespace; + + /** + * Socket namespace constructor. + * + * @constructor + * @api public + */ + + function SocketNamespace (socket, name) { + this.socket = socket; + this.name = name || ''; + this.flags = {}; + this.json = new Flag(this, 'json'); + this.ackPackets = 0; + this.acks = {}; + }; + + /** + * Apply EventEmitter mixin. + */ + + io.util.mixin(SocketNamespace, io.EventEmitter); + + /** + * Copies emit since we override it + * + * @api private + */ + + SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit; + + /** + * Creates a new namespace, by proxying the request to the socket. This + * allows us to use the synax as we do on the server. + * + * @api public + */ + + SocketNamespace.prototype.of = function () { + return this.socket.of.apply(this.socket, arguments); + }; + + /** + * Sends a packet. + * + * @api private + */ + + SocketNamespace.prototype.packet = function (packet) { + packet.endpoint = this.name; + this.socket.packet(packet); + this.flags = {}; + return this; + }; + + /** + * Sends a message + * + * @api public + */ + + SocketNamespace.prototype.send = function (data, fn) { + var packet = { + type: this.flags.json ? 'json' : 'message' + , data: data + }; + + if ('function' == typeof fn) { + packet.id = ++this.ackPackets; + packet.ack = true; + this.acks[packet.id] = fn; + } + + return this.packet(packet); + }; + + /** + * Emits an event + * + * @api public + */ + + SocketNamespace.prototype.emit = function (name) { + var args = Array.prototype.slice.call(arguments, 1) + , lastArg = args[args.length - 1] + , packet = { + type: 'event' + , name: name + }; + + if ('function' == typeof lastArg) { + packet.id = ++this.ackPackets; + packet.ack = 'data'; + this.acks[packet.id] = lastArg; + args = args.slice(0, args.length - 1); + } + + packet.args = args; + + return this.packet(packet); + }; + + /** + * Disconnects the namespace + * + * @api private + */ + + SocketNamespace.prototype.disconnect = function () { + if (this.name === '') { + this.socket.disconnect(); + } else { + this.packet({ type: 'disconnect' }); + this.$emit('disconnect'); + } + + return this; + }; + + /** + * Handles a packet + * + * @api private + */ + + SocketNamespace.prototype.onPacket = function (packet) { + var self = this; + + function ack () { + self.packet({ + type: 'ack' + , args: io.util.toArray(arguments) + , ackId: packet.id + }); + }; + + switch (packet.type) { + case 'connect': + this.$emit('connect'); + break; + + case 'disconnect': + if (this.name === '') { + this.socket.onDisconnect(packet.reason || 'booted'); + } else { + this.$emit('disconnect', packet.reason); + } + break; + + case 'message': + case 'json': + var params = ['message', packet.data]; + + if (packet.ack == 'data') { + params.push(ack); + } else if (packet.ack) { + this.packet({ type: 'ack', ackId: packet.id }); + } + + this.$emit.apply(this, params); + break; + + case 'event': + var params = [packet.name].concat(packet.args); + + if (packet.ack == 'data') + params.push(ack); + + this.$emit.apply(this, params); + break; + + case 'ack': + if (this.acks[packet.ackId]) { + this.acks[packet.ackId].apply(this, packet.args); + delete this.acks[packet.ackId]; + } + break; + + case 'error': + if (packet.advice){ + this.socket.onError(packet); + } else { + if (packet.reason == 'unauthorized') { + this.$emit('connect_failed', packet.reason); + } else { + this.$emit('error', packet.reason); + } + } + break; + } + }; + + /** + * Flag interface. + * + * @api private + */ + + function Flag (nsp, name) { + this.namespace = nsp; + this.name = name; + }; + + /** + * Send a message + * + * @api public + */ + + Flag.prototype.send = function () { + this.namespace.flags[this.name] = true; + this.namespace.send.apply(this.namespace, arguments); + }; + + /** + * Emit an event + * + * @api public + */ + + Flag.prototype.emit = function () { + this.namespace.flags[this.name] = true; + this.namespace.emit.apply(this.namespace, arguments); + }; + +})( + 'undefined' != typeof io ? io : module.exports + , 'undefined' != typeof io ? io : module.parent.exports +); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io, global) { + + /** + * Expose constructor. + */ + + exports.websocket = WS; + + /** + * The WebSocket transport uses the HTML5 WebSocket API to establish an + * persistent connection with the Socket.IO server. This transport will also + * be inherited by the FlashSocket fallback as it provides a API compatible + * polyfill for the WebSockets. + * + * @constructor + * @extends {io.Transport} + * @api public + */ + + function WS (socket) { + io.Transport.apply(this, arguments); + }; + + /** + * Inherits from Transport. + */ + + io.util.inherit(WS, io.Transport); + + /** + * Transport name + * + * @api public + */ + + WS.prototype.name = 'websocket'; + + /** + * Initializes a new `WebSocket` connection with the Socket.IO server. We attach + * all the appropriate listeners to handle the responses from the server. + * + * @returns {Transport} + * @api public + */ + + WS.prototype.open = function () { + var query = io.util.query(this.socket.options.query) + , self = this + , Socket + + + if (!Socket) { + Socket = global.MozWebSocket || global.WebSocket; + } + + this.websocket = new Socket(this.prepareUrl() + query); + + this.websocket.onopen = function () { + self.onOpen(); + self.socket.setBuffer(false); + }; + this.websocket.onmessage = function (ev) { + self.onData(ev.data); + }; + this.websocket.onclose = function () { + self.onClose(); + self.socket.setBuffer(true); + }; + this.websocket.onerror = function (e) { + self.onError(e); + }; + + return this; + }; + + /** + * Send a message to the Socket.IO server. The message will automatically be + * encoded in the correct message format. + * + * @returns {Transport} + * @api public + */ + + // Do to a bug in the current IDevices browser, we need to wrap the send in a + // setTimeout, when they resume from sleeping the browser will crash if + // we don't allow the browser time to detect the socket has been closed + if (io.util.ua.iDevice) { + WS.prototype.send = function (data) { + var self = this; + setTimeout(function() { + self.websocket.send(data); + },0); + return this; + }; + } else { + WS.prototype.send = function (data) { + this.websocket.send(data); + return this; + }; + } + + /** + * Payload + * + * @api private + */ + + WS.prototype.payload = function (arr) { + for (var i = 0, l = arr.length; i < l; i++) { + this.packet(arr[i]); + } + return this; + }; + + /** + * Disconnect the established `WebSocket` connection. + * + * @returns {Transport} + * @api public + */ + + WS.prototype.close = function () { + this.websocket.close(); + return this; + }; + + /** + * Handle the errors that `WebSocket` might be giving when we + * are attempting to connect or send messages. + * + * @param {Error} e The error. + * @api private + */ + + WS.prototype.onError = function (e) { + this.socket.onError(e); + }; + + /** + * Returns the appropriate scheme for the URI generation. + * + * @api private + */ + WS.prototype.scheme = function () { + return this.socket.options.secure ? 'wss' : 'ws'; + }; + + /** + * Checks if the browser has support for native `WebSockets` and that + * it's not the polyfill created for the FlashSocket transport. + * + * @return {Boolean} + * @api public + */ + + WS.check = function () { + return ('WebSocket' in global && !('__addTask' in WebSocket)) + || 'MozWebSocket' in global; + }; + + /** + * Check if the `WebSocket` transport support cross domain communications. + * + * @returns {Boolean} + * @api public + */ + + WS.xdomainCheck = function () { + return true; + }; + + /** + * Add the transport to your public io.transports array. + * + * @api private + */ + + io.transports.push('websocket'); + +})( + 'undefined' != typeof io ? io.Transport : module.exports + , 'undefined' != typeof io ? io : module.parent.exports + , this +); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io) { + + /** + * Expose constructor. + */ + + exports.flashsocket = Flashsocket; + + /** + * The FlashSocket transport. This is a API wrapper for the HTML5 WebSocket + * specification. It uses a .swf file to communicate with the server. If you want + * to serve the .swf file from a other server than where the Socket.IO script is + * coming from you need to use the insecure version of the .swf. More information + * about this can be found on the github page. + * + * @constructor + * @extends {io.Transport.websocket} + * @api public + */ + + function Flashsocket () { + io.Transport.websocket.apply(this, arguments); + }; + + /** + * Inherits from Transport. + */ + + io.util.inherit(Flashsocket, io.Transport.websocket); + + /** + * Transport name + * + * @api public + */ + + Flashsocket.prototype.name = 'flashsocket'; + + /** + * Disconnect the established `FlashSocket` connection. This is done by adding a + * new task to the FlashSocket. The rest will be handled off by the `WebSocket` + * transport. + * + * @returns {Transport} + * @api public + */ + + Flashsocket.prototype.open = function () { + var self = this + , args = arguments; + + WebSocket.__addTask(function () { + io.Transport.websocket.prototype.open.apply(self, args); + }); + return this; + }; + + /** + * Sends a message to the Socket.IO server. This is done by adding a new + * task to the FlashSocket. The rest will be handled off by the `WebSocket` + * transport. + * + * @returns {Transport} + * @api public + */ + + Flashsocket.prototype.send = function () { + var self = this, args = arguments; + WebSocket.__addTask(function () { + io.Transport.websocket.prototype.send.apply(self, args); + }); + return this; + }; + + /** + * Disconnects the established `FlashSocket` connection. + * + * @returns {Transport} + * @api public + */ + + Flashsocket.prototype.close = function () { + WebSocket.__tasks.length = 0; + io.Transport.websocket.prototype.close.call(this); + return this; + }; + + /** + * The WebSocket fall back needs to append the flash container to the body + * element, so we need to make sure we have access to it. Or defer the call + * until we are sure there is a body element. + * + * @param {Socket} socket The socket instance that needs a transport + * @param {Function} fn The callback + * @api private + */ + + Flashsocket.prototype.ready = function (socket, fn) { + function init () { + var options = socket.options + , port = options['flash policy port'] + , path = [ + 'http' + (options.secure ? 's' : '') + ':/' + , options.host + ':' + options.port + , options.resource + , 'static/flashsocket' + , 'WebSocketMain' + (socket.isXDomain() ? 'Insecure' : '') + '.swf' + ]; + + // Only start downloading the swf file when the checked that this browser + // actually supports it + if (!Flashsocket.loaded) { + if (typeof WEB_SOCKET_SWF_LOCATION === 'undefined') { + // Set the correct file based on the XDomain settings + WEB_SOCKET_SWF_LOCATION = path.join('/'); + } + + if (port !== 843) { + WebSocket.loadFlashPolicyFile('xmlsocket://' + options.host + ':' + port); + } + + WebSocket.__initialize(); + Flashsocket.loaded = true; + } + + fn.call(self); + } + + var self = this; + if (document.body) return init(); + + io.util.load(init); + }; + + /** + * Check if the FlashSocket transport is supported as it requires that the Adobe + * Flash Player plug-in version `10.0.0` or greater is installed. And also check if + * the polyfill is correctly loaded. + * + * @returns {Boolean} + * @api public + */ + + Flashsocket.check = function () { + if ( + typeof WebSocket == 'undefined' + || !('__initialize' in WebSocket) || !swfobject + ) return false; + + return swfobject.getFlashPlayerVersion().major >= 10; + }; + + /** + * Check if the FlashSocket transport can be used as cross domain / cross origin + * transport. Because we can't see which type (secure or insecure) of .swf is used + * we will just return true. + * + * @returns {Boolean} + * @api public + */ + + Flashsocket.xdomainCheck = function () { + return true; + }; + + /** + * Disable AUTO_INITIALIZATION + */ + + if (typeof window != 'undefined') { + WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true; + } + + /** + * Add the transport to your public io.transports array. + * + * @api private + */ + + io.transports.push('flashsocket'); +})( + 'undefined' != typeof io ? io.Transport : module.exports + , 'undefined' != typeof io ? io : module.parent.exports +); +/* SWFObject v2.2 + is released under the MIT License +*/ +if ('undefined' != typeof window) { +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O[(['Active'].concat('Object').join('X'))]!=D){try{var ad=new window[(['Active'].concat('Object').join('X'))](W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab +// License: New BSD License +// Reference: http://dev.w3.org/html5/websockets/ +// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol + +(function() { + + if ('undefined' == typeof window || window.WebSocket) return; + + var console = window.console; + if (!console || !console.log || !console.error) { + console = {log: function(){ }, error: function(){ }}; + } + + if (!swfobject.hasFlashPlayerVersion("10.0.0")) { + console.error("Flash Player >= 10.0.0 is required."); + return; + } + if (location.protocol == "file:") { + console.error( + "WARNING: web-socket-js doesn't work in file:///... URL " + + "unless you set Flash Security Settings properly. " + + "Open the page via Web server i.e. http://..."); + } + + /** + * This class represents a faux web socket. + * @param {string} url + * @param {array or string} protocols + * @param {string} proxyHost + * @param {int} proxyPort + * @param {string} headers + */ + WebSocket = function(url, protocols, proxyHost, proxyPort, headers) { + var self = this; + self.__id = WebSocket.__nextId++; + WebSocket.__instances[self.__id] = self; + self.readyState = WebSocket.CONNECTING; + self.bufferedAmount = 0; + self.__events = {}; + if (!protocols) { + protocols = []; + } else if (typeof protocols == "string") { + protocols = [protocols]; + } + // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc. + // Otherwise, when onopen fires immediately, onopen is called before it is set. + setTimeout(function() { + WebSocket.__addTask(function() { + WebSocket.__flash.create( + self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null); + }); + }, 0); + }; + + /** + * Send data to the web socket. + * @param {string} data The data to send to the socket. + * @return {boolean} True for success, false for failure. + */ + WebSocket.prototype.send = function(data) { + if (this.readyState == WebSocket.CONNECTING) { + throw "INVALID_STATE_ERR: Web Socket connection has not been established"; + } + // We use encodeURIComponent() here, because FABridge doesn't work if + // the argument includes some characters. We don't use escape() here + // because of this: + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#escape_and_unescape_Functions + // But it looks decodeURIComponent(encodeURIComponent(s)) doesn't + // preserve all Unicode characters either e.g. "\uffff" in Firefox. + // Note by wtritch: Hopefully this will not be necessary using ExternalInterface. Will require + // additional testing. + var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data)); + if (result < 0) { // success + return true; + } else { + this.bufferedAmount += result; + return false; + } + }; + + /** + * Close this web socket gracefully. + */ + WebSocket.prototype.close = function() { + if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) { + return; + } + this.readyState = WebSocket.CLOSING; + WebSocket.__flash.close(this.__id); + }; + + /** + * Implementation of {@link DOM 2 EventTarget Interface} + * + * @param {string} type + * @param {function} listener + * @param {boolean} useCapture + * @return void + */ + WebSocket.prototype.addEventListener = function(type, listener, useCapture) { + if (!(type in this.__events)) { + this.__events[type] = []; + } + this.__events[type].push(listener); + }; + + /** + * Implementation of {@link DOM 2 EventTarget Interface} + * + * @param {string} type + * @param {function} listener + * @param {boolean} useCapture + * @return void + */ + WebSocket.prototype.removeEventListener = function(type, listener, useCapture) { + if (!(type in this.__events)) return; + var events = this.__events[type]; + for (var i = events.length - 1; i >= 0; --i) { + if (events[i] === listener) { + events.splice(i, 1); + break; + } + } + }; + + /** + * Implementation of {@link DOM 2 EventTarget Interface} + * + * @param {Event} event + * @return void + */ + WebSocket.prototype.dispatchEvent = function(event) { + var events = this.__events[event.type] || []; + for (var i = 0; i < events.length; ++i) { + events[i](event); + } + var handler = this["on" + event.type]; + if (handler) handler(event); + }; + + /** + * Handles an event from Flash. + * @param {Object} flashEvent + */ + WebSocket.prototype.__handleEvent = function(flashEvent) { + if ("readyState" in flashEvent) { + this.readyState = flashEvent.readyState; + } + if ("protocol" in flashEvent) { + this.protocol = flashEvent.protocol; + } + + var jsEvent; + if (flashEvent.type == "open" || flashEvent.type == "error") { + jsEvent = this.__createSimpleEvent(flashEvent.type); + } else if (flashEvent.type == "close") { + // TODO implement jsEvent.wasClean + jsEvent = this.__createSimpleEvent("close"); + } else if (flashEvent.type == "message") { + var data = decodeURIComponent(flashEvent.message); + jsEvent = this.__createMessageEvent("message", data); + } else { + throw "unknown event type: " + flashEvent.type; + } + + this.dispatchEvent(jsEvent); + }; + + WebSocket.prototype.__createSimpleEvent = function(type) { + if (document.createEvent && window.Event) { + var event = document.createEvent("Event"); + event.initEvent(type, false, false); + return event; + } else { + return {type: type, bubbles: false, cancelable: false}; + } + }; + + WebSocket.prototype.__createMessageEvent = function(type, data) { + if (document.createEvent && window.MessageEvent && !window.opera) { + var event = document.createEvent("MessageEvent"); + event.initMessageEvent("message", false, false, data, null, null, window, null); + return event; + } else { + // IE and Opera, the latter one truncates the data parameter after any 0x00 bytes. + return {type: type, data: data, bubbles: false, cancelable: false}; + } + }; + + /** + * Define the WebSocket readyState enumeration. + */ + WebSocket.CONNECTING = 0; + WebSocket.OPEN = 1; + WebSocket.CLOSING = 2; + WebSocket.CLOSED = 3; + + WebSocket.__flash = null; + WebSocket.__instances = {}; + WebSocket.__tasks = []; + WebSocket.__nextId = 0; + + /** + * Load a new flash security policy file. + * @param {string} url + */ + WebSocket.loadFlashPolicyFile = function(url){ + WebSocket.__addTask(function() { + WebSocket.__flash.loadManualPolicyFile(url); + }); + }; + + /** + * Loads WebSocketMain.swf and creates WebSocketMain object in Flash. + */ + WebSocket.__initialize = function() { + if (WebSocket.__flash) return; + + if (WebSocket.__swfLocation) { + // For backword compatibility. + window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation; + } + if (!window.WEB_SOCKET_SWF_LOCATION) { + console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf"); + return; + } + var container = document.createElement("div"); + container.id = "webSocketContainer"; + // Hides Flash box. We cannot use display: none or visibility: hidden because it prevents + // Flash from loading at least in IE. So we move it out of the screen at (-100, -100). + // But this even doesn't work with Flash Lite (e.g. in Droid Incredible). So with Flash + // Lite, we put it at (0, 0). This shows 1x1 box visible at left-top corner but this is + // the best we can do as far as we know now. + container.style.position = "absolute"; + if (WebSocket.__isFlashLite()) { + container.style.left = "0px"; + container.style.top = "0px"; + } else { + container.style.left = "-100px"; + container.style.top = "-100px"; + } + var holder = document.createElement("div"); + holder.id = "webSocketFlash"; + container.appendChild(holder); + document.body.appendChild(container); + // See this article for hasPriority: + // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html + swfobject.embedSWF( + WEB_SOCKET_SWF_LOCATION, + "webSocketFlash", + "1" /* width */, + "1" /* height */, + "10.0.0" /* SWF version */, + null, + null, + {hasPriority: true, swliveconnect : true, allowScriptAccess: "always"}, + null, + function(e) { + if (!e.success) { + console.error("[WebSocket] swfobject.embedSWF failed"); + } + }); + }; + + /** + * Called by Flash to notify JS that it's fully loaded and ready + * for communication. + */ + WebSocket.__onFlashInitialized = function() { + // We need to set a timeout here to avoid round-trip calls + // to flash during the initialization process. + setTimeout(function() { + WebSocket.__flash = document.getElementById("webSocketFlash"); + WebSocket.__flash.setCallerUrl(location.href); + WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG); + for (var i = 0; i < WebSocket.__tasks.length; ++i) { + WebSocket.__tasks[i](); + } + WebSocket.__tasks = []; + }, 0); + }; + + /** + * Called by Flash to notify WebSockets events are fired. + */ + WebSocket.__onFlashEvent = function() { + setTimeout(function() { + try { + // Gets events using receiveEvents() instead of getting it from event object + // of Flash event. This is to make sure to keep message order. + // It seems sometimes Flash events don't arrive in the same order as they are sent. + var events = WebSocket.__flash.receiveEvents(); + for (var i = 0; i < events.length; ++i) { + WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]); + } + } catch (e) { + console.error(e); + } + }, 0); + return true; + }; + + // Called by Flash. + WebSocket.__log = function(message) { + console.log(decodeURIComponent(message)); + }; + + // Called by Flash. + WebSocket.__error = function(message) { + console.error(decodeURIComponent(message)); + }; + + WebSocket.__addTask = function(task) { + if (WebSocket.__flash) { + task(); + } else { + WebSocket.__tasks.push(task); + } + }; + + /** + * Test if the browser is running flash lite. + * @return {boolean} True if flash lite is running, false otherwise. + */ + WebSocket.__isFlashLite = function() { + if (!window.navigator || !window.navigator.mimeTypes) { + return false; + } + var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"]; + if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) { + return false; + } + return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false; + }; + + if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) { + if (window.addEventListener) { + window.addEventListener("load", function(){ + WebSocket.__initialize(); + }, false); + } else { + window.attachEvent("onload", function(){ + WebSocket.__initialize(); + }); + } + } + +})(); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io, global) { + + /** + * Expose constructor. + * + * @api public + */ + + exports.XHR = XHR; + + /** + * XHR constructor + * + * @costructor + * @api public + */ + + function XHR (socket) { + if (!socket) return; + + io.Transport.apply(this, arguments); + this.sendBuffer = []; + }; + + /** + * Inherits from Transport. + */ + + io.util.inherit(XHR, io.Transport); + + /** + * Establish a connection + * + * @returns {Transport} + * @api public + */ + + XHR.prototype.open = function () { + this.socket.setBuffer(false); + this.onOpen(); + this.get(); + + // we need to make sure the request succeeds since we have no indication + // whether the request opened or not until it succeeded. + this.setCloseTimeout(); + + return this; + }; + + /** + * Check if we need to send data to the Socket.IO server, if we have data in our + * buffer we encode it and forward it to the `post` method. + * + * @api private + */ + + XHR.prototype.payload = function (payload) { + var msgs = []; + + for (var i = 0, l = payload.length; i < l; i++) { + msgs.push(io.parser.encodePacket(payload[i])); + } + + this.send(io.parser.encodePayload(msgs)); + }; + + /** + * Send data to the Socket.IO server. + * + * @param data The message + * @returns {Transport} + * @api public + */ + + XHR.prototype.send = function (data) { + this.post(data); + return this; + }; + + /** + * Posts a encoded message to the Socket.IO server. + * + * @param {String} data A encoded message. + * @api private + */ + + function empty () { }; + + XHR.prototype.post = function (data) { + var self = this; + this.socket.setBuffer(true); + + function stateChange () { + if (this.readyState == 4) { + this.onreadystatechange = empty; + self.posting = false; + + if (this.status == 200){ + self.socket.setBuffer(false); + } else { + self.onClose(); + } + } + } + + function onload () { + this.onload = empty; + self.socket.setBuffer(false); + }; + + this.sendXHR = this.request('POST'); + + if (global.XDomainRequest && this.sendXHR instanceof XDomainRequest) { + this.sendXHR.onload = this.sendXHR.onerror = onload; + } else { + this.sendXHR.onreadystatechange = stateChange; + } + + this.sendXHR.send(data); + }; + + /** + * Disconnects the established `XHR` connection. + * + * @returns {Transport} + * @api public + */ + + XHR.prototype.close = function () { + this.onClose(); + return this; + }; + + /** + * Generates a configured XHR request + * + * @param {String} url The url that needs to be requested. + * @param {String} method The method the request should use. + * @returns {XMLHttpRequest} + * @api private + */ + + XHR.prototype.request = function (method) { + var req = io.util.request(this.socket.isXDomain()) + , query = io.util.query(this.socket.options.query, 't=' + +new Date); + + req.open(method || 'GET', this.prepareUrl() + query, true); + + if (method == 'POST') { + try { + if (req.setRequestHeader) { + req.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); + } else { + // XDomainRequest + req.contentType = 'text/plain'; + } + } catch (e) {} + } + + return req; + }; + + /** + * Returns the scheme to use for the transport URLs. + * + * @api private + */ + + XHR.prototype.scheme = function () { + return this.socket.options.secure ? 'https' : 'http'; + }; + + /** + * Check if the XHR transports are supported + * + * @param {Boolean} xdomain Check if we support cross domain requests. + * @returns {Boolean} + * @api public + */ + + XHR.check = function (socket, xdomain) { + try { + var request = io.util.request(xdomain), + usesXDomReq = (global.XDomainRequest && request instanceof XDomainRequest), + socketProtocol = (socket && socket.options && socket.options.secure ? 'https:' : 'http:'), + isXProtocol = (socketProtocol != global.location.protocol); + if (request && !(usesXDomReq && isXProtocol)) { + return true; + } + } catch(e) {} + + return false; + }; + + /** + * Check if the XHR transport supports cross domain requests. + * + * @returns {Boolean} + * @api public + */ + + XHR.xdomainCheck = function () { + return XHR.check(null, true); + }; + +})( + 'undefined' != typeof io ? io.Transport : module.exports + , 'undefined' != typeof io ? io : module.parent.exports + , this +); +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io) { + + /** + * Expose constructor. + */ + + exports.htmlfile = HTMLFile; + + /** + * The HTMLFile transport creates a `forever iframe` based transport + * for Internet Explorer. Regular forever iframe implementations will + * continuously trigger the browsers buzy indicators. If the forever iframe + * is created inside a `htmlfile` these indicators will not be trigged. + * + * @constructor + * @extends {io.Transport.XHR} + * @api public + */ + + function HTMLFile (socket) { + io.Transport.XHR.apply(this, arguments); + }; + + /** + * Inherits from XHR transport. + */ + + io.util.inherit(HTMLFile, io.Transport.XHR); + + /** + * Transport name + * + * @api public + */ + + HTMLFile.prototype.name = 'htmlfile'; + + /** + * Creates a new Ac...eX `htmlfile` with a forever loading iframe + * that can be used to listen to messages. Inside the generated + * `htmlfile` a reference will be made to the HTMLFile transport. + * + * @api private + */ + + HTMLFile.prototype.get = function () { + this.doc = new window[(['Active'].concat('Object').join('X'))]('htmlfile'); + this.doc.open(); + this.doc.write(''); + this.doc.close(); + this.doc.parentWindow.s = this; + + var iframeC = this.doc.createElement('div'); + iframeC.className = 'socketio'; + + this.doc.body.appendChild(iframeC); + this.iframe = this.doc.createElement('iframe'); + + iframeC.appendChild(this.iframe); + + var self = this + , query = io.util.query(this.socket.options.query, 't='+ +new Date); + + this.iframe.src = this.prepareUrl() + query; + + io.util.on(window, 'unload', function () { + self.destroy(); + }); + }; + + /** + * The Socket.IO server will write script tags inside the forever + * iframe, this function will be used as callback for the incoming + * information. + * + * @param {String} data The message + * @param {document} doc Reference to the context + * @api private + */ + + HTMLFile.prototype._ = function (data, doc) { + this.onData(data); + try { + var script = doc.getElementsByTagName('script')[0]; + script.parentNode.removeChild(script); + } catch (e) { } + }; + + /** + * Destroy the established connection, iframe and `htmlfile`. + * And calls the `CollectGarbage` function of Internet Explorer + * to release the memory. + * + * @api private + */ + + HTMLFile.prototype.destroy = function () { + if (this.iframe){ + try { + this.iframe.src = 'about:blank'; + } catch(e){} + + this.doc = null; + this.iframe.parentNode.removeChild(this.iframe); + this.iframe = null; + + CollectGarbage(); + } + }; + + /** + * Disconnects the established connection. + * + * @returns {Transport} Chaining. + * @api public + */ + + HTMLFile.prototype.close = function () { + this.destroy(); + return io.Transport.XHR.prototype.close.call(this); + }; + + /** + * Checks if the browser supports this transport. The browser + * must have an `Ac...eXObject` implementation. + * + * @return {Boolean} + * @api public + */ + + HTMLFile.check = function () { + if (typeof window != "undefined" && (['Active'].concat('Object').join('X')) in window){ + try { + var a = new window[(['Active'].concat('Object').join('X'))]('htmlfile'); + return a && io.Transport.XHR.check(); + } catch(e){} + } + return false; + }; + + /** + * Check if cross domain requests are supported. + * + * @returns {Boolean} + * @api public + */ + + HTMLFile.xdomainCheck = function () { + // we can probably do handling for sub-domains, we should + // test that it's cross domain but a subdomain here + return false; + }; + + /** + * Add the transport to your public io.transports array. + * + * @api private + */ + + io.transports.push('htmlfile'); + +})( + 'undefined' != typeof io ? io.Transport : module.exports + , 'undefined' != typeof io ? io : module.parent.exports +); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io, global) { + + /** + * Expose constructor. + */ + + exports['xhr-polling'] = XHRPolling; + + /** + * The XHR-polling transport uses long polling XHR requests to create a + * "persistent" connection with the server. + * + * @constructor + * @api public + */ + + function XHRPolling () { + io.Transport.XHR.apply(this, arguments); + }; + + /** + * Inherits from XHR transport. + */ + + io.util.inherit(XHRPolling, io.Transport.XHR); + + /** + * Merge the properties from XHR transport + */ + + io.util.merge(XHRPolling, io.Transport.XHR); + + /** + * Transport name + * + * @api public + */ + + XHRPolling.prototype.name = 'xhr-polling'; + + /** + * Establish a connection, for iPhone and Android this will be done once the page + * is loaded. + * + * @returns {Transport} Chaining. + * @api public + */ + + XHRPolling.prototype.open = function () { + var self = this; + + io.Transport.XHR.prototype.open.call(self); + return false; + }; + + /** + * Starts a XHR request to wait for incoming messages. + * + * @api private + */ + + function empty () {}; + + XHRPolling.prototype.get = function () { + if (!this.open) return; + + var self = this; + + function stateChange () { + if (this.readyState == 4) { + this.onreadystatechange = empty; + + if (this.status == 200) { + self.onData(this.responseText); + self.get(); + } else { + self.onClose(); + } + } + }; + + function onload () { + this.onload = empty; + this.onerror = empty; + self.onData(this.responseText); + self.get(); + }; + + function onerror () { + self.onClose(); + }; + + this.xhr = this.request(); + + if (global.XDomainRequest && this.xhr instanceof XDomainRequest) { + this.xhr.onload = onload; + this.xhr.onerror = onerror; + } else { + this.xhr.onreadystatechange = stateChange; + } + + this.xhr.send(null); + }; + + /** + * Handle the unclean close behavior. + * + * @api private + */ + + XHRPolling.prototype.onClose = function () { + io.Transport.XHR.prototype.onClose.call(this); + + if (this.xhr) { + this.xhr.onreadystatechange = this.xhr.onload = this.xhr.onerror = empty; + try { + this.xhr.abort(); + } catch(e){} + this.xhr = null; + } + }; + + /** + * Webkit based browsers show a infinit spinner when you start a XHR request + * before the browsers onload event is called so we need to defer opening of + * the transport until the onload event is called. Wrapping the cb in our + * defer method solve this. + * + * @param {Socket} socket The socket instance that needs a transport + * @param {Function} fn The callback + * @api private + */ + + XHRPolling.prototype.ready = function (socket, fn) { + var self = this; + + io.util.defer(function () { + fn.call(self); + }); + }; + + /** + * Add the transport to your public io.transports array. + * + * @api private + */ + + io.transports.push('xhr-polling'); + +})( + 'undefined' != typeof io ? io.Transport : module.exports + , 'undefined' != typeof io ? io : module.parent.exports + , this +); + +/** + * socket.io + * Copyright(c) 2011 LearnBoost + * MIT Licensed + */ + +(function (exports, io, global) { + /** + * There is a way to hide the loading indicator in Firefox. If you create and + * remove a iframe it will stop showing the current loading indicator. + * Unfortunately we can't feature detect that and UA sniffing is evil. + * + * @api private + */ + + var indicator = global.document && "MozAppearance" in + global.document.documentElement.style; + + /** + * Expose constructor. + */ + + exports['jsonp-polling'] = JSONPPolling; + + /** + * The JSONP transport creates an persistent connection by dynamically + * inserting a script tag in the page. This script tag will receive the + * information of the Socket.IO server. When new information is received + * it creates a new script tag for the new data stream. + * + * @constructor + * @extends {io.Transport.xhr-polling} + * @api public + */ + + function JSONPPolling (socket) { + io.Transport['xhr-polling'].apply(this, arguments); + + this.index = io.j.length; + + var self = this; + + io.j.push(function (msg) { + self._(msg); + }); + }; + + /** + * Inherits from XHR polling transport. + */ + + io.util.inherit(JSONPPolling, io.Transport['xhr-polling']); + + /** + * Transport name + * + * @api public + */ + + JSONPPolling.prototype.name = 'jsonp-polling'; + + /** + * Posts a encoded message to the Socket.IO server using an iframe. + * The iframe is used because script tags can create POST based requests. + * The iframe is positioned outside of the view so the user does not + * notice it's existence. + * + * @param {String} data A encoded message. + * @api private + */ + + JSONPPolling.prototype.post = function (data) { + var self = this + , query = io.util.query( + this.socket.options.query + , 't='+ (+new Date) + '&i=' + this.index + ); + + if (!this.form) { + var form = document.createElement('form') + , area = document.createElement('textarea') + , id = this.iframeId = 'socketio_iframe_' + this.index + , iframe; + + form.className = 'socketio'; + form.style.position = 'absolute'; + form.style.top = '0px'; + form.style.left = '0px'; + form.style.display = 'none'; + form.target = id; + form.method = 'POST'; + form.setAttribute('accept-charset', 'utf-8'); + area.name = 'd'; + form.appendChild(area); + document.body.appendChild(form); + + this.form = form; + this.area = area; + } + + this.form.action = this.prepareUrl() + query; + + function complete () { + initIframe(); + self.socket.setBuffer(false); + }; + + function initIframe () { + if (self.iframe) { + self.form.removeChild(self.iframe); + } + + try { + // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) + iframe = document.createElement('