# HG changeset patch
# User Thierry Florac
# Date 1441200715 -7200
# Node ID fd39db613f8b0915e3b5b941d84ded68f5a83cd9
First release
diff -r 000000000000 -r fd39db613f8b src/pyams_media/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/__init__.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+from pyramid.i18n import TranslationStringFactory
+_ = TranslationStringFactory('pyams_media')
+
+
+def includeme(config):
+ """Pyramid include"""
+
+ from .include import include_package
+ include_package(config)
diff -r 000000000000 -r fd39db613f8b src/pyams_media/converter.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/converter.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,189 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import mimetypes
+
+from io import StringIO
+from tempfile import NamedTemporaryFile
+
+# import interfaces
+from pyams_media.interfaces import IMediaVideoConverter, IMediaAudioConverter, IMediaConversionUtility, IMediaConverter
+
+# import packages
+from pyams_media.ffdocument import FFDocument
+from pyams_utils.list import unique
+from pyams_utils.registry import utility_config, get_utilities_for, query_utility
+from zope.interface import implementer
+from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm, getVocabularyRegistry
+
+from pyams_media import _
+
+
+class BaseMediaConverter(object):
+ """Base media converter"""
+
+ format = None
+ require_temp_file = False
+
+ def require_input_file(self, media):
+ """Check if a physical file is required to handle conversion"""
+ return media.content_type == b'video/quicktime'
+
+ def convert(self, media):
+ """Convert media"""
+ if self.require_input_file(media):
+ input = NamedTemporaryFile(prefix='input_', suffix=mimetypes.guess_extension(media.contentType))
+ if isinstance(media, str):
+ input.write(media)
+ else:
+ input.write(media.data)
+ input.file.flush()
+ document = FFDocument(input.name)
+ else:
+ if isinstance(media, str):
+ media = StringIO(media)
+ document = FFDocument(media)
+ self.add_filters(document)
+ for loop in self.get_conversion_loop(document):
+ if self.require_temp_file:
+ output = NamedTemporaryFile(prefix='media_', suffix='.%s' % self.format)
+ document.get_output(self.format, target=output.name)
+ output.file.seek(0)
+ yield loop, output.file.read()
+ else:
+ yield loop, document.get_output(self.format)
+
+ def add_filters(self, document):
+ pass
+
+ def get_conversion_loop(self, document):
+ yield None
+
+
+#
+# Audio converters
+#
+
+@implementer(IMediaAudioConverter)
+class BaseAudioConverter(BaseMediaConverter):
+ """Base media converter"""
+
+
+@utility_config(name='audio/wav', provides=IMediaConverter)
+class WavAudioConverter(BaseAudioConverter):
+ """Default WAV media converter"""
+
+ label = _("WAV audio converter")
+ format = 'wav'
+
+
+@utility_config(name='audio/mpeg', provides=IMediaConverter)
+class Mp3AudioConverter(BaseAudioConverter):
+ """Default MP3 media converter"""
+
+ label = _("MP3 audio converter")
+ format = 'mp3'
+
+
+@utility_config(name='audio/ogg', provides=IMediaConverter)
+class OggAudioConverter(BaseAudioConverter):
+ """Default OGG audio converter"""
+
+ label = _("OGG audio converter")
+ format = 'ogg'
+
+
+class AudioConvertersVocabulary(SimpleVocabulary):
+ """Audio converters vocabulary"""
+
+ def __init__(self, context=None):
+ terms = [SimpleTerm(name, title=util.label)
+ for name, util in unique(get_utilities_for(IMediaConverter))
+ if IMediaAudioConverter.providedBy(util)]
+ super(AudioConvertersVocabulary, self).__init__(terms)
+
+getVocabularyRegistry().register('PyAMS media audio converters', AudioConvertersVocabulary)
+
+
+#
+# Video converters
+#
+
+@implementer(IMediaVideoConverter)
+class BaseVideoConverter(BaseMediaConverter):
+ """Base video converter"""
+
+ def add_filters(self, document):
+ utility = query_utility(IMediaConversionUtility)
+ if utility is not None:
+ if utility.video_audio_sampling:
+ document.audiosampling(utility.video_audio_sampling)
+ if utility.video_audio_bitrate:
+ document.bitrate(utility.video_audio_bitrate)
+ if utility.video_quantisation:
+ document.quantizerscale(utility.video_quantisation)
+
+ def get_conversion_loop(self, document):
+ utility = query_utility(IMediaConversionUtility)
+ if utility is not None:
+ for size in utility.video_frame_size or ():
+ document.size(size)
+ yield size
+
+
+@utility_config(name='video/x-flv', provides=IMediaConverter)
+class FlvVideoConverter(BaseVideoConverter):
+ """Default FLV media converter"""
+
+ label = _("FLV (Flash Video) video converter")
+ format = 'flv'
+
+
+@utility_config(name='video/mp4', provides=IMediaConverter)
+class Mp4VideoConverter(BaseVideoConverter):
+ """Default MP4 media converter"""
+
+ label = _("MP4 (HTML5) video converter")
+ format = 'mp4'
+ require_temp_file = True
+
+
+@utility_config(name='video/ogg', provides=IMediaConverter)
+class OggVideoConverter(BaseVideoConverter):
+ """OGG media converter"""
+
+ label = _("OGG video converter")
+ format = 'ogg'
+
+
+@utility_config(name='video/webm', provides=IMediaConverter)
+class WebmVideoConverter(BaseVideoConverter):
+ """WebM Media converter"""
+
+ label = _("WebM video converter")
+ format = 'webm'
+
+
+class VideoConvertersVocabulary(SimpleVocabulary):
+ """Video converters vocabulary"""
+
+ def __init__(self, context=None):
+ terms = [SimpleTerm(name, title=util.label)
+ for name, util in unique(get_utilities_for(IMediaConverter))
+ if IMediaVideoConverter.providedBy(util)]
+ super(VideoConvertersVocabulary, self).__init__(terms)
+
+getVocabularyRegistry().register('PyAMS media video converters', VideoConvertersVocabulary)
diff -r 000000000000 -r fd39db613f8b src/pyams_media/doctests/README.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/doctests/README.txt Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,3 @@
+===================
+pyams_media package
+===================
diff -r 000000000000 -r fd39db613f8b src/pyams_media/ffbase.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/ffbase.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,614 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+# import standard library
+import json
+import logging
+logger = logging.getLogger('PyAMS (media)')
+
+import mimetypes
+import re
+import tempfile
+
+from os.path import dirname, basename
+from os import sep, remove
+from subprocess import Popen, PIPE
+
+# import interfaces
+from pyams_file.interfaces import IFile
+
+# import packages
+from pyams_file.file import get_magic_content_type
+from pyams_media.ffexception import FFException
+
+
+__all__ = ['FFmpeg', 'FFVideoEffect', 'FFAudioEffect']
+
+
+INPUT_BLOCK_SIZE = 1024 ** 2
+
+
+class FFmpeg(object):
+ """
+ FFmpeg Wrapper
+ """
+
+ # thanks to pyxcoder http://code.google.com/p/pyxcoder for
+ # the main idea
+ re_mainline = re.compile("^\s*Input #(\d+?), (.*?), from \'(.*?)\':$")
+ re_infoline = re.compile("^\s*Duration: (.*?), start: 0\.000000, bitrate: (\d+?) kb\/s$")
+ re_videoline = re.compile("^\s*Stream #(\d+:\d+?)\(?([A-Za-z]*)\)?: Video: (.*?), (.*?), (.*?), (.*?)$")
+ re_audioline = re.compile("^\s*Stream #(\d+:\d+?)\(?([A-Za-z]*)\)?: Audio: (.*?), (\d+?) Hz, (.*?), (.*?), (\d+?) kb\/s$")
+
+ def __init__(self, cmd="ffmpeg"):
+ self.__ffmpeg__ = cmd
+
+ def __exec__(self, *args):
+ """Build and execute a command line"""
+ cmdline = [self.__ffmpeg__]
+ if self.__ffmpeg__ == 'ffmpeg':
+ cmdline.append('-y')
+ use_stdin = None
+ for arg in args:
+ if IFile.providedBy(arg):
+ if len(args) == 2:
+ # FFmpeg can't get media info from an input pipe
+ # We have to write media content to temporary file
+ suffix = '.tmp'
+ content_type = get_magic_content_type(arg.data)
+ if content_type:
+ suffix = mimetypes.guess_extension(content_type) or suffix
+ output = tempfile.NamedTemporaryFile(prefix='media_', suffix=suffix)
+ output.write(arg.data)
+ output.file.flush()
+ cmdline.append(output.name)
+ else:
+ use_stdin = arg
+ cmdline.append('-')
+ elif hasattr(arg, 'read'): # StringIO or any file like object
+ if len(args) == 2:
+ # FFmpeg can't get media info from an input pipe
+ # We have to write media content to temporary file
+ arg.reset()
+ content_type = get_magic_content_type(arg.read(4096))
+ suffix = mimetypes.guess_extension(content_type) if content_type else '.tmp'
+ output = tempfile.NamedTemporaryFile(prefix='media_', suffix=suffix)
+ try:
+ arg.reset()
+ except:
+ pass
+ data = arg.read(INPUT_BLOCK_SIZE)
+ while data:
+ output.write(data)
+ data = arg.read(INPUT_BLOCK_SIZE)
+ output.file.flush()
+ cmdline.append(output.name)
+ else:
+ use_stdin = arg
+ cmdline.append('-')
+ else:
+ cmdline.append(arg)
+ logger.debug("Running FFmpeg command line: {0}".format(cmdline))
+ p = Popen(cmdline, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ if use_stdin is not None:
+ if IFile.providedBy(use_stdin):
+ return p.communicate(use_stdin.data)
+ else:
+ use_stdin.reset()
+ return p.communicate(use_stdin.read())
+ else:
+ return p.communicate()
+
+ def render(self, effectchain, output):
+ """Create a new file by chaining audio/video effects"""
+ inputs = []
+ cmds = [[]]
+ outputs = []
+ # we want to operate on more objects that use the same file
+ # source, So, we have to split the effect chain in various
+ # intermediate jobs, then rebuild all
+ for index, effect in enumerate(effectchain):
+ if index == 1 and not effect in inputs:
+ inputs.append(effect)
+ cmds[len(cmds)-1].append(effect)
+ else:
+ outputs.append("%s%s%s-%s" % (dirname(output), sep, len(cmds), basename(output)))
+ cmds.append([])
+ input = []
+ # prcessing intermediate outputs
+ for index, output in enumerate(outputs):
+ cmd = ["-y", ]
+ cmd.extend(inputs[index].cmdline())
+ cmd.append(output)
+ self.__exec__(*cmd)
+ # procesing final output
+ cmd = ["-y", ]
+ for index, output in enumerate(outputs):
+ doc = FFEffect(output)
+ if index == 0 and inputs[index].offset():
+ doc.offset(inputs[index].offset())
+ cmd.extend(doc.cmdline())
+ cmd.append(output)
+ self.__exec__(*cmd)
+ # removing intermediate outputs
+ for tmp in outputs:
+ remove(tmp)
+
+ def info(self, input):
+ """Retrieve file information parsing command output"""
+ metadata = []
+ if IFile.providedBy(input) or isinstance(input, str) or hasattr(input, 'read'):
+ input = [input, ]
+ for i in range(0, len(input) * 2, 2):
+ input.insert(i, "-i")
+ if self.__ffmpeg__ == 'ffprobe':
+ input.extend(['-show_streams', '-print_format', 'json'])
+ probe = self.__exec__(*input)[0] # stdout
+ metadata.extend(json.loads(probe.decode()).get('streams', []))
+ else:
+ lines = self.__exec__(*input)[1] # stderr
+ for line in lines.split(b'\n'):
+ if isinstance(line, bytes):
+ try:
+ line = line.decode()
+ except UnicodeDecodeError:
+ logger.debug("Unicode decode error: {0}".format(line))
+ continue
+ if FFmpeg.re_mainline.match(line):
+ clip, vtype, filename = FFmpeg.re_mainline.match(line).groups()
+ metadata.append({"vtype": vtype, "filename": filename, "video": [], "audio": []})
+ elif FFmpeg.re_infoline.match(line):
+ current = len(metadata) - 1
+ metadata[current]["duration"], metadata[current]["bitrate"] = FFmpeg.re_infoline.match(line).groups()
+ elif FFmpeg.re_audioline.match(line):
+ clip, lang, codec, freq, chan, freqbit, bitrate = FFmpeg.re_audioline.match(line).groups()
+ audiostream = {"codec": codec, "lang": lang, "freq": freq, "chan": chan, "freqbit": freqbit, "bitrate": bitrate}
+ metadata[len(metadata) - 1]["audio"].append(audiostream)
+ elif FFmpeg.re_videoline.match(line):
+ clip, lang, codec, pix_fmt, size, framerate = FFmpeg.re_videoline.match(line).groups()
+ size = size.split(" ")
+ videostream = {"codec": codec, "lang": lang, "pix_fmt": pix_fmt, "size": size, "framerate": framerate}
+ metadata[len(metadata) - 1]["video"].append(videostream)
+ return metadata
+
+
+class FFEffect:
+ """
+ effect for a specified input file
+ each "set" method has an unset_* method
+ to clear the effect of the former (e.g.
+ crop() and unset_crop() ), and a general
+ unset() method
+ """
+
+ def __init__(self, inputfile, **args):
+ self.__file__ = inputfile
+ for opt in args.keys():
+ if opt not in ["b", "vframes", "r", "s", "aspect", "croptop",
+ "cropbottom", "cropleft", "cropright", "padtop",
+ "padbottom", "padleft", "padright", "padcolor",
+ "vn", "bt", "maxrate", "minrate", "bufsize",
+ "vcodec", "sameq", "pass", "newvideo", "pix_fmt",
+ "sws_flag", "g", "intra", "vdt", "qscale",
+ "qmin", "qmax", "qdiff", "qblur", "qcomp", "lmin",
+ "lmax", "mblmin", "mblmax", "rc_init_cplx",
+ "b_qfactor", "i_qfactor", "b_qoffset",
+ "i_qoffset", "rc_eq", "rc_override", "me_method",
+ "dct_algo", "idct_algo", "er", "ec", "bf", "mbd",
+ "4mv", "part", "bug", "strict", "aic", "umv",
+ "deinterlace", "ilme", "psnr", "vhook", "top",
+ "dc", "vtag", "vbsf", "aframes", "ar", "ab", "ac",
+ "an", "acodec", "newaudio", "alang", "t",
+ "itsoffset", "ss", "dframes"]:
+ raise FFException("Error parsing option: %s" % opt)
+ self.__effects__ = args
+ self.__default__ = self.__effects__.copy()
+
+ def cmdline(self):
+ """ return a list of arguments """
+ cmd = ["-i", self.__file__]
+ for opt, value in self.__effects__.items():
+ cmd.append("-%s" % opt)
+ if value is not True:
+ cmd.append("%s" % value)
+ return cmd
+
+ def get_output(self, format=None, target='-', get_stderr=False):
+ if (format is None) and hasattr(self, '__metadata__'):
+ format = self.__metadata__.get('vtype')
+ stdout, stderr = FFmpeg().__exec__(*self.cmdline() + ['-f', format, target])
+ return (stdout, stderr) if get_stderr else stdout
+
+ def restore(self):
+ """
+ restore initial settings
+ """
+ self.__effects__ = self.__default__.copy()
+
+ def unset(self):
+ """
+ clear settings
+ """
+ self.__effects__ = {}
+
+ def duration(self, t=None):
+ """ restrict transcode sequence to duration specified """
+ if t:
+ self.__effects__["t"] = float(t)
+ return self.__effects__.get("t")
+
+ def unset_duration(self):
+ del self.__effects__["duration"]
+
+ def seek(self, ss=None):
+ """ seek to time position in seconds """
+ if ss:
+ self.__effects__["ss"] = float(ss)
+ return self.__effects__.get("ss")
+
+ def unset_seek(self):
+ del self.__effects__["ss"]
+
+ def offset(self, itsoffset=None):
+ """ Set the input time offset in seconds """
+ if itsoffset:
+ self.__effects__["itsoffset"] = itsoffset
+ return self.__effects__.get("itsoffset")
+
+ def unset_offset(self):
+ del self.__effects__["itsoffset"]
+
+ def dframes(self, dframes=None):
+ """ number of data frames to record """
+ if dframes:
+ self.__effects__["dframes"] = dframes
+ return self.__effects__.get("dframes")
+
+ def unset_dframes(self):
+ del self.__effects__["dframes"]
+
+
+class FFVideoEffect(FFEffect):
+ """
+ video effect
+ """
+
+ def __init__(self, inputfile=None, **args):
+ FFEffect.__init__(self, inputfile, **args)
+
+ def bitrate(self, b=None):
+ """ set video bitrate """
+ if b:
+ self.__effects__["b"] = "%sk" % int(b)
+ return self.__effects__.get("b")
+
+ def unset_bitrate(self):
+ del self.__effects__["b"]
+
+ def vframes(self, vframes=None):
+ """ set number of video frames to record """
+ if vframes:
+ self.__effects__["vframes"] = int(vframes)
+ return self.__effects__.get("vframes")
+
+ def unset_vframes(self):
+ del self.__effects__["vframes"]
+
+ def rate(self, r=None):
+ """ set frame rate """
+ if r:
+ self.__effects__["r"] = int(r)
+ return self.__effects__.get("r")
+
+ def unset_rate(self):
+ del self.__effects__["r"]
+
+ def size(self, s=None):
+ """ set frame size """
+ if s in ["sqcif", "qcif", "cif", "4cif", "qqvga", "qvga", "vga", "svga",
+ "xga", "uxga", "qxga", "sxga", "qsxga", "hsxga", "wvga", "wxga",
+ "wsxga", "wuxga", "wqxga", "wqsxga", "wquxga", "whsxga",
+ "whuxga", "cga", "ega", "hd480", "hd720", "hd1080"]:
+ self.__effects__["s"] = s
+ elif s:
+ wh = s.split("x")
+ if len(wh) == 2 and int(wh[0]) and int(wh[1]):
+ self.__effects__["s"] = s
+ else:
+ raise FFException("Error parsing option: size")
+ return self.__effects__.get("s")
+
+ def unset_size(self):
+ del self.__effects__["s"]
+
+ def aspect(self, aspect=None):
+ """ set aspect ratio """
+ if aspect:
+ self.__effects__["aspect"] = aspect
+ return self.__effects__.get("aspect")
+
+ def unset_aspect(self):
+ del self.__effects__["aspect"]
+
+ def crop(self, top=0, bottom=0, left=0, right=0):
+ """ set the crop size """
+ if top % 2:
+ top = top - 1
+ if bottom % 2:
+ bottom = bottom - 1
+ if left % 2:
+ left = left - 1
+ if right % 2:
+ right = right - 1
+ if top:
+ self.__effects__["croptop"] = top
+ if bottom:
+ self.__effects__["cropbottom"] = bottom
+ if left:
+ self.__effects__["cropleft"] = left
+ if right:
+ self.__effects__["cropright"] = right
+ return self.__effects__.get("croptop"), self.__effects__.get("cropbottom"), self.__effects__.get("cropleft"), self.__effects__.get("cropright")
+
+ def unset_crop(self):
+ del self.__effects__["croptop"]
+ del self.__effects__["cropbottom"]
+ del self.__effects__["cropleft"]
+ del self.__effects__["cropright"]
+
+ def pad(self, top=0, bottom=0, left=0, right=0, color="000000"):
+ """ set the pad band size and color as hex value """
+ if top:
+ self.__effects__["padtop"] = top
+ if bottom:
+ self.__effects__["padbottom"] = bottom
+ if left:
+ self.__effects__["padleft"] = left
+ if right:
+ self.__effects__["padright"] = right
+ if color:
+ self.__effects__["padcolor"] = color
+ return self.__effects__.get("padtop"), self.__effects__.get("padbottom"), self.__effects__.get("padleft"), self.__effects__.get("padright"), self.__effects__.get("padcolor")
+
+ def unset_pad(self):
+ del self.__effects__["padtop"]
+ del self.__effects__["padbottom"]
+ del self.__effects__["padleft"]
+ del self.__effects__["padright"]
+
+ def vn(self):
+ """ disable video recording """
+ self.__effects__["vn"] = True
+
+ def unset_vn(self):
+ del self.__effects__["vn"]
+
+ def bitratetolerance(self, bt=None):
+ """ set bitrate tolerance """
+ if bt:
+ self.__effects__["bt"] = "%sk" % int(bt)
+ return self.__effects__.get("bt")
+
+ def unset_bitratetolerance(self):
+ del self.__effects__["bt"]
+
+ def bitraterange(self, minrate=None, maxrate=None):
+ """ set min/max bitrate (bit/s) """
+ if minrate or maxrate and not self.__effects__["bufsize"]:
+ self.__effects__["bufsize"] = 4096
+ if minrate:
+ self.__effects__["minrate"] = minrate
+ if maxrate:
+ self.__effects__["maxrate"] = maxrate
+
+ return self.__effects__.get("minrate"), self.__effects__.get("maxrate")
+
+ def unset_bitraterange(self):
+ del self.__effects__["maxrate"]
+ del self.__effects__["minrate"]
+
+ def bufsize(self, bufsize=4096):
+ """ set buffer size (bits) """
+ self.__effects__["bufsize"] = int(bufsize)
+ return self.__effects__["bufsize"]
+
+ def unset_bufsize(self):
+ del self.__effects__["bufsize"]
+
+ def vcodec(self, vcodec="copy"):
+ """ set video codec """
+ self.__effects__["vcodec"] = vcodec
+ return self.__effects__["vcodec"]
+
+ def unset_vcodec(self):
+ del self.__effects__["vcodec"]
+
+ def sameq(self):
+ """ use same video quality as source """
+ self.__effects__["sameq"] = True
+
+ def unset_sameq(self):
+ del self.__effects__["sameq"]
+
+ def passenc(self, p=1):
+ """ select pass number (1 or 2)"""
+ self.__effects__["pass"] = (int(p) % 3 + 1) % 2 + 1 #!!!
+ return self.__effects__["pass"]
+
+ def unset_passenc(self):
+ del self.__effects__["pass"]
+
+ def pixelformat(self, p=None):
+ """ set pixelformat """
+ if p:
+ self.__effects__["pix_fmt"] = p
+ return self.__effects__.get("pix_fmt")
+
+ def unset_pixelformat(self):
+ del self.__effects__["pix_fmt"]
+
+ #TODO: sws_flag
+
+ def picturesize(self, gop=None):
+ """ set of group pictures size """
+ if gop:
+ self.__effects__["gop"] = int(gop)
+ return self.__effects__.get("gop")
+
+ def unset_picturesize(self):
+ del self.__effects__["gop"]
+
+ def intra(self):
+ """ use only intra frames """
+ self.__effects__["intra"] = True
+
+ def unset_intra(self):
+ del self.__effects__["intra"]
+
+ def vdthreshold(self, vdt=None):
+ """ discard threshold """
+ if vdt:
+ self.__effects__["vdt"] = int(vdt)
+ return self.__effects__.get("vdt")
+
+ def unset_vdthreshold(self):
+ del self.__effects__["vdt"]
+
+ def quantizerscale(self, qscale=None):
+ """ Fixed quantizer scale """
+ if qscale:
+ self.__effects__["qscale"] = int(qscale)
+ return self.__effects__.get("qscale")
+
+ def unset_quantizerscale(self):
+ del self.__effects__["qscale"]
+
+ def quantizerrange(self, qmin=None, qmax=None, qdiff=None):
+ """ define min/max quantizer scale """
+ if qdiff:
+ self.__effects__["qdiff"] = int(qdiff)
+ else:
+ if qmin:
+ self.__effects__["qmin"] = int(qmin)
+ if qmax:
+ self.__effects__["qmax"] = int(qmax)
+ return self.__effects__.get("qmin"), self.__effects__.get("qmax"), self.__effects__.get("qdiff"),
+
+ def unset_quantizerrange(self):
+ del self.__effects__["qdiff"]
+
+ def quantizerblur(self, qblur=None):
+ """ video quantizer scale blur """
+ if qblur:
+ self.__effects__["qblur"] = float(qblur)
+ return self.__effects__.get("qblur")
+
+ def unset_quantizerblur(self):
+ del self.__effects__["qblur"]
+
+ def quantizercompression(self, qcomp=0.5):
+ """ video quantizer scale compression """
+ self.__effects__["qcomp"] = float(qcomp)
+ return self.__effects__["qcomp"]
+
+ def unset_quantizercompression(self):
+ del self.__effects__["qcomp"]
+
+ def lagrangefactor(self, lmin=None, lmax=None):
+ """ min/max lagrange factor """
+ if lmin:
+ self.__effects__["lmin"] = int(lmin)
+ if lmax:
+ self.__effects__["lmax"] = int(lmax)
+ return self.__effects__.get("lmin"), self.__effects__.get("lmax")
+
+ def unset_lagrangefactor(self):
+ del self.__effects__["lmin"]
+ del self.__effects__["lmax"]
+
+ def macroblock(self, mblmin=None, mblmax=None):
+ """ min/max macroblock scale """
+ if mblmin:
+ self.__effects__["mblmin"] = int(mblmin)
+ if mblmax:
+ self.__effects__["mblmax"] = int(mblmax)
+ return self.__effects__.get("mblmin"), self.__effects__.get("mblmax")
+
+ def unset_macroblock(self):
+ del self.__effects__["mblmin"]
+ del self.__effects__["mblmax"]
+
+ #TODO: read man pages !
+
+
+class FFAudioEffect(FFEffect):
+ """
+ Audio effect
+ """
+
+ def __init__(self, inputfile, **args):
+ FFEffect.__init__(self, inputfile, **args)
+
+ def aframes(self, aframes=None):
+ """ set number of audio frames to record """
+ if aframes:
+ self.__effects__["aframes"] = int(aframes)
+ return self.__effects__.get("aframes")
+
+ def unset_aframes(self):
+ del self.__effects__["aframes"]
+
+ def audiosampling(self, ar=44100):
+ """ set audio sampling frequency (Hz)"""
+ self.__effects__["ar"] = int(ar)
+ return self.__effects__["ar"]
+
+ def unset_audiosampling(self):
+ del self.__effects__["ar"]
+
+ def audiobitrate(self, ab=64):
+ """ set audio bitrate (kbit/s)"""
+ self.__effects__["ab"] = int(ab)
+ return self.__effects__["ab"]
+
+ def unset_audiobitrate(self):
+ del self.__effects__["ab"]
+
+ def audiochannels(self, ac=1):
+ """ set number of audio channels """
+ self.__effects__["ac"] = int(ac)
+ return self.__effects__["ac"]
+
+ def unset_audiochannels(self):
+ del self.__effects__["ac"]
+
+ def audiorecording(self):
+ """ disable audio recording """
+ self.__effects__["an"] = True
+
+ def unset_audiorecording(self):
+ del self.__effects__["an"]
+
+ def acodec(self, acodec="copy"):
+ """ select audio codec """
+ self.__effects__["acodec"] = acodec
+ return self.__effects__["acodec"]
+
+ def unset_acodec(self):
+ del self.__effects__["acodec"]
+
+ def newaudio(self):
+ """ add new audio track """
+ self.__effects__["newaudio"] = True
+
+ def unset_newaudio(self):
+ del self.__effects__["newaudio"]
diff -r 000000000000 -r fd39db613f8b src/pyams_media/ffdocument.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/ffdocument.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,224 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+# import standard library
+
+# import interfaces
+
+# import packages
+from pyams_media.ffbase import FFVideoEffect, FFAudioEffect, FFmpeg
+from pyams_media.interfaces import IMediaInfo
+
+
+class FFDocument(FFVideoEffect, FFAudioEffect):
+ """
+ audio/video document. A FFDocument describe a higer level action set
+ combining several FF[Audio|Video]Effect methods.
+ """
+
+ def __init__(self, file, metadata=None, effects={}):
+ """
+ x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+ """
+ FFAudioEffect.__init__(self, file)
+ FFVideoEffect.__init__(self, file, **effects)
+ if not metadata:
+ info = IMediaInfo(file, None)
+ if info is not None:
+ self.__metadata__ = info
+ else:
+ info = FFmpeg('ffprobe').info(file)
+ if info:
+ self.__metadata__ = info
+ else:
+ self.__metadata__ = []
+ else:
+ self.__metadata__ = metadata
+
+ def get_stream_info(self, codec_type=None):
+ """Get metadata info for given stream"""
+ for stream in self.__metadata__:
+ if (not codec_type) or (stream.get('codec_type') == codec_type):
+ return stream
+
+ def __tlen__(self):
+ """
+ return time length
+ """
+ stream = self.get_stream_info()
+ if stream is not None:
+ t = self.__timeparse__(float(stream["duration"]))
+ if self.seek():
+ t = t - self.seek()
+ if self.duration():
+ t = t - (t - self.duration())
+ return t
+
+ def __timereference__(self, reference, time):
+ if isinstance(time, str):
+ if '%' in time:
+ parsed = (reference / 100.0) * int(time.split("%")[0])
+ else:
+ elts = time.split(':')
+ if len(elts) == 3:
+ hhn, mmn, ssn = [float(i) for i in elts]
+ parsed = hhn * 3600 + mmn * 60 + ssn
+ elif len(elts) == 2:
+ hhn, mmn = [float(i) for i in elts]
+ ssn = 0
+ parsed = hhn * 3600 + mmn * 60 + ssn
+ else:
+ parsed = 0
+ else:
+ parsed = time
+ return parsed
+
+ def __timeparse__(self, time):
+ if isinstance(time, str):
+ if ':' in time:
+ hh, mm, ss = [float(i) for i in time.split(":")]
+ return hh * 3600 + mm * 60 + ss
+ elif isinstance(time, float):
+ return time
+
+ def __clone__(self):
+ return FFDocument(self.__file__, self.__metadata__.copy(), self.__effects__.copy())
+
+ def resample(self, width=0, height=0, vstream=0):
+ """Adjust video dimensions. If one dimension is specified, the re-sampling is proportional
+ """
+ stream = self.get_stream_info('video')
+ if stream is not None:
+ w, h = stream['width'], stream['height']
+ if not width:
+ width = int(w * (float(height) / h))
+ elif not height:
+ height = int(h * (float(width) / w))
+ elif not width and height:
+ return
+
+ new = self.__clone__()
+ if width < w:
+ cropsize = (w - width) / 2
+ new.crop(0, 0, cropsize, cropsize)
+ elif width > w:
+ padsize = (width - w) / 2
+ new.pad(0, 0, padsize, padsize)
+ if height < h:
+ cropsize = (h - height) / 2
+ new.crop(cropsize, cropsize, 0, 0)
+ elif height > h:
+ padsize = (height - h) / 2
+ new.pad(padsize, padsize, 0, 0)
+ return new
+
+ def resize(self, width=0, height=0, vstream=0):
+ """Resize video dimensions. If one dimension is specified, the re-sampling is proportional
+
+ Width and height can be pixel or % (not mixable)
+ """
+ stream = self.get_stream_info('video')
+ if stream is not None:
+ w, h = stream['width'], stream['height']
+ if type(width) == str or type(height) == str:
+ if not width:
+ width = height = int(height.split("%")[0])
+ elif not height:
+ height = width = int(width.split("%")[0])
+ elif not width and height:
+ return
+ elif width and height:
+ width = int(width.split("%")[0])
+ height = int(height.split("%")[0])
+ size = "%sx%s" % (int(w / 100.0 * width), int(h / 100.0 * height))
+ else:
+ if not width:
+ width = int(w * (float(height) / h))
+ elif not height:
+ height = int(h * (float(width) / w))
+ elif not width and height:
+ return
+ size = "%sx%s" % (width, height)
+ new = self.__clone__()
+ new.size(size)
+ return new
+
+ def split(self, time):
+ """Return a tuple of FFDocument splitted at a specified time.
+
+ Allowed formats: %, sec, hh:mm:ss.mmm
+ """
+ stream = self.get_stream_info()
+ if stream is not None:
+ sectime = self.__timeparse__(stream["duration"])
+ if self.duration():
+ sectime = sectime - (sectime - self.duration())
+ if self.seek():
+ sectime = sectime - self.seek()
+ cut = self.__timereference__(sectime, time)
+
+ first = self.__clone__()
+ second = self.__clone__()
+ first.duration(cut)
+ second.seek(cut + 0.001)
+ return first, second
+
+ def ltrim(self, time):
+ """Trim leftmost side (from start) of the clip"""
+ stream = self.get_stream_info()
+ if stream is not None:
+ sectime = self.__timeparse__(stream["duration"])
+ if self.duration():
+ sectime = sectime - (sectime - self.duration())
+ if self.seek():
+ sectime = sectime - self.seek()
+ trim = self.__timereference__(sectime, time)
+ new = self.__clone__()
+ if self.seek():
+ new.seek(self.seek() + trim)
+ else:
+ new.seek(trim)
+ return new
+
+ def rtrim(self, time):
+ """Trim rightmost side (from end) of the clip"""
+ stream = self.get_stream_info()
+ if stream is not None:
+ sectime = self.__timeparse__(self.__metadata__["duration"])
+ if self.duration():
+ sectime = sectime - (sectime - self.duration())
+ if self.seek():
+ sectime = sectime - self.seek()
+ trim = self.__timereference__(sectime, time)
+ new = self.__clone__()
+ new.duration(trim)
+ return new
+
+ def trim(self, left, right):
+ """Left and right trim (actually calls ltrim and rtrim)"""
+ return self.__clone__().ltrim(left).rtrim(right)
+
+ def chainto(self, ffdoc):
+ """Prepare to append at the end of another movie clip"""
+ offset = 0
+ if ffdoc.seek():
+ offset = ffdoc.seek()
+ if ffdoc.duration():
+ offset = offset + ffdoc.seek()
+ if ffdoc.offset():
+ offset = offset + ffdoc.offset()
+
+ new = self.__clone__()
+ new.offset(offset)
+ return new
+
+ #TODO: more and more effects!!!
diff -r 000000000000 -r fd39db613f8b src/pyams_media/ffexception.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/ffexception.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,8 @@
+
+class FFException(Exception):
+
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
diff -r 000000000000 -r fd39db613f8b src/pyams_media/include.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/include.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import atexit
+import logging
+logger = logging.getLogger('PyAMS (media)')
+
+import sys
+
+# import interfaces
+from pyams_media.interfaces import CONVERTER_HANDLER_KEY, CONVERTER_NAME
+from pyams_utils.interfaces import PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME
+
+# import packages
+from pyams_media.process import MediaConversionProcess, MediaConversionMessageHandler
+from pyams_utils.registry import set_local_registry
+from pyams_utils.zodb import get_connection_from_settings
+from pyams_zmq.process import process_exit_func
+
+
+def include_package(config):
+ """Pyramid include"""
+
+ # add translations
+ config.add_translation_dirs('pyams_media:locales')
+
+ # load registry components
+ try:
+ import pyams_zmi
+ except ImportError:
+ config.scan(ignore='pyams_media.zmi')
+ else:
+ config.scan()
+
+ # check for upgrade mode
+ if sys.argv[0].endswith('pyams_upgrade'):
+ return
+
+ settings = config.registry.settings
+ start_handler = settings.get(CONVERTER_HANDLER_KEY, False)
+ if start_handler:
+ # get database connection
+ connection = get_connection_from_settings(settings)
+ root = connection.root()
+ # get application
+ application_name = settings.get(PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME)
+ application = root.get(application_name)
+ process = None
+ if application is not None:
+ sm = application.getSiteManager()
+ set_local_registry(sm)
+ try:
+ conversion_util = sm.get(CONVERTER_NAME)
+ if conversion_util is not None:
+ # create medias converter process
+ process = MediaConversionProcess(start_handler, MediaConversionMessageHandler, config.registry)
+ logger.debug('Starting medias conversion process {0!r}...'.format(process))
+ process.start()
+ if process.is_alive():
+ atexit.register(process_exit_func, process=process)
+ finally:
+ if process and not process.is_alive():
+ process.terminate()
+ process.join()
+ set_local_registry(None)
diff -r 000000000000 -r fd39db613f8b src/pyams_media/interfaces/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/interfaces/__init__.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,198 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+from collections import OrderedDict
+
+# import interfaces
+
+# import packages
+from zope.interface import Interface, Attribute
+from zope.schema import List, Choice, Int
+from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
+
+from pyams_media import _
+
+
+#
+# Medias interfaces
+#
+
+CONVERTER_NAME = 'Medias converter'
+CONVERTER_HANDLER_KEY = 'pyams_media.tcp_handler'
+
+CUSTOM_AUDIO_TYPES = (b'application/ogg',)
+CUSTOM_VIDEO_TYPES = ()
+
+
+class IMediaInfo(Interface):
+ """Media file info interface"""
+
+ infos = Attribute("Complete media info dictionary")
+
+
+#
+# Media converter utility interfaces
+#
+
+class IMediaConverter(Interface):
+ """Media converter interface"""
+
+ label = Attribute("Media converter label")
+
+ format = Attribute("Media converter target format")
+
+ def convert(self, media):
+ """Convert media to format handled by given converter"""
+
+
+class IMediaVideoConverter(IMediaConverter):
+ """Media video converter"""
+
+
+class IMediaAudioConverter(IMediaConverter):
+ """Media audio converter"""
+
+
+#
+# Media conversions adapter interfaces
+#
+
+class IMediaConversions(Interface):
+ """Media conversions interface"""
+
+ def add_conversion(self, conversion, format, extension=None, width=None):
+ """Add given conversion to media"""
+
+ def has_conversion(self, formats):
+ """Check if one of given formats is available in conversions"""
+
+ def get_conversion(self, format):
+ """Get converted media for given format and width"""
+
+ def get_conversions(self):
+ """Get current list of media conversions"""
+
+
+class IMediaConversion(Interface):
+ """Marker interface for already converted media files"""
+
+
+#
+# Media conversion utility configuration interface
+#
+
+VIDEO_FRAME_SIZE = {'sqcif': (128, 96),
+ 'qqvga': (160, 120),
+ 'qcif': (176, 144),
+ 'cga': (320, 200),
+ 'qvga': (320, 240),
+ 'cif': (352, 288),
+ 'vga': (640, 480),
+ '4cif': (704, 576),
+ 'svga': (800, 600),
+ 'wvga': (852, 480),
+ 'hd480': (852, 480),
+ 'hd720': (1280, 720),
+ 'xga': (1024, 768),
+ 'sxga': (1280, 1024),
+ 'wxga': (1366, 768),
+ 'uxga': (1600, 1200),
+ 'wsxga': (1600, 1024),
+ 'hd1080': (1920, 1080),
+ 'wuxga': (1920, 1200),
+ 'qxga': (2048, 1536),
+ 'wqxga': (2560, 1600),
+ 'qsxga': (2560, 2048),
+ 'wqsxga': (3200, 2048),
+ 'wquxga': (3840, 2400),
+ 'hsxga': (5120, 4096),
+ 'whsxga': (6400, 4096),
+ 'whuxga': (7680, 4800)}
+
+
+VIDEO_FRAME_SIZE_NAMES = OrderedDict((('sqcif', "sqcif (128x96)"),
+ ('qqvga', "qqvga (160x120)"),
+ ('qcif', "qcif (176x144)"),
+ ('cga', "cga (320x200)"),
+ ('qvga', "qvga (320x240)"),
+ ('cif', "cif (352x288)"),
+ ('vga', "vga (640x480)"),
+ ('4cif', "4cif (704x576)"),
+ ('svga', "svga (800x600)"),
+ ('wvga', "wvga (852x480)"),
+ ('hd480', "hd480 (852x480)"),
+ ('hd720', "hd720 (1280x720)"),
+ ('xga', "xga (1024x768)"),
+ ('sxga', "sxga (1280x1024)"),
+ ('wxga', "wxga (1366x768)"),
+ ('uxga', "uxga (1600x1200)"),
+ ('wsxga', "wsxga (1600x1024)"),
+ ('hd1080', "hd1080 (1920x1080)"),
+ ('wuxga', "wuxga (1920x1200)"),
+ ('qxga', "qxga (2048x1536)"),
+ ('wqxga', "wqxga (2560x1600)"),
+ ('qsxga', "qsxga (2560x2048)"),
+ ('wqsxga', "wqsxga (3200x2048)"),
+ ('wquxga', "wquxga (3840x2400)"),
+ ('hsxga', "hsxga (5120x4096)"),
+ ('whsxga', "whsxga (6400x4096)"),
+ ('whuxga', "whuxga (7680x4800)")))
+
+
+VIDEO_FRAME_SIZE_VOCABULARY = SimpleVocabulary([SimpleTerm(v, title=t) for v, t in VIDEO_FRAME_SIZE_NAMES.items()])
+
+
+class IMediaConversionUtility(Interface):
+ """Media conversion client interface"""
+
+ zeo_connection = Choice(title=_("ZEO connection name"),
+ description=_("Name of ZEO connection utility defining converter connection"),
+ required=False,
+ vocabulary="PyAMS ZEO connections")
+
+ video_formats = List(title=_("Video formats conversions"),
+ description=_("Published video files will be automatically converted to this format"),
+ value_type=Choice(vocabulary="PyAMS media video converters"),
+ required=False)
+
+ video_frame_size = List(title=_("Video frames size"),
+ description=_("Leave empty to keep original frame size..."),
+ required=True,
+ value_type=Choice(vocabulary=VIDEO_FRAME_SIZE_VOCABULARY))
+
+ video_audio_sampling = Int(title=_("Video audio frequency"),
+ description=_("A common value is 22050. Leave empty to keep original value."),
+ required=False)
+
+ video_audio_bitrate = Int(title=_("Video audio bitrate"),
+ description=_("In kilo-bytes per second. Leave empty to keep original value."),
+ required=False)
+
+ video_quantisation = Int(title=_("Video quantisation scale"),
+ description=_("Lower value indicates higher quality"),
+ required=False,
+ default=1)
+
+ audio_formats = List(title=_("Audio formats conversions"),
+ description=_("Published audio files will be automatically converted to this format"),
+ value_type=Choice(vocabulary="PyAMS media audio converters"),
+ required=False)
+
+ def check_media_conversion(self, media):
+ """Check if conversion is needed for given media"""
+
+ def convert(self, media, format):
+ """Convert given media to requested format"""
diff -r 000000000000 -r fd39db613f8b src/pyams_media/locales/fr/LC_MESSAGES/pyams_media.mo
Binary file src/pyams_media/locales/fr/LC_MESSAGES/pyams_media.mo has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/locales/fr/LC_MESSAGES/pyams_media.po
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/locales/fr/LC_MESSAGES/pyams_media.po Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,163 @@
+#
+# French translations for PACKAGE package
+# This file is distributed under the same license as the PACKAGE package.
+# Thierry Florac , 2015.
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE 1.0\n"
+"POT-Creation-Date: 2015-08-28 15:21+0200\n"
+"PO-Revision-Date: 2015-08-28 13:59+0200\n"
+"Last-Translator: Thierry Florac \n"
+"Language-Team: French\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Lingua 3.8\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: src/pyams_media/converter.py:89
+msgid "WAV audio converter"
+msgstr "Conversion audio WAV"
+
+#: src/pyams_media/converter.py:97
+msgid "MP3 audio converter"
+msgstr "Conversion audio MP3"
+
+#: src/pyams_media/converter.py:105
+msgid "OGG audio converter"
+msgstr "Conversion audio OGG"
+
+#: src/pyams_media/converter.py:151
+msgid "FLV (Flash Video) video converter"
+msgstr "Conversion vidéo FLV (Flash)"
+
+#: src/pyams_media/converter.py:159
+msgid "MP4 (HTML5) video converter"
+msgstr "Conversion vidéo MP4 (HTML5)"
+
+#: src/pyams_media/converter.py:168
+msgid "OGG video converter"
+msgstr "Conversion vidéo OGG"
+
+#: src/pyams_media/converter.py:176
+msgid "WebM video converter"
+msgstr "Conversion vidéo WebM"
+
+#: src/pyams_media/zmi/__init__.py:50
+msgid "Update medias converter properties"
+msgstr "Modifier les propriétés du convertisseur de médias"
+
+#: src/pyams_media/zmi/__init__.py:71
+msgid "Test process connection..."
+msgstr "Tester la connexion..."
+
+#: src/pyams_media/zmi/__init__.py:94
+msgid "Test medias converter process connection"
+msgstr "Tester la connexion au processus de conversion"
+
+#: src/pyams_media/zmi/__init__.py:81 src/pyams_media/zmi/video.py:71
+msgid "Close"
+msgstr "Fermer"
+
+#: src/pyams_media/zmi/__init__.py:82
+msgid "Test connection"
+msgstr "Tester la connexion"
+
+#: src/pyams_media/zmi/video.py:61
+msgid "Select thumbnail..."
+msgstr "Sélectionner l'illustration..."
+
+#: src/pyams_media/zmi/video.py:87
+msgid "Select video thumbnail"
+msgstr "Sélection de l'illustration"
+
+#: src/pyams_media/zmi/video.py:144
+msgid ""
+"You can play the video until you display the image you want.\n"
+"\n"
+"By pausing the video and clicking on ''Select thumbnail'' button, the "
+"selected frame will be used as\n"
+"video illustration."
+msgstr ""
+"Pour sélectionner l'illustration de cette vidéo, lancez sa lecture et au "
+"moment souhaité, mettez-la en pause.\n"
+"Le bouton ''Sélectionner cette illustration'' permet alors de générer "
+"l'image qui sera utilisée comme illustration."
+
+#: src/pyams_media/zmi/video.py:72
+msgid "Select thumbnail"
+msgstr "Sélectionner cette illustration"
+
+#: src/pyams_media/zmi/video.py:78
+msgid "Thumbnail timestamp"
+msgstr "Position de l'illustration"
+
+#: src/pyams_media/zmi/video.py:127
+msgid "Thumbnail selected successfully."
+msgstr "L'illustration a été générée avec succès."
+
+#: src/pyams_media/zmi/video.py:130
+msgid "An error occurred. No created thumbnail."
+msgstr "Une erreur est intervenue. L'illustration n'a pas pu être générée."
+
+#: src/pyams_media/interfaces/__init__.py:161
+msgid "ZEO connection name"
+msgstr "Connexion ZEO"
+
+#: src/pyams_media/interfaces/__init__.py:162
+msgid "Name of ZEO connection utility defining converter connection"
+msgstr "Nom de la connexion ZEO utilisée par le processus de conversion"
+
+#: src/pyams_media/interfaces/__init__.py:166
+msgid "Video formats conversions"
+msgstr "Formats de conversion vidéo"
+
+#: src/pyams_media/interfaces/__init__.py:167
+msgid "Published video files will be automatically converted to this format"
+msgstr "Les vidéos publiées seront automatiquement converties dans ces formats"
+
+#: src/pyams_media/interfaces/__init__.py:171
+msgid "Video frames size"
+msgstr "Taille de l'image"
+
+#: src/pyams_media/interfaces/__init__.py:172
+msgid "Leave empty to keep original frame size..."
+msgstr "Indiquez ici les différentes résolutions qui seront générées..."
+
+#: src/pyams_media/interfaces/__init__.py:176
+msgid "Video audio frequency"
+msgstr "Fréquence audio"
+
+#: src/pyams_media/interfaces/__init__.py:177
+msgid "A common value is 22050. Leave empty to keep original value."
+msgstr ""
+"Une valeur courante est 22050. Laissez cette zone vide pour garder la valeur "
+"de la vidéo d'origine."
+
+#: src/pyams_media/interfaces/__init__.py:180
+msgid "Video audio bitrate"
+msgstr "Débit vidéo"
+
+#: src/pyams_media/interfaces/__init__.py:181
+msgid "In kilo-bytes per second. Leave empty to keep original value."
+msgstr ""
+"En kilo-octets par seconde. Laissez cette zone vide pour garder la valeur de "
+"la vidéo d'origine."
+
+#: src/pyams_media/interfaces/__init__.py:184
+msgid "Video quantisation scale"
+msgstr "Quantification vidéo"
+
+#: src/pyams_media/interfaces/__init__.py:185
+msgid "Lower value indicates higher quality"
+msgstr "Une valeur faible indique une qualité plus élevée"
+
+#: src/pyams_media/interfaces/__init__.py:189
+msgid "Audio formats conversions"
+msgstr "Formats de conversion audio"
+
+#: src/pyams_media/interfaces/__init__.py:190
+msgid "Published audio files will be automatically converted to this format"
+msgstr ""
+"Les fichiers audios publiés seront automatiquement convertis dans ces formats"
diff -r 000000000000 -r fd39db613f8b src/pyams_media/locales/pyams_media.pot
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/locales/pyams_media.pot Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,153 @@
+#
+# SOME DESCRIPTIVE TITLE
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , 2015.
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE 1.0\n"
+"POT-Creation-Date: 2015-08-28 15:21+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Lingua 3.8\n"
+
+#: ./src/pyams_media/converter.py:89
+msgid "WAV audio converter"
+msgstr ""
+
+#: ./src/pyams_media/converter.py:97
+msgid "MP3 audio converter"
+msgstr ""
+
+#: ./src/pyams_media/converter.py:105
+msgid "OGG audio converter"
+msgstr ""
+
+#: ./src/pyams_media/converter.py:151
+msgid "FLV (Flash Video) video converter"
+msgstr ""
+
+#: ./src/pyams_media/converter.py:159
+msgid "MP4 (HTML5) video converter"
+msgstr ""
+
+#: ./src/pyams_media/converter.py:168
+msgid "OGG video converter"
+msgstr ""
+
+#: ./src/pyams_media/converter.py:176
+msgid "WebM video converter"
+msgstr ""
+
+#: ./src/pyams_media/zmi/__init__.py:50
+msgid "Update medias converter properties"
+msgstr ""
+
+#: ./src/pyams_media/zmi/__init__.py:71
+msgid "Test process connection..."
+msgstr ""
+
+#: ./src/pyams_media/zmi/__init__.py:94
+msgid "Test medias converter process connection"
+msgstr ""
+
+#: ./src/pyams_media/zmi/__init__.py:81 ./src/pyams_media/zmi/video.py:71
+msgid "Close"
+msgstr ""
+
+#: ./src/pyams_media/zmi/__init__.py:82
+msgid "Test connection"
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:61
+msgid "Select thumbnail..."
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:87
+msgid "Select video thumbnail"
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:144
+msgid ""
+"You can play the video until you display the image you want.\n"
+"\n"
+"By pausing the video and clicking on ''Select thumbnail'' button, the selected frame will be used as\n"
+"video illustration."
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:72
+msgid "Select thumbnail"
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:78
+msgid "Thumbnail timestamp"
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:127
+msgid "Thumbnail selected successfully."
+msgstr ""
+
+#: ./src/pyams_media/zmi/video.py:130
+msgid "An error occurred. No created thumbnail."
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:161
+msgid "ZEO connection name"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:162
+msgid "Name of ZEO connection utility defining converter connection"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:166
+msgid "Video formats conversions"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:167
+msgid "Published video files will be automatically converted to this format"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:171
+msgid "Video frames size"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:172
+msgid "Leave empty to keep original frame size..."
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:176
+msgid "Video audio frequency"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:177
+msgid "A common value is 22050. Leave empty to keep original value."
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:180
+msgid "Video audio bitrate"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:181
+msgid "In kilo-bytes per second. Leave empty to keep original value."
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:184
+msgid "Video quantisation scale"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:185
+msgid "Lower value indicates higher quality"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:189
+msgid "Audio formats conversions"
+msgstr ""
+
+#: ./src/pyams_media/interfaces/__init__.py:190
+msgid "Published audio files will be automatically converted to this format"
+msgstr ""
diff -r 000000000000 -r fd39db613f8b src/pyams_media/media.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/media.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,160 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+from mimetypes import guess_extension, guess_type
+
+# import interfaces
+from pyams_file.interfaces import IFile
+from pyams_media.interfaces import IMediaInfo, CUSTOM_AUDIO_TYPES, CUSTOM_VIDEO_TYPES, IMediaConversions, \
+ IMediaConversion, IMediaConversionUtility
+from transaction.interfaces import ITransactionManager
+from zope.annotation.interfaces import IAnnotations
+from zope.lifecycleevent.interfaces import IObjectAddedEvent
+
+# import packages
+from pyams_file.file import FileFactory
+from pyams_media.ffbase import FFmpeg
+from pyams_media.ffdocument import FFDocument
+from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.registry import query_utility
+from pyramid.events import subscriber
+from pyramid.threadlocal import get_current_registry
+from zope.container.folder import Folder
+from zope.interface import implementer, alsoProvides
+from zope.lifecycleevent import ObjectCreatedEvent
+from zope.location import locate
+from zope.traversing.interfaces import ITraversable
+
+
+#
+# Media infos
+#
+
+MEDIA_INFO_KEY = 'pyams_media.media.info'
+
+
+@adapter_config(context=IFile, provides=IMediaInfo)
+def MediaInfoFactory(context):
+ """Media info adapter"""
+ if not (context.content_type.startswith(b'audio/') or
+ context.content_type.startswith(b'video/') or
+ context.content_type in (CUSTOM_AUDIO_TYPES + CUSTOM_VIDEO_TYPES)):
+ return None
+ annotations = IAnnotations(context)
+ info = annotations.get(MEDIA_INFO_KEY)
+ if info is None:
+ info = annotations[MEDIA_INFO_KEY] = FFmpeg('ffprobe').info(context)
+ return info
+
+
+#
+# Media conversions
+#
+
+MEDIA_CONVERSIONS_KEY = 'pyams_media.media.conversions'
+
+
+@implementer(IMediaConversions)
+class MediaConversions(Folder):
+ """Media conversions"""
+
+ def add_conversion(self, conversion, format, extension=None, width=None):
+ target = FileFactory(conversion)
+ registry = get_current_registry()
+ registry.notify(ObjectCreatedEvent(target))
+ alsoProvides(target, IMediaConversion)
+ if extension is None:
+ extension = guess_extension(format)
+ target_name = '{name}{width}.{extension}'.format(name=target.content_type.decode().split('/', 1)[0]
+ if target.content_type else 'media',
+ width='-{0}'.format(width) if width else '',
+ extension=extension)
+ self[target_name] = target
+
+ def get_conversions(self):
+ context = self.__parent__
+ return [context] + list(self.values())
+
+ def get_conversion(self, name):
+ if '/' in name:
+ for conversion in self.get_conversions():
+ if conversion.content_type == name:
+ return conversion
+ return self.get(name)
+
+ def has_conversion(self, formats):
+ for conversion in self.get_conversions():
+ if conversion.content_type in formats:
+ return True
+ return False
+
+
+@adapter_config(context=IFile, provides=IMediaConversions)
+def MediaConversionsFactory(context):
+ """Media conversions factory"""
+ annotations = IAnnotations(context)
+ conversions = annotations.get(MEDIA_CONVERSIONS_KEY)
+ if conversions is None:
+ conversions = annotations[MEDIA_CONVERSIONS_KEY] = MediaConversions()
+ locate(conversions, context, '++conversions++')
+ return conversions
+
+
+@adapter_config(name='conversions', context=IFile, provides=ITraversable)
+class MediaConversionsTraverser(ContextAdapter):
+ """++conversions++ file traverser"""
+
+ def traverse(self, name, furtherpath=None):
+ return IMediaConversions(self.context)
+
+
+#
+# Media files events
+#
+
+def check_media_conversion(status, media):
+ if not status: # aborted transaction
+ return
+ converter = query_utility(IMediaConversionUtility)
+ if converter is not None:
+ converter.check_media_conversion(media)
+
+
+@subscriber(IObjectAddedEvent, context_selector=IFile)
+def handle_added_media(event):
+ """Handle added media file"""
+ media = event.object
+ # Don't convert images or already converted files!
+ if IMediaConversion.providedBy(media):
+ return
+ content_type = media.content_type.decode() if media.content_type else None
+ if (not content_type) or content_type.startswith('image/'):
+ return
+ # Try to use FFMpeg if content type is unknown...
+ media_type = content_type.startswith('audio/') or \
+ content_type.startswith('video/') or \
+ content_type in (CUSTOM_AUDIO_TYPES + CUSTOM_VIDEO_TYPES)
+ if not media_type:
+ document = FFDocument(media)
+ metadata = document.__metadata__
+ media_type = metadata.get('vtype')
+ if media_type:
+ ext = media_type.split('.')[0]
+ content_type = guess_type('media.{0}'.format(ext))[0]
+ if content_type is not None:
+ media.content_type = content_type
+ if media_type:
+ ITransactionManager(media).get().addAfterCommitHook(check_media_conversion, kws={'media': media})
diff -r 000000000000 -r fd39db613f8b src/pyams_media/process.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/process.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,151 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import logging
+logger = logging.getLogger('PyAMS (media)')
+import os
+import shutil
+
+from multiprocessing import Process
+from threading import Thread
+
+# import interfaces
+from pyams_media.interfaces import IMediaConverter, IMediaConversions
+from pyams_utils.interfaces import PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME
+from transaction.interfaces import ITransactionManager
+from zope.intid.interfaces import IIntIds
+
+# import packages
+from pyams_utils.registry import set_local_registry, get_utility
+from pyams_utils.zodb import ZEOConnection
+from pyams_zmq.handler import ZMQMessageHandler
+from pyams_zmq.process import ZMQProcess
+from pyramid.threadlocal import manager as threadlocal_manager
+from zope.component.globalregistry import getGlobalSiteManager
+
+
+class ConversionProcess(Process):
+ """Media conversion process"""
+
+ def __init__(self, settings, group=None, target=None, name=None, *args, **kwargs):
+ Process.__init__(self, group, target, name, *args, **kwargs)
+ self.settings = settings
+
+ def run(self):
+ logger.debug("Starting conversion process...")
+ # Lower process nice...
+ os.nice(10)
+ # Loading components registry
+ registry = getGlobalSiteManager()
+ threadlocal_manager.set({'request': None, 'registry': registry})
+ logger.debug("Getting global registry: {0!r}".format(registry))
+ # Check settings
+ settings = self.settings
+ logger.debug("Checking conversion parameters: {0}".format(str(settings)))
+ zeo_settings = settings.get('zeo')
+ media_id = settings.get('media')
+ media_format = settings.get('format')
+ if not (zeo_settings and media_id and media_format):
+ logger.warning('Bad conversion request: {0}'.format(str(settings)))
+ return
+ converter = registry.queryUtility(IMediaConverter, media_format)
+ if converter is None:
+ logger.warning('Missing media converter: {0}'.format(media_format))
+ return
+ # Open ZEO connection
+ manager = None
+ connection_info = ZEOConnection()
+ connection_info.update(zeo_settings)
+ logger.debug("Opening ZEO connection...")
+ storage, db = connection_info.get_connection(get_storage=True)
+ try:
+ connection = db.open()
+ root = connection.root()
+ logger.debug("Getting connection root {0!r}".format(root))
+ application_name = registry.settings.get(PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME)
+ application = root.get(application_name)
+ logger.debug("Loading application {0!r} named {1}".format(application, application_name))
+ if application is not None:
+ # set local registry
+ sm = application.getSiteManager()
+ set_local_registry(sm)
+ logger.debug("Setting local registry {0!r}".format(sm))
+ # find media
+ intids = get_utility(IIntIds)
+ media = intids.queryObject(media_id)
+ if media is None:
+ logger.warning("Can't find requested media {0}!".format(media_id))
+ return
+ # extract converter output
+ logger.debug("Starting conversion process for {0!r} to {1}".format(media, media_format))
+ manager = ITransactionManager(media)
+ for loop, conversion in converter.convert(media):
+ logger.debug("Finished FFmpeg conversion process. {0} bytes output".format(len(conversion)))
+ # add conversion in a transaction attempts loop
+ for attempt in manager.attempts():
+ with attempt as t:
+ IMediaConversions(media).add_conversion(conversion, media_format, converter.format, loop)
+ if t.status == 'Committed':
+ break
+ finally:
+ if manager is not None:
+ manager.abort()
+ connection.close()
+ storage.close()
+ threadlocal_manager.pop()
+
+
+class ConversionThread(Thread):
+ """Media conversion thread"""
+
+ def __init__(self, process):
+ Thread.__init__(self)
+ self.process = process
+
+ def run(self):
+ self.process.start()
+ self.process.join()
+
+
+class MediaConversionHandler(object):
+ """Media conversion handler"""
+
+ def convert(self, settings):
+ ConversionThread(ConversionProcess(settings)).start()
+ return [200, 'Conversion process started']
+
+ def test(self, settings):
+ messages = ['Conversion process ready to handle requests.']
+ ffmpeg = shutil.which('ffmpeg')
+ if ffmpeg is None:
+ messages.append("WARNING: missing 'ffmpeg' command!")
+ else:
+ messages.append("'ffmpeg' command is available.")
+ return [200, '\n'.join(messages)]
+
+
+class MediaConversionMessageHandler(ZMQMessageHandler):
+ """Media conversion message handler"""
+
+ handler = MediaConversionHandler
+
+
+class MediaConversionProcess(ZMQProcess):
+ """Media conversion ZMQ process"""
+
+ def __init__(self, zmq_address, handler, registry):
+ ZMQProcess.__init__(self, zmq_address, handler)
+ self.registry = registry
diff -r 000000000000 -r fd39db613f8b src/pyams_media/site.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/site.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_media.interfaces import IMediaConversionUtility, CONVERTER_NAME
+from pyams_utils.interfaces.site import ISiteGenerations
+from zope.site.interfaces import INewLocalSite
+
+# import packages
+from pyams_media.utility import MediaConversionUtility
+from pyams_utils.registry import utility_config
+from pyams_utils.site import check_required_utilities
+from pyramid.events import subscriber
+
+
+REQUIRED_UTILITIES = ((IMediaConversionUtility, '', MediaConversionUtility, CONVERTER_NAME), )
+
+
+@subscriber(INewLocalSite)
+def handle_new_local_site(event):
+ """Create a new conversion utility when a site is created"""
+ site = event.manager.__parent__
+ check_required_utilities(site, REQUIRED_UTILITIES)
+
+
+@utility_config(name='PyAMS medias converter', provides=ISiteGenerations)
+class MediaConversionGenerationsChecker(object):
+ """Medias conversion utility generations checker"""
+
+ generation = 1
+
+ def evolve(self, site, current=None):
+ """Check for required utilities"""
+ check_required_utilities(site, REQUIRED_UTILITIES)
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/__init__.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
+from fanstatic import Library
+
+
+library = Library('pyams_media', 'resources')
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/LICENSE.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/LICENSE.md Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,715 @@
+
+# GPL License v3
+
+The Flowplayer Free version is released under the GNU GENERAL PUBLIC LICENSE
+Version 3 (GPL).
+
+#### The GPL requires that you not remove the Flowplayer logo and copyright notices from the user interface. See section 5.d below.
+
+Commercial licenses [are available](http://flowplayer.org/download/). The commercial player version does not
+require any Flowplayer notices or texts and also provides some additional
+features.
+
+
+## ADDITIONAL TERM per GPL Section 7
+
+If you convey this program (or any modifications of it) and assume
+contractual liability for the program to recipients of it, you agree to
+indemnify Flowplayer, Ltd. for any liability that those contractual
+assumptions impose on Flowplayer, Ltd.
+
+Except as expressly provided herein, no trademark rights are granted in any
+trademarks of Flowplayer, Ltd. Licensees are granted a limited, non-exclusive
+right to use the mark Flowplayer and the Flowplayer logos in connection with
+unmodified copies of the Program and the copyright notices required by section
+5.d of the GPL license. For the purposes of this limited trademark license
+grant, customizing the Flowplayer by skinning, scripting, or including plugins
+provided by Flowplayer, Ltd. is not considered modifying the Program.
+
+Licensees that do modify the Program, taking advantage of the open-source
+license, may not use the Flowplayer mark or Flowplayer logos and must
+change the logo as follows:
+
+stating that the licensee modified the Flowplayer. A suitable notice might
+read "Flowplayer Source code modified by ModOrg 2012"; for the canvas, the
+notice should read "Based on Flowplayer source code".
+
+In addition, licensees that modify the Program must give the modified Program
+a new name that is not confusingly similar to Flowplayer and may not
+distribute it under the name Flowplayer.
+
+
+# GNU GENERAL PUBLIC LICENSE
+## Version 3, 29 June 2007
+
+Copyright (C) 2007 Free Software Foundation, Inc. http://fsf.org
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+### Preamble
+
+The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+### TERMS AND CONDITIONS
+
+### 0. Definitions.
+
+*This License* refers to version 3 of the GNU General Public License.
+
+*Copyright* also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+*The Program* refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+To *modify* a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+A *covered work* means either the unmodified Program or a work based
+on the Program.
+
+To *propagate* a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+To *convey* a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+An interactive user interface displays *Appropriate Legal Notices*
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+### 1. Source Code.
+
+The *source code* for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+A *Standard Interface* means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+The *System Libraries* of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+The *Corresponding Source* for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+The Corresponding Source for a work in source code form is that
+same work.
+
+### 2. Basic Permissions.
+
+All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+### 4. Conveying Verbatim Copies.
+
+You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+### 5. Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+a) The work must carry prominent notices stating that you modified
+it, and giving a relevant date.
+
+b) The work must carry prominent notices stating that it is
+released under this License and any conditions added under section
+7. This requirement modifies the requirement in section 4 to
+"keep intact all notices".
+
+c) You must license the entire work, as a whole, under this
+License to anyone who comes into possession of a copy. This
+License will therefore apply, along with any applicable section 7
+additional terms, to the whole of the work, and all its parts,
+regardless of how they are packaged. This License gives no
+permission to license the work in any other way, but it does not
+invalidate such permission if you have separately received it.
+
+d) If the work has interactive user interfaces, each must display
+Appropriate Legal Notices; however, if the Program has interactive
+interfaces that do not display Appropriate Legal Notices, your
+work need not make them do so.
+
+A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+### 6. Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+a) Convey the object code in, or embodied in, a physical product
+(including a physical distribution medium), accompanied by the
+Corresponding Source fixed on a durable physical medium
+customarily used for software interchange.
+
+b) Convey the object code in, or embodied in, a physical product
+(including a physical distribution medium), accompanied by a
+written offer, valid for at least three years and valid for as
+long as you offer spare parts or customer support for that product
+model, to give anyone who possesses the object code either (1) a
+copy of the Corresponding Source for all the software in the
+product that is covered by this License, on a durable physical
+medium customarily used for software interchange, for a price no
+more than your reasonable cost of physically performing this
+conveying of source, or (2) access to copy the
+Corresponding Source from a network server at no charge.
+
+c) Convey individual copies of the object code with a copy of the
+written offer to provide the Corresponding Source. This
+alternative is allowed only occasionally and noncommercially, and
+only if you received the object code with such an offer, in accord
+with subsection 6b.
+
+d) Convey the object code by offering access from a designated
+place (gratis or for a charge), and offer equivalent access to the
+Corresponding Source in the same way through the same place at no
+further charge. You need not require recipients to copy the
+Corresponding Source along with the object code. If the place to
+copy the object code is a network server, the Corresponding Source
+may be on a different server (operated by you or a third party)
+that supports equivalent copying facilities, provided you maintain
+clear directions next to the object code saying where to find the
+Corresponding Source. Regardless of what server hosts the
+Corresponding Source, you remain obligated to ensure that it is
+available for as long as needed to satisfy these requirements.
+
+e) Convey the object code using peer-to-peer transmission, provided
+you inform other peers where the object code and Corresponding
+Source of the work are being offered to the general public at no
+charge under subsection 6d.
+
+A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+"Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+### 7. Additional Terms.
+
+"Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+a) Disclaiming warranty or limiting liability differently from the
+terms of sections 15 and 16 of this License; or
+
+b) Requiring preservation of specified reasonable legal notices or
+author attributions in that material or in the Appropriate Legal
+Notices displayed by works containing it; or
+
+c) Prohibiting misrepresentation of the origin of that material, or
+requiring that modified versions of such material be marked in
+reasonable ways as different from the original version; or
+
+d) Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+e) Declining to grant rights under trademark law for use of some
+trade names, trademarks, or service marks; or
+
+f) Requiring indemnification of licensors and authors of that
+material by anyone who conveys the material (or modified versions of
+it) with contractual assumptions of liability to the recipient, for
+any liability that these contractual assumptions directly impose on
+those licensors and authors.
+
+All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+### 8. Termination.
+
+You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+### 9. Acceptance Not Required for Having Copies.
+
+You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+### 10. Automatic Licensing of Downstream Recipients.
+
+Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+An *entity transaction* is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+### 11. Patents.
+
+A *contributor* is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+### 12. No Surrender of Others' Freedom.
+
+If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+### 13. Use with the GNU Affero General Public License.
+
+Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+### 14. Revised Versions of this License.
+
+The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+### 15. Disclaimer of Warranty.
+
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+### 16. Limitation of Liability.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+### 17. Interpretation of Sections 15 and 16.
+
+If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+One line to give the program's name and a brief idea of what it does.
+Copyright (C)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+http://www.gnu.org/licenses/.
+
+The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+http://www.gnu.org/philosophy/why-not-lgpl.html.
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/embed.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/embed.min.js Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,1 @@
+!function n(e,t,r){function o(u,c){if(!t[u]){if(!e[u]){var f="function"==typeof require&&require;if(!c&&f)return f(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var a=t[u]={exports:{}};e[u][0].call(a.exports,function(n){var t=e[u][1][n];return o(t?t:n)},a,a.exports,n,e,t,r)}return t[u].exports}for(var i="function"==typeof require&&require,u=0;ut;++t)if(!e(n[t]))return f;return 1}function e(e,t){n(e,function(n){return!t(n)})}function t(i,u,c){function f(n){return n.call?n():d[n]}function a(){if(!--w){d[y]=1,v&&v();for(var t in m)n(t.split("|"),f)&&!e(m[t],f)&&(m[t]=[])}}i=i[s]?i:[i];var l=u&&u.call,v=l?u:c,y=l?i.join(""):u,w=i.length;return setTimeout(function(){e(i,function n(e,t){return null===e?a():(e=t||-1!==e.indexOf(".js")||/^https?:\/\//.test(e)||!o?e:o+e+".js",h[e]?(y&&(p[y]=1),2==h[e]?a():setTimeout(function(){n(e,!0)},0)):(h[e]=1,y&&(p[y]=1),void r(e,a)))})},0),t}function r(n,e){var t,r=u.createElement("script");r.onload=r.onerror=r[l]=function(){r[a]&&!/^c|loade/.test(r[a])||t||(r.onload=r[l]=null,t=1,h[n]=2,e())},r.async=1,r.src=i?n+(-1===n.indexOf("?")?"?":"&")+i:n,c.insertBefore(r,c.lastChild)}var o,i,u=document,c=u.getElementsByTagName("head")[0],f=!1,s="push",a="readyState",l="onreadystatechange",d={},p={},m={},h={};return t.get=r,t.order=function(n,e,r){!function o(i){i=n.shift(),n.length?t(i,o):t(i,e,r)}()},t.path=function(n){o=n},t.urlArgs=function(n){i=n},t.ready=function(r,o,i){r=r[s]?r:[r];var u=[];return!e(r,function(n){d[n]||u[s](n)})&&n(r,function(n){return d[n]})?o():!function(n){m[n]=m[n]||[],m[n][s](o),i&&i(u)}(r.join("|")),t},t.done=function(n){t([null],n)},t})},{}]},{},[1]);
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/flowplayer.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/flowplayer.js Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,6697 @@
+/*!
+
+ Flowplayer v6.0.3 (Thursday, 23. July 2015 09:32PM) | flowplayer.org/license
+
+*/
+/*! (C) WebReflection Mit Style License */
+(function(e){function m(e,t,n,r){for(var i,s=n.slice(),o=b(t,e),u=0,a=s.length;u' + innerHTML + '' + tag + '>').attr(attributes)[0];
+ }
+};
+
+common.toggleClass = function(el, cls, flag) {
+ if (!el) return;
+ var classes = ClassList(el);
+ if (typeof flag === 'undefined') classes.toggle(cls);
+ else if (flag) classes.add(cls);
+ else if (!flag) classes.remove(cls);
+};
+
+common.addClass = function(el, cls) {
+ return common.toggleClass(el, cls, true);
+};
+
+common.removeClass = function(el, cls) {
+ return common.toggleClass(el, cls, false);
+};
+
+common.append = function(par, child) {
+ par.appendChild(child);
+ return par;
+};
+
+common.appendTo = function(child, par) {
+ common.append(par, child);
+ return child;
+};
+
+common.prepend = function(par, child) {
+ par.insertBefore(child, par.firstChild);
+};
+
+
+// Inserts `el` after `child` that is child of `par`
+common.insertAfter = function(par, child, el) {
+ if (child == common.lastChild(par)) par.appendChild(el);
+ var childIndex = Array.prototype.indexOf.call(par.children, child);
+ par.insertBefore(el, par.children[childIndex + 1]);
+};
+
+common.html = function(elms, val) {
+ elms = elms.length ? elms : [elms];
+ elms.forEach(function(elm) {
+ elm.innerHTML = val;
+ });
+};
+
+
+common.attr = function(el, key, val) {
+ if (key === 'class') key = 'className';
+ if (common.hasOwnOrPrototypeProperty(el, key)) {
+ try {
+ el[key] = val;
+ } catch (e) { // Most likely IE not letting set property
+ if ($) {
+ $(el).attr(key, val);
+ } else {
+ throw e;
+ }
+ }
+ } else {
+ if (val === false) {
+ el.removeAttribute(key);
+ } else {
+ el.setAttribute(key, val);
+ }
+ }
+ return el;
+};
+
+common.prop = function(el, key, val) {
+ if (typeof val === 'undefined') {
+ return el && el[key];
+ }
+ el[key] = val;
+};
+
+common.offset = function(el) {
+ var ret = el.getBoundingClientRect();
+ if (el.offsetWidth / el.offsetHeight > el.clientWidth / el.clientHeight) { // https://github.com/flowplayer/flowplayer/issues/757
+ ret = {
+ left: ret.left * 100,
+ right: ret.right * 100,
+ top: ret.top * 100,
+ bottom: ret.bottom * 100,
+ width: ret.width * 100,
+ height: ret.height * 100
+ };
+ }
+ return ret;
+};
+
+common.width = function(el, val) {
+ /*jshint -W093 */
+ if (val) return el.style.width = (''+val).replace(/px$/, '') + 'px';
+ var ret = common.offset(el).width;
+ return typeof ret === 'undefined' ? el.offsetWidth : ret;
+};
+
+common.height = function(el, val) {
+ /*jshint -W093 */
+ if (val) return el.style.height = (''+val).replace(/px$/, '') + 'px';
+ var ret = common.offset(el).height;
+ return typeof ret === 'undefined' ? el.offsetHeight : ret;
+};
+
+common.lastChild = function(el) {
+ return el.children[el.children.length - 1];
+};
+
+common.hasParent = function(el, parentSelector) {
+ var parent = el.parentElement;
+ while (parent) {
+ if (common.matches(parent, parentSelector)) return true;
+ parent = parent.parentElement;
+ }
+ return false;
+};
+
+common.createAbsoluteUrl = function(url) {
+ return common.createElement('a', {href: url}).href; // This won't work on IE7
+};
+
+common.xhrGet = function(url, successCb, errorCb) {
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (this.readyState !== 4) return;
+ if (this.status >= 400) return errorCb();
+ successCb(this.responseText);
+ };
+ xhr.open('get', url, true);
+ xhr.send();
+};
+
+common.pick = function(obj, props) {
+ var ret = {};
+ props.forEach(function(prop) {
+ if (obj.hasOwnProperty(prop)) ret[prop] = obj[prop];
+ });
+ return ret;
+};
+
+common.hostname = function(host) {
+ return punycode.toUnicode(host || window.location.hostname);
+};
+
+//Hacks
+common.browser = {
+ webkit: 'WebkitAppearance' in document.documentElement.style
+};
+
+common.getPrototype = function(el) {
+ /* jshint proto:true */
+ if (!Object.getPrototypeOf) return el.__proto__;
+ return Object.getPrototypeOf(el);
+};
+
+common.hasOwnOrPrototypeProperty = function(obj, prop) {
+ var o = obj;
+ while (o) {
+ if (Object.prototype.hasOwnProperty.call(o, prop)) return true;
+ o = common.getPrototype(o);
+ }
+ return false;
+};
+
+
+// Polyfill for Element.matches
+// adapted from https://developer.mozilla.org/en/docs/Web/API/Element/matches
+common.matches = function(elem, selector) {
+ var proto = Element.prototype,
+ fn = proto.matches ||
+ proto.matchesSelector ||
+ proto.mozMatchesSelector ||
+ proto.msMatchesSelector ||
+ proto.oMatchesSelector ||
+ proto.webkitMatchesSelector ||
+ function (selector) {
+ var element = this,
+ matches = (element.document || element.ownerDocument).querySelectorAll(selector),
+ i = 0;
+ while (matches[i] && matches[i] !== element) {
+ i++;
+ }
+
+ return matches[i] ? true : false;
+ };
+ return fn.call(elem, selector);
+};
+
+
+// Polyfill for CSSStyleDeclaration
+// from https://github.com/shawnbot/aight
+(function(CSSSDProto) {
+
+ function getAttribute(property) {
+ return property.replace(/-[a-z]/g, function(bit) {
+ return bit[1].toUpperCase();
+ });
+ }
+
+ // patch CSSStyleDeclaration.prototype using IE8's methods
+ if (typeof CSSSDProto.setAttribute !== "undefined") {
+ CSSSDProto.setProperty = function(property, value) {
+ return this.setAttribute(getAttribute(property), String(value) /*, important */ );
+ };
+ CSSSDProto.getPropertyValue = function(property) {
+ return this.getAttribute(getAttribute(property)) || null;
+ };
+ CSSSDProto.removeProperty = function(property) {
+ var value = this.getPropertyValue(property);
+ this.removeAttribute(getAttribute(property));
+ return value;
+ };
+ }
+
+})(window.CSSStyleDeclaration.prototype);
+
+},{"class-list":22,"computed-style":24,"punycode":21}],2:[function(_dereq_,module,exports){
+/* global __flash_unloadHandler:true,__flash_savedUnloadHandler:true */
+'use strict';
+var common = _dereq_('../common');
+
+// movie required in opts
+module.exports = function embed(swf, flashvars, wmode, bgColor) {
+ wmode = wmode || "opaque";
+
+ var id = "obj" + ("" + Math.random()).slice(2, 15),
+ tag = ' -1;
+
+ tag += msie ? 'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">' :
+ ' data="' + swf + '" type="application/x-shockwave-flash">';
+
+ var opts = {
+ width: "100%",
+ height: "100%",
+ allowscriptaccess: "always",
+ wmode: wmode,
+ quality: "high",
+ flashvars: "",
+
+ // https://github.com/flowplayer/flowplayer/issues/13#issuecomment-9369919
+ movie: swf + (msie ? "?" + id : ""),
+ name: id
+ };
+
+ if (wmode !== 'transparent') opts.bgcolor = bgColor || '#333333';
+
+ // flashvars
+ Object.keys(flashvars).forEach(function(key) {
+ opts.flashvars += key + "=" + flashvars[key] + "&";
+ });
+
+ // parameters
+ Object.keys(opts).forEach(function(key) {
+ tag += ' ';
+ });
+
+ tag += " ";
+ var el = common.createElement('div', {}, tag);
+ return common.find('object', el);
+
+};
+
+
+// Flash is buggy allover
+if (window.attachEvent) {
+ window.attachEvent("onbeforeunload", function() {
+ __flash_savedUnloadHandler = __flash_unloadHandler = function() {};
+ });
+}
+
+
+},{"../common":1}],3:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ common = _dereq_('../common'),
+ embed = _dereq_('./embed'),
+ extend = _dereq_('extend-object'),
+ bean = _dereq_('bean'),
+ engineImpl;
+
+engineImpl = function flashEngine(player, root) {
+
+ var conf = player.conf,
+ video = player.video,
+ loadVideo,
+ callbackId,
+ objectTag,
+ api;
+
+ var win = window;
+
+ var engine = {
+ engineName: engineImpl.engineName,
+
+ pick: function(sources) {
+
+ if (flowplayer.support.flashVideo) {
+ var selectedSource;
+ for (var i = 0, source; i < sources.length; i++) {
+ source = sources[i];
+ if (/mp4|flv|flash/i.test(source.type)) selectedSource = source;
+ if (player.conf.swfHls && /mpegurl/i.test(source.type)) selectedSource = source;
+ if (selectedSource && !/mp4/i.test(selectedSource.type)) return selectedSource;
+ // Did not find any source or source was video/mp4, let's try find more
+ }
+ return selectedSource; // Accept the fact we don't have anything or just an MP4
+ }
+ },
+
+ load: function(video) {
+ loadVideo = video;
+
+ function escapeURL(url) {
+ return url.replace(/&/g, '%26').replace(/&/g, '%26').replace(/=/g, '%3D');
+ }
+
+ var html5Tag = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0],
+ url = escapeURL(video.src),
+ is_absolute = /^https?:/.test(url);
+
+ var removeTag = function() {
+ common.removeNode(html5Tag);
+ };
+ var hasSupportedSource = function(sources) {
+ return sources.some(function(src) {
+ return !!html5Tag.canPlayType(src.type);
+ });
+ };
+ if (flowplayer.support.video &&
+ common.prop(html5Tag, 'autoplay') &&
+ hasSupportedSource(video.sources)) bean.one(html5Tag, 'timeupdate', removeTag);
+ else removeTag();
+
+ // convert to absolute
+ var rtmp = video.rtmp || conf.rtmp;
+ if (!is_absolute && !rtmp) url = common.createAbsoluteUrl(url);
+
+ if (api && isHLS(video) && api.data !== conf.swfHls) engine.unload();
+
+ if (api) {
+ ['live', 'preload', 'loop'].forEach(function(prop) {
+ if (!video.hasOwnProperty(prop)) return;
+ api.__set(prop, video[prop]);
+ });
+ Object.keys(video.flashls || {}).forEach(function(key) {
+ api.__set('hls_' + key, video.flashls[key]);
+ });
+ var providerChangeNeeded = false;
+ if (!is_absolute && rtmp) api.__set('rtmp', rtmp.url || rtmp);
+ else {
+ var oldRtmp = api.__get('rtmp');
+ providerChangeNeeded = !!oldRtmp;
+ api.__set('rtmp', null);
+ }
+ api.__play(url, providerChangeNeeded || video.rtmp && video.rtmp !== conf.rtmp);
+
+ } else {
+
+ callbackId = "fpCallback" + ("" + Math.random()).slice(3, 15);
+
+ var opts = {
+ hostname: conf.embedded ? common.hostname(conf.hostname) : common.hostname(location.hostname),
+ url: url,
+ callback: callbackId
+ };
+ if (root.getAttribute('data-origin')) {
+ opts.origin = root.getAttribute('data-origin');
+ }
+
+ // optional conf
+ ['proxy', 'key', 'autoplay', 'preload', 'subscribe', 'live', 'loop', 'debug', 'splash', 'poster', 'rtmpt'].forEach(function(key) {
+ if (conf.hasOwnProperty(key)) opts[key] = conf[key];
+ if (video.hasOwnProperty(key)) opts[key] = video[key];
+ if ((conf.rtmp || {}).hasOwnProperty(key)) opts[key] = (conf.rtmp || {})[key];
+ if ((video.rtmp || {}).hasOwnProperty(key)) opts[key] = (video.rtmp || {})[key];
+ });
+ if (conf.rtmp) opts.rtmp = conf.rtmp.url || conf.rtmp;
+ if (video.rtmp) opts.rtmp = video.rtmp.url || video.rtmp;
+ Object.keys(video.flashls || {}).forEach(function(key) {
+ var val = video.flashls[key];
+ opts['hls_' + key] = val;
+ });
+ // bufferTime might be 0
+ if (conf.bufferTime !== undefined) opts.bufferTime = conf.bufferTime;
+
+ if (is_absolute) delete opts.rtmp;
+
+ // issues #376
+ if (opts.rtmp) {
+ opts.rtmp = escapeURL(opts.rtmp);
+ }
+
+ // issue #733
+ var bgColor = common.css(root, 'background-color') ||'', bg;
+ if (bgColor.indexOf('rgb') === 0) {
+ bg = toHex(bgColor);
+ } else if (bgColor.indexOf('#') === 0) {
+ bg = toLongHex(bgColor);
+ }
+
+ // issues #387
+ opts.initialVolume = player.volumeLevel;
+
+ var swfUrl = isHLS(video) ? conf.swfHls : conf.swf;
+
+ api = embed(swfUrl, opts, conf.wmode, bg)[0];
+
+ var container = common.find('.fp-player', root)[0];
+
+ common.prepend(container, api);
+
+ // throw error if no loading occurs
+ setTimeout(function() {
+ try {
+ if (!api.PercentLoaded()) {
+ return player.trigger("error", [player, { code: 7, url: conf.swf }]);
+ }
+ } catch (e) {}
+ }, 5000);
+
+ // detect disabled flash
+ setTimeout(function() {
+ if (typeof api.PercentLoaded === 'undefined') {
+ player.trigger('flashdisabled', [player]);
+ }
+ }, 1000);
+
+ api.pollInterval = setInterval(function () {
+ if (!api) return;
+ var status = api.__status ? api.__status() : null;
+
+ if (!status) return;
+
+ if (player.playing && status.time && status.time !== player.video.time) player.trigger("progress", [player, status.time]);
+
+ video.buffer = status.buffer / video.bytes * video.duration;
+ player.trigger("buffer", [player, video.buffer]);
+ if (!video.buffered && status.time > 0) {
+ video.buffered = true;
+ player.trigger("buffered", [player]);
+ }
+
+ }, 250);
+
+ // listen
+ window[callbackId] = function(type, arg) {
+ var video = loadVideo;
+
+ if (conf.debug) {
+ if (type.indexOf('debug') === 0 && arg && arg.length) {
+ console.log.apply(console, ['-- ' + type].concat(arg));
+ }
+ else console.log("--", type, arg);
+ }
+
+ var event = {
+ type: type
+ };
+
+ switch (type) {
+
+ // RTMP sends a lot of finish events in vain
+ // case "finish": if (conf.rtmp) return;
+ case "ready": arg = extend(video, arg); break;
+ case "click": event.flash = true; break;
+ case "keydown": event.which = arg; break;
+ case "seek": video.time = arg; break;
+ case "status":
+ player.trigger("progress", [player, arg.time]);
+
+ if (arg.buffer < video.bytes && !video.buffered) {
+ video.buffer = arg.buffer / video.bytes * video.duration;
+ player.trigger("buffer", video.buffer);
+ } else if (!video.buffered) {
+ video.buffered = true;
+ player.trigger("buffered");
+ }
+
+ break;
+ }
+ if (type === 'click' || type === 'keydown') {
+ event.target = root;
+ bean.fire(root, type, [event]);
+ }
+ else if (type != 'buffered' && type !== 'unload') {
+ // add some delay so that player is truly ready after an event
+ setTimeout(function() { player.trigger(event, [player, arg]); }, 1);
+ } else if (type === 'unload') {
+ player.trigger(event, [player, arg]);
+ }
+
+ };
+
+ }
+
+ },
+
+ // not supported yet
+ speed: common.noop,
+
+
+ unload: function() {
+ if (api && api.__unload) api.__unload();
+ try {
+ if (callbackId && window[callbackId])delete window[callbackId];
+ } catch (e) {}
+ common.find("object", root).forEach(common.removeNode);
+ api = 0;
+ player.off('.flashengine');
+ clearInterval(api.pollInterval);
+ }
+
+ };
+
+ ['pause','resume','seek','volume'].forEach(function(name) {
+
+ engine[name] = function(arg) {
+ try {
+ if (player.ready) {
+
+ if (name == 'seek' && player.video.time && !player.paused) {
+ player.trigger("beforeseek");
+ }
+
+ if (arg === undefined) {
+ api["__" + name]();
+
+ } else {
+ api["__" + name](arg);
+ }
+
+ }
+ } catch (e) {
+ if (typeof api["__" + name] === 'undefined') { //flash lost it's methods
+ return player.trigger('flashdisabled', [player]);
+ }
+ throw e;
+ }
+ };
+
+ });
+
+ function toHex(bg) {
+ function hex(x) {
+ return ("0" + parseInt(x).toString(16)).slice(-2);
+ }
+
+ bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
+ if (!bg) return;
+
+ return '#' + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
+ }
+
+ function toLongHex(bg) {
+ if (bg.length === 7) return bg;
+ var a = bg.split('').slice(1);
+ return '#' + a.map(function(i) {
+ return i + i;
+ }).join('');
+ }
+
+ function isHLS(video) {
+ return /application\/x-mpegurl/i.test(video.type);
+ }
+
+ return engine;
+
+};
+
+
+engineImpl.engineName = 'flash';
+engineImpl.canPlay = function(type, conf) {
+ return flowplayer.support.flashVideo && /video\/(mp4|flash|flv)/i.test(type) || flowplayer.support.flashVideo && conf.swfHls && /mpegurl/i.test(type);
+};
+flowplayer.engines.push(engineImpl);
+
+},{"../common":1,"../flowplayer":18,"./embed":2,"bean":20,"extend-object":26}],4:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ bean = _dereq_('bean'),
+ ClassList = _dereq_('class-list'),
+ extend = _dereq_('extend-object'),
+ common = _dereq_('../common');
+var VIDEO = document.createElement('video');
+
+// HTML5 --> Flowplayer event
+var EVENTS = {
+
+ // fired
+ ended: 'finish',
+ pause: 'pause',
+ play: 'resume',
+ progress: 'buffer',
+ timeupdate: 'progress',
+ volumechange: 'volume',
+ ratechange: 'speed',
+ //seeking: 'beforeseek',
+ seeked: 'seek',
+ // abort: 'resume',
+
+ // not fired
+ loadeddata: 'ready',
+ // loadedmetadata: 0,
+ // canplay: 0,
+
+ // error events
+ // load: 0,
+ // emptied: 0,
+ // empty: 0,
+ error: 'error',
+ dataunavailable: 'error',
+ webkitendfullscreen: !flowplayer.support.inlineVideo && 'unload'
+
+};
+
+function round(val, per) {
+ per = per || 100;
+ return Math.round(val * per) / per;
+}
+
+function getType(type) {
+ return /mpegurl/i.test(type) ? "application/x-mpegurl" : type;
+}
+
+function canPlay(type) {
+ if (!/^(video|application)/i.test(type))
+ type = getType(type);
+ return !!VIDEO.canPlayType(type).replace("no", '');
+}
+
+function findFromSourcesByType(sources, type) {
+ var arr = sources.filter(function(s) {
+ return s.type === type;
+ });
+ return arr.length ? arr[0] : null;
+}
+
+var videoTagCache;
+var createVideoTag = function(video, autoplay, preload, useCache) {
+ if (typeof autoplay === 'undefined') autoplay = true;
+ if (typeof preload === 'undefined') preload = 'none';
+ if (typeof useCache === 'undefined') useCache = true;
+ if (useCache && videoTagCache) {
+ videoTagCache.type = getType(video.type);
+ videoTagCache.src = video.src;
+ return videoTagCache;
+ }
+ var el = document.createElement('video');
+ el.src = video.src;
+ el.type = getType(video.type);
+ el.className = 'fp-engine';
+ el.autoplay = autoplay ? 'autoplay' : false;
+ el.preload = preload;
+ el.setAttribute('x-webkit-airplay', 'allow');
+ if (useCache) videoTagCache = el;
+ return el;
+};
+
+var engine;
+
+engine = function(player, root) {
+
+ var api = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0],
+ support = flowplayer.support,
+ track = common.find("track", api)[0],
+ conf = player.conf,
+ self,
+ timer,
+ volumeLevel;
+ /*jshint -W093 */
+ return self = {
+ engineName: engine.engineName,
+
+ pick: function(sources) {
+ if (support.video) {
+ if (conf.videoTypePreference) {
+ var mp4source = findFromSourcesByType(sources, conf.videoTypePreference);
+ if (mp4source) return mp4source;
+ }
+
+ for (var i = 0, source; i < sources.length; i++) {
+ if (canPlay(sources[i].type)) return sources[i];
+ }
+ }
+ },
+
+ load: function(video) {
+ var created = false, container = common.find('.fp-player', root)[0], reload = false;
+ if (conf.splash && !api) {
+ api = createVideoTag(video);
+ common.prepend(container, api);
+ created = true;
+ } else if (!api) {
+ api = createVideoTag(video, !!video.autoplay || !!conf.autoplay, conf.clip.preload || 'metadata', false);
+ common.prepend(container, api);
+ created = true;
+ } else {
+ ClassList(api).add('fp-engine');
+ common.find('source,track', api).forEach(common.removeNode);
+ if (!player.conf.nativesubtitles) common.attr(api, 'crossorigin', false);
+ reload = api.src === video.src;
+ }
+ if (!support.inlineVideo) {
+ common.css(api, {
+ position: 'absolute',
+ top: '-9999em'
+ });
+ }
+ //TODO subtitles support
+
+ // IE does not fire delegated timeupdate events
+ bean.off(api, 'timeupdate', common.noop);
+ bean.on(api, 'timeupdate', common.noop);
+
+ common.prop(api, 'loop', !!(video.loop || conf.loop));
+
+ if (typeof volumeLevel !== 'undefined') {
+ api.volume = volumeLevel;
+ }
+
+ if (player.video.src && video.src != player.video.src || video.index) common.attr(api, 'autoplay', 'autoplay');
+ api.src = video.src;
+ api.type = video.type;
+
+ listen(api, common.find("source", api).concat(api), video);
+
+ // iPad (+others?) demands load()
+ if (conf.clip.preload != 'none' && video.type != "mpegurl" || !support.zeropreload || !support.dataload) api.load();
+ if (created || reload) api.load();
+ if (api.paused && (video.autoplay || conf.autoplay)) api.play();
+ },
+
+ pause: function() {
+ api.pause();
+ },
+
+ resume: function() {
+ api.play();
+ },
+
+ speed: function(val) {
+ api.playbackRate = val;
+ },
+
+ seek: function(time) {
+ try {
+ var pausedState = player.paused;
+ api.currentTime = time;
+ if (pausedState) api.pause();
+ } catch (ignored) {}
+ },
+
+ volume: function(level) {
+ volumeLevel = level;
+ if (api) {
+ api.volume = level;
+ }
+ },
+
+ unload: function() {
+ common.find('video.fp-engine', root).forEach(common.removeNode);
+ if (!support.cachedVideoTag) videoTagCache = null;
+ timer = clearInterval(timer);
+ api = 0;
+ }
+
+ };
+
+ function listen(api, sources, video) {
+ // listen only once
+ var instanceId = root.getAttribute('data-flowplayer-instance-id');
+
+ if (api.listeners && api.listeners.hasOwnProperty(instanceId)) {
+ api.listeners[instanceId] = video;
+ return;
+ }
+ (api.listeners || (api.listeners = {}))[instanceId] = video;
+
+ bean.on(sources, 'error', function(e) {
+ try {
+ if (canPlay(e.target.getAttribute('type'))) {
+ player.trigger("error", [player, { code: 4, video: extend(video, {src: api.src, url: api.src}) }]);
+ }
+ } catch (er) {
+ // Most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ }
+ });
+
+ player.on('shutdown', function() {
+ bean.off(sources);
+ });
+
+ Object.keys(EVENTS).forEach(function(type) {
+ var flow = EVENTS[type];
+ if (!flow) return;
+ root.addEventListener(type, function(e) {
+ video = api.listeners[instanceId];
+ if (!e.target || !ClassList(e.target).contains('fp-engine')) return;
+
+ if (conf.debug && !/progress/.test(flow)) console.log(type, "->", flow, e);
+
+ // no events if player not ready
+ if (!player.ready && !/ready|error/.test(flow) || !flow || !common.find('video', root).length) { return; }
+
+ var arg, vtype;
+
+ if (flow === 'unload') { //Call player unload
+ player.unload();
+ return;
+ }
+
+ var triggerEvent = function() {
+ player.trigger(flow, [player, arg]);
+ };
+
+ switch (flow) {
+
+ case "ready":
+
+ arg = extend(video, {
+ duration: api.duration,
+ width: api.videoWidth,
+ height: api.videoHeight,
+ url: api.currentSrc,
+ src: api.currentSrc
+ });
+
+ try {
+ arg.seekable = !conf.live && /mpegurl/i.test(video ? (video.type || '') : '') && api.duration || api.seekable && api.seekable.end(null);
+
+ } catch (ignored) {}
+
+ // buffer
+ timer = timer || setInterval(function() {
+
+ try {
+ arg.buffer = api.buffered.end(null);
+
+ } catch (ignored) {}
+
+ if (arg.buffer) {
+ if (round(arg.buffer, 1000) < round(arg.duration, 1000) && !arg.buffered) {
+ player.trigger("buffer", e);
+
+ } else if (!arg.buffered) {
+ arg.buffered = true;
+ player.trigger("buffer", e).trigger("buffered", e);
+ clearInterval(timer);
+ timer = 0;
+ }
+ }
+
+ }, 250);
+
+ if (!conf.live && !arg.duration && !support.hlsDuration && type === "loadeddata") {
+ var durationChanged = function() {
+ arg.duration = api.duration;
+ try {
+ arg.seekable = api.seekable && api.seekable.end(null);
+
+ } catch (ignored) {}
+ triggerEvent();
+ api.removeEventListener('durationchange', durationChanged);
+ ClassList(root).remove('is-live');
+ };
+ api.addEventListener('durationchange', durationChanged);
+
+ // Ugly hack to handle broken Android devices
+ var timeUpdated = function() {
+ if (!player.ready && !api.duration) { // No duration even though the video already plays
+ arg.duration = 0;
+ ClassList(root).add('is-live'); // Make UI believe it's live
+ triggerEvent();
+ }
+ api.removeEventListener('timeupdate', timeUpdated);
+ };
+ api.addEventListener('timeupdate', timeUpdated);
+ return;
+ }
+
+ break;
+
+ case "progress": case "seek":
+
+ var dur = player.video.duration;
+
+ if (api.currentTime > 0 || player.live) {
+ arg = Math.max(api.currentTime, 0);
+
+ } else if (flow == 'progress') {
+ return;
+ }
+ break;
+
+
+ case "speed":
+ arg = round(api.playbackRate);
+ break;
+
+ case "volume":
+ arg = round(api.volume);
+ break;
+
+ case "error":
+ try {
+ arg = (e.srcElement || e.originalTarget).error;
+ arg.video = extend(video, {src: api.src, url: api.src});
+ } catch (er) {
+ // Most likely https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return;
+ }
+ }
+
+ triggerEvent();
+
+
+ }, true);
+
+ });
+
+ }
+
+};
+
+
+engine.canPlay = function(type) {
+ return flowplayer.support.video && canPlay(type);
+};
+
+engine.engineName = 'html5';
+
+flowplayer.engines.push(engine);
+
+},{"../common":1,"../flowplayer":18,"bean":20,"class-list":22,"extend-object":26}],5:[function(_dereq_,module,exports){
+'use strict';
+/* global _gat */
+var flowplayer = _dereq_('../flowplayer'),
+ TYPE_RE = _dereq_('./resolve').TYPE_RE,
+ scriptjs = _dereq_('scriptjs'),
+ bean = _dereq_('bean');
+flowplayer(function(player, root) {
+
+ var id = player.conf.analytics, time = 0, last = 0, timer;
+
+ if (id) {
+
+ // load Analytics script if needed
+ if (typeof _gat == 'undefined') scriptjs("//google-analytics.com/ga.js");
+
+ var getTracker = function() {
+ var tracker = _gat._getTracker(id);
+ tracker._setAllowLinker(true);
+ return tracker;
+ };
+
+ var track = function track(e, api, video) {
+
+ video = video || player.video;
+
+ if (time && typeof _gat != 'undefined') {
+ var tracker = getTracker();
+
+
+ // http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html
+ tracker._trackEvent(
+ "Video / Seconds played",
+ player.engine.engineName + "/" + video.type,
+ video.title || root.getAttribute("title") || video.src.split("/").slice(-1)[0].replace(TYPE_RE, ''),
+ Math.round(time / 1000)
+ );
+ time = 0;
+ if (timer) {
+ clearTimeout(timer);
+ timer = null;
+ }
+ }
+
+ };
+
+ player.bind("load unload", track).bind("progress", function() {
+
+ if (!player.seeking) {
+ time += last ? (+new Date() - last) : 0;
+ last = +new Date();
+ }
+
+ if (!timer) {
+ timer = setTimeout(function() {
+ timer = null;
+ var tracker = getTracker();
+ tracker._trackEvent('Flowplayer heartbeat', 'Heartbeat', '', 0, true);
+ }, 10*60*1000); // heartbeat every 10 minutes
+ }
+
+ }).bind("pause", function() {
+ last = 0;
+ });
+
+ player.bind('shutdown', function() {
+ bean.off(window, 'unload', track);
+ });
+
+ bean.on(window, 'unload', track);
+
+ }
+
+});
+
+},{"../flowplayer":18,"./resolve":13,"bean":20,"scriptjs":29}],6:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ ClassList = _dereq_('class-list'),
+ common = _dereq_('../common'),
+ bean = _dereq_('bean');
+
+flowplayer(function(player, root) {
+
+ var CUE_RE = / ?cue\d+ ?/;
+
+ var lastTime = 0, cuepointsDisabled = false;
+
+ function setClass(index) {
+ root.className = root.className.replace(CUE_RE, " ");
+ if (index >= 0) ClassList(root).add('cue' + index);
+ }
+
+ var segments = {}, lastFiredSegment = -0.125;
+
+ var fire = function(cue) {
+ var idx = player.cuepoints.indexOf(cue);
+ if (!isNaN(cue)) cue = { time: cue };
+ cue.index = idx;
+ setClass(idx);
+ player.trigger('cuepoint', [player, cue]);
+ };
+
+ player.on("progress", function(e, api, time) {
+ if (cuepointsDisabled) return;
+ var segment = segmentForCue(time);
+ while (lastFiredSegment < segment) {
+ lastFiredSegment += 0.125;
+ if (!segments[lastFiredSegment]) continue;
+ segments[lastFiredSegment].forEach(fire);
+ }
+
+ }).on("unload", setClass)
+ .on('beforeseek', function() {
+ cuepointsDisabled = true;
+ }).on("seek", function(ev, api, time) {
+ setClass();
+ lastFiredSegment = segmentForCue(time || 0) - 0.125;
+ cuepointsDisabled = false;
+ if (!time && segments[0]) segments[0].forEach(fire);
+ }).on('ready', function(e, api, video) {
+ lastFiredSegment = -0.125;
+ var cues = video.cuepoints || player.conf.cuepoints || [];
+ player.setCuepoints(cues);
+ }).on('finish', function() {
+ lastFiredSegment = -0.125;
+ });
+ if (player.conf.generate_cuepoints) {
+
+ player.bind("load", function() {
+
+ // clean up cuepoint elements of previous playlist items
+ common.find('.fp-cuepoint', root).forEach(common.removeNode);
+
+ });
+ }
+
+ /**
+ * API
+ */
+ player.setCuepoints = function(cues) {
+ player.cuepoints = [];
+ segments = {};
+ cues.forEach(player.addCuepoint);
+ return player;
+ };
+ player.addCuepoint = function(cue) {
+ if (!player.cuepoints) player.cuepoints = [];
+ var segment = segmentForCue(cue);
+ if (!segments[segment]) segments[segment] = [];
+ segments[segment].push(cue);
+ player.cuepoints.push(cue);
+
+ if (player.conf.generate_cuepoints && cue.visible !== false) {
+ var duration = player.video.duration,
+ timeline = common.find('.fp-timeline', root)[0];
+ common.css(timeline, "overflow", "visible");
+
+ var time = cue.time || cue;
+ if (time < 0) time = duration + cue;
+
+ var el = common.createElement('a', {className: 'fp-cuepoint fp-cuepoint' + (player.cuepoints.length - 1)});
+ common.css(el, "left", (time / duration * 100) + "%");
+
+ timeline.appendChild(el);
+ bean.on(el, 'mousedown', function(e) {
+ e.preventDefault();
+ player.seek(time);
+
+ // preventDefault() doesn't work
+ return false;
+ });
+ }
+ return player;
+ };
+
+ player.removeCuepoint = function(cue) {
+ var idx = player.cuepoints.indexOf(cue),
+ segment = segmentForCue(cue);
+ if (idx === -1) return;
+ player.cuepoints = player.cuepoints.slice(0, idx).concat(player.cuepoints.slice(idx+1));
+
+ var sIdx = segments[segment].indexOf(cue);
+ if (sIdx === -1) return;
+ segments[segment] = segments[segment].slice(0, sIdx).concat(segments[segment].slice(sIdx+1));
+ return player;
+ };
+
+ function segmentForCue(cue) {
+ var time = cue && !isNaN(cue.time) ? cue.time : cue;
+ if (time < 0) time = player.video.duration + time;
+ return Math.round(time/0.125)*0.125;
+ }
+
+});
+
+},{"../common":1,"../flowplayer":18,"bean":20,"class-list":22}],7:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ bean = _dereq_('bean'),
+ common = _dereq_('../common'),
+ isObject = _dereq_('is-object'),
+ extend = _dereq_('extend-object'),
+ ClassList = _dereq_('class-list');
+
+
+
+flowplayer(function(player, root) {
+
+ // no embedding
+ if (player.conf.embed === false) return;
+
+ var conf = player.conf,
+ ui = common.find('.fp-ui', root)[0],
+ trigger = common.createElement('a', { "class": "fp-embed", title: 'Copy to your site'}),
+ target = common.createElement('div',{ 'class': 'fp-embed-code'}, 'Paste this HTML code on your site to embed. '),
+ area = common.find("textarea", target)[0];
+
+ ui.appendChild(trigger);
+ ui.appendChild(target);
+
+ player.embedCode = function() {
+ var embedConf = player.conf.embed || {},
+ video = player.video;
+
+ if (embedConf.iframe) {
+ var src = player.conf.embed.iframe,
+ width = embedConf.width || video.width || common.width(root),
+ height = embedConf.height || video.height || common.height(root);
+ return '';
+ }
+ var props = ['ratio', 'rtmp', 'live', 'bufferTime', 'origin', 'analytics', 'key', 'subscribe', 'swf', 'swfHls', 'embed', 'adaptiveRatio', 'logo'];
+ if (embedConf.playlist) props.push('playlist');
+ var c = common.pick(player.conf, props);
+ if (c.logo) c.logo = common.createElement('img', {src: c.logo}).src;
+ if (!embedConf.playlist || !player.conf.playlist.length) c.clip = extend({}, player.conf.clip, common.pick(player.video, ['sources']));
+ var script = "var w=window,d=document,e;w._fpes||(w._fpes=[],w.addEventListener(\"load\",function(){var s=d.createElement(\"script\");s.src=\"//embed.flowplayer.org/6.0.3/embed.min.js\",d.body.appendChild(s)})),e=[].slice.call(d.getElementsByTagName(\"script\"),-1)[0].parentNode,w._fpes.push({e:e,l:\"$library\",c:$conf});\n".replace('$conf', JSON.stringify(c)).replace('$library', embedConf.library || '');
+
+ return ' Watch video!\n '.replace('$href', player.conf.origin || window.location.href).replace('$script', script);
+
+ };
+ fptip(root, ".fp-embed", "is-embedding");
+
+ bean.on(root, 'click', '.fp-embed-code textarea', function() {
+ area.select();
+ });
+
+ bean.on(root, 'click', '.fp-embed', function() {
+ area.textContent = player.embedCode().replace(/(\r\n|\n|\r)/gm,"");
+ area.focus();
+ area.select();
+ });
+
+});
+
+var fptip = function(root, trigger, active) {
+
+ function close() {
+ rootClasses.remove(active);
+ bean.off(document, '.st');
+ }
+
+ var rootClasses = ClassList(root);
+
+ bean.on(root, 'click', trigger || 'a', function(e) {
+ e.preventDefault();
+
+ rootClasses.toggle(active);
+
+ if (rootClasses.contains(active)) {
+
+ bean.on(document, 'keydown.st', function(e) {
+ if (e.which == 27) close();
+ });
+ bean.on(document, 'click.st', function(e) {
+ if (!common.hasParent(e.target, '.' + active)) close();
+ });
+ }
+ });
+};
+
+
+},{"../common":1,"../flowplayer":18,"bean":20,"class-list":22,"extend-object":26,"is-object":28}],8:[function(_dereq_,module,exports){
+'use strict';
+/* global jQuery */
+/**
+ * Mimimal jQuery-like event emitter implementation
+ */
+module.exports = function(obj, elem) {
+ if (!elem) elem = document.createElement('div'); //In this case we always want to trigger (Custom)Events on dom element
+ var handlers = {}, eventArguments = {};
+
+ var listenEvent = function(type, hndlr, disposable) {
+ var actualEvent = type.split('.')[0]; //Strip namespace
+ var internalHandler = function(ev) {
+ if (disposable) {
+ elem.removeEventListener(actualEvent, internalHandler);
+ handlers[type].splice(handlers[type].indexOf(internalHandler), 1);
+ }
+ var args = [ev].concat(eventArguments[ev.timeStamp + ev.type] || []);
+ if (hndlr) hndlr.apply(undefined, args);
+ };
+ elem.addEventListener(actualEvent, internalHandler);
+
+ //Store handlers for unbinding
+ if (!handlers[type]) handlers[type] = [];
+ handlers[type].push(internalHandler);
+ };
+
+ obj.on = obj.bind = function(typ, hndlr) {
+ var types = typ.split(' ');
+ types.forEach(function(type) {
+ listenEvent(type, hndlr);
+ });
+ return obj; //for chaining
+ };
+
+ obj.one = function(typ, hndlr) {
+ var types = typ.split(' ');
+ types.forEach(function(type) {
+ listenEvent(type, hndlr, true);
+ });
+ return obj;
+ };
+
+ // Function to check if all items in toBeContained array are in the containing array
+ var containsAll = function(containing, toBeContained) {
+ return toBeContained.filter(function(i) {
+ return containing.indexOf(i) === -1;
+ }).length === 0;
+ };
+
+
+ obj.off = obj.unbind = function(typ) {
+ var types = typ.split(' ');
+ types.forEach(function(type) {
+ var typeNameSpaces = type.split('.').slice(1),
+ actualType = type.split('.')[0];
+ Object.keys(handlers).filter(function(t) {
+ var handlerNamespaces = t.split('.').slice(1);
+ return (!actualType || t.indexOf(actualType) === 0) && containsAll(handlerNamespaces, typeNameSpaces);
+ }).forEach(function(t) {
+ var registererHandlers = handlers[t],
+ actualEvent = t.split('.')[0];
+ registererHandlers.forEach(function(hndlr) {
+ elem.removeEventListener(actualEvent, hndlr);
+ registererHandlers.splice(registererHandlers.indexOf(hndlr), 1);
+ });
+ });
+ });
+ return obj;
+ };
+
+ obj.trigger = function(typ, args, returnEvent) {
+ if (!typ) return;
+ args = (args || []).length ? args || [] : [args];
+ var event = document.createEvent('Event'), typStr;
+ typStr = typ.type || typ;
+ event.initEvent(typStr, false, true);
+ eventArguments[event.timeStamp + event.type] = args;
+ elem.dispatchEvent(event);
+ return returnEvent ? event : obj;
+ };
+};
+
+
+module.exports.EVENTS = [
+ 'beforeseek',
+ 'disable',
+ 'error',
+ 'finish',
+ 'fullscreen',
+ 'fullscreen-exit',
+ 'load',
+ 'mute',
+ 'pause',
+ 'progress',
+ 'ready',
+ 'resume',
+ 'seek',
+ 'speed',
+ 'stop',
+ 'unload',
+ 'volume',
+ 'boot',
+ 'shutdown'
+];
+
+},{}],9:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ bean = _dereq_('bean'),
+ ClassList = _dereq_('class-list'),
+ extend = _dereq_('extend-object'),
+ common = _dereq_('../common'),
+ VENDOR = flowplayer.support.browser.mozilla ? "moz": "webkit",
+ FS_ENTER = "fullscreen",
+ FS_EXIT = "fullscreen-exit",
+ FULL_PLAYER,
+ FS_SUPPORT = flowplayer.support.fullscreen,
+ FS_NATIVE_SUPPORT = typeof document.exitFullscreen == 'function',
+ ua = navigator.userAgent.toLowerCase(),
+ IS_SAFARI = /(safari)[ \/]([\w.]+)/.exec(ua) && !/(chrome)[ \/]([\w.]+)/.exec(ua);
+
+
+// esc button
+bean.on(document, "fullscreenchange.ffscr webkitfullscreenchange.ffscr mozfullscreenchange.ffscr MSFullscreenChange.ffscr", function(e) {
+ var el = document.webkitCurrentFullScreenElement || document.mozFullScreenElement || document.fullscreenElement || document.msFullscreenElement || e.target;
+ if (!FULL_PLAYER && (!el.parentNode || !el.parentNode.getAttribute('data-flowplayer-instance-id'))) return;
+ var player = FULL_PLAYER || flowplayer(el.parentNode);
+ if (el && !FULL_PLAYER) {
+ FULL_PLAYER = player.trigger(FS_ENTER, [el]);
+ } else {
+ FULL_PLAYER.trigger(FS_EXIT, [FULL_PLAYER]);
+ FULL_PLAYER = null;
+ }
+ });
+
+flowplayer(function(player, root) {
+
+ var wrapper = common.createElement('div', {className: 'fp-player'});
+ Array.prototype.map.call(root.children, common.identity).forEach(function(el) {
+ if (common.matches(el, '.fp-ratio,script')) return;
+ wrapper.appendChild(el);
+ });
+ root.appendChild(wrapper);
+
+ if (!player.conf.fullscreen) return;
+
+ var win = window,
+ scrollY,
+ scrollX,
+ rootClasses = ClassList(root);
+
+ player.isFullscreen = false;
+
+ player.fullscreen = function(flag) {
+
+ if (player.disabled) return;
+
+ if (flag === undefined) flag = !player.isFullscreen;
+
+ if (flag) {
+ scrollY = win.scrollY;
+ scrollX = win.scrollX;
+ }
+
+ if (FS_SUPPORT) {
+
+ if (flag) {
+ ['requestFullScreen', 'webkitRequestFullScreen', 'mozRequestFullScreen', 'msRequestFullscreen'].forEach(function(fName) {
+ if (typeof wrapper[fName] === 'function') {
+ wrapper[fName](Element.ALLOW_KEYBOARD_INPUT);
+ if (IS_SAFARI && !document.webkitCurrentFullScreenElement && !document.mozFullScreenElement) { // Element.ALLOW_KEYBOARD_INPUT not allowed
+ wrapper[fName]();
+ }
+ return false;
+ }
+ });
+
+ } else {
+ ['exitFullscreen', 'webkitCancelFullScreen', 'mozCancelFullScreen', 'msExitFullscreen'].forEach(function(fName) {
+ if (typeof document[fName] === 'function') {
+ document[fName]();
+ return false;
+ }
+ });
+ }
+
+ } else {
+ player.trigger(flag ? FS_ENTER : FS_EXIT, [player]);
+ }
+
+ return player;
+ };
+
+ var lastClick;
+
+ player.on("mousedown.fs", function() {
+ if (+new Date() - lastClick < 150 && player.ready) player.fullscreen();
+ lastClick = +new Date();
+ });
+
+ player.on(FS_ENTER, function(e) {
+ rootClasses.add("is-fullscreen");
+ if (!FS_SUPPORT) common.css(root, 'position', 'fixed');
+ player.isFullscreen = true;
+
+ }).on(FS_EXIT, function(e) {
+ var oldOpacity;
+ if (!FS_SUPPORT && player.engine === "html5") {
+ oldOpacity = root.css('opacity') || '';
+ common.css(root, 'opacity', 0);
+ }
+ if (!FS_SUPPORT) common.css(root, 'position', '');
+ rootClasses.remove("is-fullscreen");
+ if (!FS_SUPPORT && player.engine === "html5") setTimeout(function() { root.css('opacity', oldOpacity); });
+ player.isFullscreen = false;
+ win.scrollTo(scrollX, scrollY);
+ }).on('unload', function() {
+ if (player.isFullscreen) player.fullscreen();
+ });
+
+ player.on('shutdown', function() {
+ bean.off(document, '.ffscr');
+ FULL_PLAYER = null;
+ });
+
+});
+
+},{"../common":1,"../flowplayer":18,"bean":20,"class-list":22,"extend-object":26}],10:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ bean = _dereq_('bean'),
+ focused,
+ focusedRoot,
+ IS_HELP = "is-help",
+ common = _dereq_('../common'),
+ ClassList = _dereq_('class-list');
+
+ // keyboard. single global listener
+bean.on(document, "keydown.fp", function(e) {
+
+ var el = focused,
+ metaKeyPressed = e.ctrlKey || e.metaKey || e.altKey,
+ key = e.which,
+ conf = el && el.conf,
+ focusedRootClasses = focusedRoot && ClassList(focusedRoot);
+
+ if (!el || !conf.keyboard || el.disabled) return;
+
+ // help dialog (shift key not truly required)
+ if ([63, 187, 191].indexOf(key) != -1) {
+ focusedRootClasses.toggle(IS_HELP);
+ return false;
+ }
+
+ // close help / unload
+ if (key == 27 && focusedRootClasses.contains(IS_HELP)) {
+ focusedRootClasses.toggle(IS_HELP);
+ return false;
+ }
+
+ if (!metaKeyPressed && el.ready) {
+
+ e.preventDefault();
+
+ // slow motion / fast forward
+ if (e.shiftKey) {
+ if (key == 39) el.speed(true);
+ else if (key == 37) el.speed(false);
+ return;
+ }
+
+ // 1, 2, 3, 4 ..
+ if (key < 58 && key > 47) return el.seekTo(key - 48);
+
+ switch (key) {
+ case 38: case 75: el.volume(el.volumeLevel + 0.15); break; // volume up
+ case 40: case 74: el.volume(el.volumeLevel - 0.15); break; // volume down
+ case 39: case 76: el.seeking = true; el.seek(true); break; // forward
+ case 37: case 72: el.seeking = true; el.seek(false); break; // backward
+ case 190: el.seekTo(); break; // to last seek position
+ case 32: el.toggle(); break; // spacebar
+ case 70: if(conf.fullscreen) el.fullscreen(); break; // toggle fullscreen
+ case 77: el.mute(); break; // mute
+ case 81: el.unload(); break; // unload/stop
+ }
+
+ }
+
+});
+
+flowplayer(function(api, root) {
+
+ // no keyboard configured
+ if (!api.conf.keyboard) return;
+
+ // hover
+ bean.on(root, "mouseenter mouseleave", function(e) {
+ focused = !api.disabled && e.type == 'mouseover' ? api : 0;
+ if (focused) focusedRoot = root;
+ });
+
+ var speedhelp = flowplayer.support.video && api.conf.engine !== "flash" &&
+ !!document.createElement('video').playbackRate ?
+ 'shift + ← → slower / faster
' : '';
+
+ // TODO: add to player-layout.html
+ root.appendChild(common.createElement('div', { className: 'fp-help' }, '\
+ \
+ \
+
space play / pause
\
+
q unload | stop
\
+
f fullscreen
' + speedhelp + '\
+
\
+ \
+ \
+
← → seek
\
+
. seek to previous\
+
1 2 … 6 seek to 10%, 20% … 60%
\
+
\
+ '));
+
+ if (api.conf.tooltip) {
+ var ui = common.find('.fp-ui', root)[0];
+ ui.setAttribute('title', 'Hit ? for help');
+ bean.one(root, "mouseout.tip", '.fp-ui', function() {
+ ui.removeAttribute('title');
+ });
+ }
+
+ bean.on(root, 'click', '.fp-close', function() {
+ ClassList(root).toggle(IS_HELP);
+ });
+
+ api.bind('shutdown', function() {
+ if (focusedRoot == root) focusedRoot = null;
+ });
+
+});
+
+
+},{"../common":1,"../flowplayer":18,"bean":20,"class-list":22}],11:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ isIeMobile = /IEMobile/.test(window.navigator.userAgent),
+ ClassList = _dereq_('class-list'),
+ common = _dereq_('../common'),
+ bean = _dereq_('bean'),
+ format = _dereq_('./ui').format,
+ UA = window.navigator.userAgent;
+if (flowplayer.support.touch || isIeMobile) {
+
+ flowplayer(function(player, root) {
+ var isAndroid = /Android/.test(UA) && !/Firefox/.test(UA) && !/Opera/.test(UA),
+ isSilk = /Silk/.test(UA),
+ androidVer = isAndroid ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0,
+ rootClasses = ClassList(root);
+
+ // custom load for android
+ if (isAndroid && !isIeMobile) {
+ if (!/Chrome/.test(UA) && androidVer < 4) {
+ var originalLoad = player.load;
+ player.load = function(video, callback) {
+ var ret = originalLoad.apply(player, arguments);
+ player.trigger('ready', [player, player.video]);
+ return ret;
+ };
+ }
+ var timer, currentTime = 0;
+ var resumeTimer = function(api) {
+ timer = setInterval(function() {
+ api.video.time = ++currentTime;
+ api.trigger('progress', [api, currentTime]);
+ }, 1000);
+ };
+ player.bind('ready pause unload', function() {
+ if (timer) {
+ clearInterval(timer);
+ timer = null;
+ }
+ });
+ player.bind('ready', function() {
+ currentTime = 0;
+ });
+ player.bind('resume', function(ev, api) {
+ if (!api.live) return;
+ if (currentTime) { return resumeTimer(api); }
+ player.one('progress', function(ev, api, t) {
+ if (t === 0) { // https://github.com/flowplayer/flowplayer/issues/727
+ resumeTimer(api);
+ }
+ });
+ });
+ }
+
+ // hide volume
+ if (!flowplayer.support.volume) {
+ rootClasses.add("no-volume");
+ rootClasses.add("no-mute");
+ }
+ rootClasses.add("is-touch");
+ if (player.sliders && player.sliders.timeline) player.sliders.timeline.disableAnimation();
+
+ if (!flowplayer.support.inlineVideo || player.conf.native_fullscreen) player.conf.nativesubtitles = true;
+
+ // fake mouseover effect with click
+ var hasMoved = false;
+ bean.on(root, 'touchmove', function() {
+ hasMoved = true;
+ });
+ bean.on(root, 'touchend click', function(e) {
+ if (hasMoved) { //not intentional, most likely scrolling
+ hasMoved = false;
+ return;
+ }
+
+ if (player.playing && !rootClasses.contains("is-mouseover")) {
+ rootClasses.add("is-mouseover");
+ rootClasses.remove("is-mouseout");
+ e.preventDefault();
+ e.stopPropagation();
+ return;
+ }
+
+ if (!player.playing && !player.splash && rootClasses.contains('is-mouseout') && !rootClasses.contains('is-mouseover')) {
+ setTimeout(function() {
+ if (!player.playing && !player.splash) {
+ player.resume();
+ }
+ }, 400);
+ }
+
+
+ });
+
+ // native fullscreen
+ if (player.conf.native_fullscreen && typeof document.createElement('video').webkitEnterFullScreen === 'function') {
+ player.fullscreen = function() {
+ var video = common.find('video.fp-engine', root)[0];
+ video.webkitEnterFullScreen();
+ bean.one(video, 'webkitendfullscreen', function() {
+ common.prop(video, 'controls', true);
+ common.prop(video, 'controls', false);
+ });
+ };
+ }
+
+
+ // Android browser gives video.duration == 1 until second 'timeupdate' event
+ if (isAndroid || isSilk) player.bind("ready", function() {
+
+ var video = common.find('video.fp-engine', root)[0];
+ bean.one(video, 'canplay', function() {
+ video.play();
+ });
+ video.play();
+
+ player.bind("progress.dur", function() {
+
+ var duration = video.duration;
+
+ if (duration !== 1) {
+ player.video.duration = duration;
+ common.find(".fp-duration", root)[0].innerHTML = format(duration);
+ player.unbind("progress.dur");
+ }
+ });
+ });
+
+
+ });
+
+}
+
+
+},{"../common":1,"../flowplayer":18,"./ui":17,"bean":20,"class-list":22}],12:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ extend = _dereq_('extend-object'),
+ bean = _dereq_('bean'),
+ ClassList = _dereq_('class-list'),
+ common = _dereq_('../common'),
+ Resolve = _dereq_('./resolve'),
+ resolver = new Resolve(),
+ $ = window.jQuery,
+ externalRe = /^#/;
+flowplayer(function(player, root) {
+
+ var conf = extend({ active: 'is-active', advance: true, query: ".fp-playlist a" }, player.conf),
+ klass = conf.active, rootClasses = ClassList(root);
+
+ // getters
+ function els() {
+ return common.find(conf.query, queryRoot());
+ }
+
+ function queryRoot() {
+ if (externalRe.test(conf.query)) return;
+ return root;
+ }
+
+ function active() {
+ return common.find(conf.query + "." + klass, queryRoot());
+ }
+
+
+ player.play = function(i) {
+ if (i === undefined) return player.resume();
+ if (typeof i === 'number' && !player.conf.playlist[i]) return player;
+ else if (typeof i != 'number') return player.load.apply(null, arguments);
+ var arg = extend({index: i}, player.conf.playlist[i]);
+ if (i === player.video.index) return player.load(arg, function() { player.resume(); });
+ player.off('resume.fromfirst'); // Don't start from beginning if clip explicitely chosen
+ player.load(arg, function() {
+ player.video.index = i;
+ });
+ return player;
+ };
+
+ player.next = function(e) {
+ if (e) e.preventDefault();
+ var current = player.video.index;
+ if (current != -1) {
+ current = current === player.conf.playlist.length - 1 ? 0 : current + 1;
+ player.play(current);
+ }
+ return player;
+ };
+
+ player.prev = function(e) {
+ if (e) e.preventDefault();
+ var current = player.video.index;
+ if (current != -1) {
+ current = current === 0 ? player.conf.playlist.length - 1 : current - 1;
+ player.play(current);
+ }
+ return player;
+ };
+
+ player.setPlaylist = function(items) {
+ player.conf.playlist = items;
+ delete player.video.index;
+ generatePlaylist();
+ return player;
+ };
+
+ player.addPlaylistItem = function(item) {
+ return player.setPlaylist(player.conf.playlist.concat([item]));
+ };
+
+ player.removePlaylistItem = function(idx) {
+ var pl = player.conf.playlist;
+ return player.setPlaylist(pl.slice(0, idx).concat(pl.slice(idx+1)));
+ };
+
+ bean.on(root, 'click', '.fp-next', player.next);
+ bean.on(root, 'click', '.fp-prev', player.prev);
+
+ if (conf.advance) {
+ player.off("finish.pl").on("finish.pl", function(e, player) {
+ // clip looping
+ if (player.video.loop) return player.seek(0, function() { player.resume(); });
+ // next clip is found or loop
+ var next = player.video.index >= 0 ? player.video.index + 1 : undefined;
+ if (next < player.conf.playlist.length || conf.loop) {
+ next = next === player.conf.playlist.length ? 0 : next;
+ rootClasses.remove('is-finished');
+ setTimeout(function() { // Let other finish callbacks fire first
+ player.play(next);
+ });
+
+ // stop to last clip, play button starts from 1:st clip
+ } else {
+
+ // If we have multiple items in playlist, start from first
+ if (player.conf.playlist.length > 1) player.one("resume.fromfirst", function() {
+ player.play(0);
+ return false;
+ });
+ }
+ });
+ }
+
+ function generatePlaylist() {
+ var plEl = common.find('.fp-playlist', root)[0];
+ if (!plEl) {
+ plEl = common.createElement('div', {className: 'fp-playlist'});
+ var cntrls = common.find('.fp-next,.fp-prev', root);
+ if (!cntrls.length) common.insertAfter(root, common.find('video', root)[0], plEl);
+ else cntrls[0].parentElement.insertBefore(plEl, cntrls[0]);
+ }
+ plEl.innerHTML = '';
+ if (player.conf.playlist[0].length) { // FP5 style playlist
+ player.conf.playlist = player.conf.playlist.map(function(itm) {
+ if (typeof itm === 'string') {
+ var type = itm.split(Resolve.TYPE_RE)[1];
+ return {
+ sources: [{
+ type: type.toLowerCase() === 'm3u8' ? 'application/x-mpegurl' : 'video/' + type,
+ src: itm
+ }]
+ };
+ }
+ return {
+ sources: itm.map(function(src) {
+ var s = {};
+ Object.keys(src).forEach(function(k) {
+ s.type = /mpegurl/i.test(k) ? 'application/x-mpegurl' : 'video/' + k;
+ s.src = src[k];
+ });
+ return s;
+ })
+ };
+ });
+ }
+ player.conf.playlist.forEach(function(item, i) {
+ var href = item.sources[0].src;
+ plEl.appendChild(common.createElement('a', {
+ href: href,
+ 'data-index': i
+ }));
+ });
+ }
+
+ var playlistInitialized = false;
+ if (player.conf.playlist.length) { // playlist configured by javascript, generate playlist
+ playlistInitialized = true;
+ generatePlaylist();
+ if (!player.conf.clip || !player.conf.clip.sources.length) player.conf.clip = player.conf.playlist[0];
+ }
+
+ if (els().length && !playlistInitialized) { //generate playlist from existing elements
+ player.conf.playlist = [];
+ els().forEach(function(el) {
+ var src = el.href;
+ el.setAttribute('data-index', player.conf.playlist.length);
+ var itm = resolver.resolve(src, player.conf.clip.sources);
+ if ($) {
+ extend(itm, $(el).data());
+ }
+ player.conf.playlist.push(itm);
+ });
+ }
+
+ /* click -> play */
+ bean.on(externalRe.test(conf.query) ? document : root, "click", conf.query, function(e) {
+ e.preventDefault();
+ var el = e.currentTarget;
+ var toPlay = Number(el.getAttribute('data-index'));
+ if (toPlay != -1) {
+ player.play(toPlay);
+ }
+ });
+
+ // highlight
+ player.on("load", function(e, api, video) {
+ if (!player.conf.playlist.length) return;
+ var prev = active()[0],
+ prevIndex = prev && prev.getAttribute('data-index'),
+ index = video.index = video.index || player.video.index || 0,
+ el = common.find(conf.query +'[data-index="' + index + '"]', queryRoot())[0],
+ is_last = index == player.conf.playlist.length - 1;
+ if (prev) ClassList(prev).remove(klass);
+ if (el) ClassList(el).add(klass);
+ // index
+ rootClasses.remove("video" + prevIndex);
+ rootClasses.add("video" + index);
+ common.toggleClass(root, "last-video", is_last);
+
+ // video properties
+ video.index = api.video.index = index;
+ video.is_last = api.video.is_last = is_last;
+
+ // without namespace callback called only once. unknown rason.
+ }).on("unload.pl", function() {
+ if (!player.conf.playlist.length) return;
+ active().forEach(function(el) {
+ ClassList(el).toggle(klass);
+ });
+ player.conf.playlist.forEach(function(itm, i) {
+ rootClasses.remove('video' + i);
+ });
+ });
+
+ if (player.conf.playlist.length) {
+ // disable single clip looping
+ player.conf.loop = false;
+ }
+
+
+});
+
+},{"../common":1,"../flowplayer":18,"./resolve":13,"bean":20,"class-list":22,"extend-object":26}],13:[function(_dereq_,module,exports){
+'use strict';
+var TYPE_RE = /\.(\w{3,4})(\?.*)?$/i,
+ extend = _dereq_('extend-object');
+
+function parseSource(el) {
+
+ var src = el.attr("src"),
+ type = el.attr("type") || "",
+ suffix = src.split(TYPE_RE)[1];
+ type = type.toLowerCase();
+ return extend(el.data(), { src: src, suffix: suffix || type, type: type || suffix });
+}
+
+function getType(typ) {
+ if (/mpegurl/i.test(typ)) return 'application/x-mpegurl';
+ return 'video/' + typ;
+}
+
+/* Resolves video object from initial configuration and from load() method */
+module.exports = function URLResolver() {
+ var self = this;
+
+ self.sourcesFromVideoTag = function(videoTag, $) {
+ /* global $ */
+ var sources = [];
+ // initial sources
+ $("source", videoTag).each(function() {
+ sources.push(parseSource($(this)));
+ });
+
+ if (!sources.length && videoTag.length) sources.push(parseSource(videoTag));
+
+ return sources;
+ };
+
+
+ self.resolve = function(video, sources) {
+ if (!video) return { sources: sources };
+
+ if (typeof video == 'string') {
+ video = { src: video, sources: [] };
+ video.sources = (sources || []).map(function(source) {
+ var suffix = source.src.split(TYPE_RE)[1];
+ return {type: source.type, src: video.src.replace(TYPE_RE, '.' + suffix + "$2")};
+ });
+ }
+
+ if (video instanceof Array) {
+ video = {
+ sources: video.map(function(src) {
+ if (src.type && src.src) return src;
+ return Object.keys(src).reduce(function(m, typ) {
+ return extend(m, {
+ type: getType(typ),
+ src: src[typ]
+ });
+ }, {});
+ })
+ };
+ }
+
+ return video;
+ };
+};
+
+module.exports.TYPE_RE = TYPE_RE;
+
+},{"extend-object":26}],14:[function(_dereq_,module,exports){
+'use strict';
+// skip IE policies
+// document.ondragstart = function () { return false; };
+//
+var ClassList = _dereq_('class-list'),
+ bean = _dereq_('bean'),
+ common = _dereq_('../common');
+
+
+// execute function every ms
+var throttle = function(fn, delay) {
+ var locked;
+
+ return function () {
+ if (!locked) {
+ fn.apply(this, arguments);
+ locked = 1;
+ setTimeout(function () { locked = 0; }, delay);
+ }
+ };
+};
+
+
+var slider = function(root, rtl) {
+ var IS_IPAD = /iPad/.test(navigator.userAgent) && !/CriOS/.test(navigator.userAgent);
+
+ var progress = common.lastChild(root),
+ rootClasses = ClassList(root),
+ progressClasses = ClassList(progress),
+ disabled,
+ offset,
+ width,
+ height,
+ vertical,
+ size,
+ maxValue,
+ max,
+ skipAnimation = false,
+
+ /* private */
+ calc = function() {
+ offset = common.offset(root);
+ width = common.width(root);
+ height = common.height(root);
+
+ /* exit from fullscreen can mess this up.*/
+ // vertical = height > width;
+
+ size = vertical ? height : width;
+ max = toDelta(maxValue);
+ },
+
+ fire = function(value) {
+ if (!disabled && value != api.value && (!maxValue || value < maxValue)) {
+ bean.fire(root, 'slide', [ value ]);
+ api.value = value;
+ }
+ },
+
+ mousemove = function(e) {
+ var pageX = e.pageX || e.clientX;
+ if (!pageX && e.originalEvent && e.originalEvent.touches && e.originalEvent.touches.length) {
+ pageX = e.originalEvent.touches[0].pageX;
+ }
+ var delta = vertical ? e.pageY - offset.top : pageX - offset.left;
+ delta = Math.max(0, Math.min(max || size, delta));
+
+ var value = delta / size;
+ if (vertical) value = 1 - value;
+ if (rtl) value = 1 - value;
+ return move(value, 0, true);
+ },
+
+ move = function(value, speed) {
+ if (speed === undefined) { speed = 0; }
+ if (value > 1) value = 1;
+
+ var to = (Math.round(value * 1000) / 10) + "%";
+
+ if (!maxValue || value <= maxValue) {
+ progressClasses.remove('animated');
+ if (skipAnimation) {
+ progressClasses.remove('animated');
+ } else {
+ progressClasses.add('animated');
+ common.css(progress, 'transition-duration', (speed || 0) + 'ms');
+ }
+ common.css(progress, 'width', to);
+ }
+
+ return value;
+ },
+
+ toDelta = function(value) {
+ return Math.max(0, Math.min(size, vertical ? (1 - value) * height : value * width));
+ },
+
+ /* public */
+ api = {
+
+ max: function(value) {
+ maxValue = value;
+ },
+
+ disable: function(flag) {
+ disabled = flag;
+ },
+
+ slide: function(value, speed, fireEvent) {
+ calc();
+ if (fireEvent) fire(value);
+ move(value, speed);
+ },
+
+ // Should animation be handled via css
+ disableAnimation: function(value, alsoCssAnimations) {
+ skipAnimation = value !== false;
+ common.toggleClass(root, 'no-animation', !!alsoCssAnimations);
+ }
+
+ };
+
+ calc();
+
+ // bound dragging into document
+ bean.on(root, 'mousedown.sld touchstart', function(e) {
+ e.preventDefault();
+
+ if (!disabled) {
+ // begin --> recalculate. allows dynamic resizing of the slider
+ var delayedFire = throttle(fire, 100);
+ calc();
+ api.dragging = true;
+ rootClasses.add('is-dragging');
+ fire(mousemove(e));
+
+ bean.on(document, 'mousemove.sld touchmove.sld', function(e) {
+ e.preventDefault();
+ delayedFire(mousemove(e));
+
+ });
+ bean.one(document, 'mouseup touchend', function() {
+ api.dragging = false;
+ rootClasses.remove('is-dragging');
+ bean.off(document, 'mousemove.sld touchmove.sld');
+ });
+
+ }
+
+ });
+ return api;
+};
+
+module.exports = slider;
+
+},{"../common":1,"bean":20,"class-list":22}],15:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ common = _dereq_('../common'),
+ bean = _dereq_('bean'),
+ ClassList = _dereq_('class-list');
+
+flowplayer.defaults.subtitleParser = function(txt) {
+ var TIMECODE_RE = /^(([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3}) --\> (([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3})(.*)/;
+
+ function seconds(timecode) {
+ var els = timecode.split(':');
+ if (els.length == 2) els.unshift(0);
+ return els[0] * 60 * 60 + els[1] * 60 + parseFloat(els[2].replace(',','.'));
+ }
+
+ var entries = [];
+ for (var i = 0, lines = txt.split("\n"), len = lines.length, entry = {}, title, timecode, text, cue; i < len; i++) {
+ timecode = TIMECODE_RE.exec(lines[i]);
+
+ if (timecode) {
+
+ // title
+ title = lines[i - 1];
+
+ // text
+ text = "" + lines[++i] + "
";
+ while (typeof lines[++i] === 'string' && lines[i].trim() && i < lines.length) text += "" + lines[i] + "
";
+
+ // entry
+ entry = {
+ title: title,
+ startTime: seconds(timecode[1]),
+ endTime: seconds(timecode[3]),
+ text: text
+ };
+ entries.push(entry);
+ }
+ }
+ return entries;
+};
+
+flowplayer(function(p, root) {
+ var wrapClasses, currentPoint, wrap,
+ rootClasses = ClassList(root),
+ subtitleControl;
+
+ var createSubtitleControl = function() {
+ subtitleControl = common.createElement('a', {className: 'fp-menu'});
+ var menu = common.createElement('ul', {className: 'fp-dropdown fp-dropup'});
+ menu.appendChild(common.createElement('li', {'data-subtitle-index': -1}, 'No subtitles'));
+ (p.video.subtitles || []).forEach(function(st, i) {
+ var srcLang = st.srclang || 'en',
+ label = st.label || 'Default (' + srcLang + ')';
+ var item = common.createElement('li', {'data-subtitle-index': i}, label);
+ menu.appendChild(item);
+ });
+ subtitleControl.appendChild(menu);
+ common.find('.fp-controls', root)[0].appendChild(subtitleControl);
+ return subtitleControl;
+ };
+
+ bean.on(root, 'click', '.fp-menu', function(ev) {
+ ClassList(subtitleControl).toggle('dropdown-open');
+ });
+
+ bean.on(root, 'click', '.fp-menu li[data-subtitle-index]', function(ev) {
+ var idx = ev.target.getAttribute('data-subtitle-index');
+ if (idx === '-1') return p.disableSubtitles();
+ p.loadSubtitles(idx);
+ });
+
+ var createUIElements = function() {
+ var playerEl = common.find('.fp-player', root)[0];
+ wrap = common.find('.fp-subtitle', root)[0];
+ wrap = wrap || common.appendTo(common.createElement('div', {'class': 'fp-subtitle'}), playerEl);
+ Array.prototype.forEach.call(wrap.children, common.removeNode);
+ wrapClasses = ClassList(wrap);
+ common.find('.fp-menu', root).forEach(common.removeNode);
+ createSubtitleControl();
+ };
+
+
+ p.on('ready', function(ev, player, video) {
+ var conf = player.conf;
+ if (flowplayer.support.subtitles && conf.nativesubtitles && player.engine.engineName == 'html5') {
+ var setMode = function(mode) {
+ var tracks = common.find('video', root)[0].textTracks;
+ if (!tracks.length) return;
+ tracks[0].mode = mode;
+ };
+ if (!video.subtitles || !video.subtitles.length) return;
+ var videoTag = common.find('video.fp-engine', root)[0];
+ video.subtitles.forEach(function(st) {
+ videoTag.appendChild(common.createElement('track', {
+ kind: 'subtitles',
+ srclang: st.srclang || 'en',
+ label: st.label || 'en',
+ src: st.src,
+ 'default': st['default']
+ }));
+ });
+ setMode('disabled');
+ setMode('showing');
+ return;
+ }
+
+ player.subtitles = [];
+
+ createUIElements();
+
+ rootClasses.remove('has-menu');
+
+ p.disableSubtitles();
+
+ if (!video.subtitles || !video.subtitles.length) return;
+
+ rootClasses.add('has-menu');
+ var defaultSubtitle = video.subtitles.filter(function(one) {
+ return one['default'];
+ })[0];
+ if (defaultSubtitle) player.loadSubtitles(video.subtitles.indexOf(defaultSubtitle));
+ });
+
+ p.bind("cuepoint", function(e, api, cue) {
+ if (cue.subtitle) {
+ currentPoint = cue.index;
+ common.html(wrap, cue.subtitle.text);
+ wrapClasses.add('fp-active');
+ } else if (cue.subtitleEnd) {
+ wrapClasses.remove('fp-active');
+ currentPoint = cue.index;
+ }
+ });
+
+ p.bind("seek", function(e, api, time) {
+ // Clear future subtitles if seeking backwards
+ if (currentPoint && p.cuepoints[currentPoint] && p.cuepoints[currentPoint].time > time) {
+ wrapClasses.remove('fp-active');
+ currentPoint = null;
+ }
+ (p.cuepoints || []).forEach(function(cue) {
+ var entry = cue.subtitle;
+ //Trigger cuepoint if start time before seek position and end time nonexistent or in the future
+ if (entry && currentPoint != cue.index) {
+ if (time >= cue.time && (!entry.endTime || time <= entry.endTime)) p.trigger("cuepoint", [p, cue]);
+ } // Also handle cuepoints that act as the removal trigger
+ else if (cue.subtitleEnd && time >= cue.time && cue.index == currentPoint + 1) p.trigger("cuepoint", [p, cue]);
+ });
+
+ });
+
+ var setActiveSubtitleClass = function(idx) {
+ common.toggleClass(common.find('li.active', root)[0], 'active');
+ common.toggleClass(common.find('li[data-subtitle-index="' + idx + '"]', root)[0], 'active');
+ };
+
+ p.disableSubtitles = function() {
+ p.subtitles = [];
+ (p.cuepoints || []).forEach(function(c) {
+ if (c.subtitle || c.subtitleEnd) p.removeCuepoint(c);
+ });
+ if (wrap) Array.prototype.forEach.call(wrap.children, common.removeNode);
+ setActiveSubtitleClass(-1);
+ return p;
+ };
+
+ p.loadSubtitles = function(i) {
+ //First remove possible old subtitles
+ p.disableSubtitles();
+
+ var st = p.video.subtitles[i];
+
+ var url = st.src;
+ if (!url) return;
+ setActiveSubtitleClass(i);
+ common.xhrGet(url, function(txt) {
+ var entries = p.conf.subtitleParser(txt);
+ entries.forEach(function(entry) {
+ var cue = { time: entry.startTime, subtitle: entry, visible: false };
+ p.subtitles.push(entry);
+ p.addCuepoint(cue);
+ p.addCuepoint({ time: entry.endTime, subtitleEnd: entry.title, visible: false });
+
+ // initial cuepoint
+ if (entry.startTime === 0 && !p.video.time) {
+ p.trigger("cuepoint", [p, cue]);
+ }
+ });
+ }, function() {
+ p.trigger("error", {code: 8, url: url });
+ return false;
+ });
+ return p;
+ };
+});
+
+
+},{"../common":1,"../flowplayer":18,"bean":20,"class-list":22}],16:[function(_dereq_,module,exports){
+'use strict';
+/* global ActiveXObject */
+var flowplayer = _dereq_('../flowplayer'),
+ extend = _dereq_('extend-object');
+(function() {
+
+ var parseIpadVersion = function(UA) {
+ var e = /Version\/(\d\.\d)/.exec(UA);
+ if (e && e.length > 1) {
+ return parseFloat(e[1], 10);
+ }
+ return 0;
+ };
+
+ var createVideoTag = function() {
+ var videoTag = document.createElement('video');
+ videoTag.loop = true;
+ videoTag.autoplay = true;
+ videoTag.preload = true;
+ return videoTag;
+ };
+
+ var b = {},
+ ua = navigator.userAgent.toLowerCase(),
+ match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
+ /(safari)[ \/]([\w.]+)/.exec(ua) ||
+ /(webkit)[ \/]([\w.]+)/.exec(ua) ||
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
+ /(msie) ([\w.]+)/.exec(ua) ||
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
+
+ if (match[1]) {
+ b[match[1]] = true;
+ b.version = match[2] || "0";
+ }
+
+ var video = createVideoTag(),
+ UA = navigator.userAgent,
+ IS_IE = b.msie || /Trident\/7/.test(UA),
+ IS_IPAD = /iPad|MeeGo/.test(UA) && !/CriOS/.test(UA),
+ IS_IPAD_CHROME = /iPad/.test(UA) && /CriOS/.test(UA),
+ IS_IPHONE = /iP(hone|od)/i.test(UA) && !/iPad/.test(UA) && !/IEMobile/i.test(UA),
+ IS_ANDROID = /Android/.test(UA) && !/Firefox/.test(UA),
+ IS_ANDROID_FIREFOX = /Android/.test(UA) && /Firefox/.test(UA),
+ IS_SILK = /Silk/.test(UA),
+ IS_WP = /IEMobile/.test(UA),
+ WP_VER = IS_WP ? parseFloat(/Windows\ Phone\ (\d+\.\d+)/.exec(UA)[1], 10) : 0,
+ IE_MOBILE_VER = IS_WP ? parseFloat(/IEMobile\/(\d+\.\d+)/.exec(UA)[1], 10) : 0,
+ IPAD_VER = IS_IPAD ? parseIpadVersion(UA) : 0,
+ ANDROID_VER = IS_ANDROID ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0,
+ s = extend(flowplayer.support, {
+
+ browser: b,
+ subtitles: !!video.addTextTrack,
+ fullscreen: typeof document.webkitCancelFullScreen == 'function' && !/Mac OS X 10_5.+Version\/5\.0\.\d Safari/.test(UA) ||
+ document.mozFullScreenEnabled ||
+ typeof document.exitFullscreen == 'function' ||
+ typeof document.msExitFullscreen == 'function',
+ inlineBlock: !(IS_IE && b.version < 8),
+ touch: ('ontouchstart' in window),
+ dataload: !IS_IPAD && !IS_IPHONE && !IS_WP,
+ zeropreload: !IS_IE && !IS_ANDROID, // IE supports only preload=metadata
+ volume: !IS_IPAD && !IS_ANDROID && !IS_IPHONE && !IS_SILK && !IS_IPAD_CHROME,
+ cachedVideoTag: !IS_IPAD && !IS_IPHONE && !IS_IPAD_CHROME && !IS_WP,
+ firstframe: !IS_IPHONE && !IS_IPAD && !IS_ANDROID && !IS_SILK && !IS_IPAD_CHROME && !IS_WP && !IS_ANDROID_FIREFOX,
+ inlineVideo: !IS_IPHONE && (!IS_WP || (WP_VER >= 8.1 && IE_MOBILE_VER >= 11)) && (!IS_ANDROID || ANDROID_VER >= 3),
+ hlsDuration: !IS_ANDROID && (!b.safari || IS_IPAD || IS_IPHONE || IS_IPAD_CHROME),
+ seekable: !IS_IPAD && !IS_IPAD_CHROME
+ });
+
+ // flashVideo
+ try {
+ var plugin = navigator.plugins["Shockwave Flash"],
+ ver = IS_IE ? new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable('$version') : plugin.description;
+ if (!IS_IE && !plugin[0].enabledPlugin) s.flashVideo = false;
+ else {
+
+ ver = ver.split(/\D+/);
+ if (ver.length && !ver[0]) ver = ver.slice(1);
+
+ s.flashVideo = ver[0] > 9 || ver[0] == 9 && ver[3] >= 115;
+ }
+
+ } catch (ignored) {}
+ try {
+ s.video = !!video.canPlayType;
+ if (s.video) video.canPlayType('video/mp4');
+ } catch (e) {
+ s.video = false;
+ }
+
+ // animation
+ s.animation = (function() {
+ var vendors = ['','Webkit','Moz','O','ms','Khtml'], el = document.createElement('p');
+
+ for (var i = 0; i < vendors.length; i++) {
+ if (typeof el.style[vendors[i] + 'AnimationName'] !== 'undefined') return true;
+ }
+ })();
+
+
+
+})();
+
+
+},{"../flowplayer":18,"extend-object":26}],17:[function(_dereq_,module,exports){
+'use strict';
+var flowplayer = _dereq_('../flowplayer'),
+ common = _dereq_('../common'),
+ ClassList = _dereq_('class-list'),
+ bean = _dereq_('bean'),
+ slider = _dereq_('./slider');
+
+function zeropad(val) {
+ val = parseInt(val, 10);
+ return val >= 10 ? val : "0" + val;
+}
+
+// display seconds in hh:mm:ss format
+function format(sec) {
+
+ sec = sec || 0;
+
+ var h = Math.floor(sec / 3600),
+ min = Math.floor(sec / 60);
+
+ sec = sec - (min * 60);
+
+ if (h >= 1) {
+ min -= h * 60;
+ return h + ":" + zeropad(min) + ":" + zeropad(sec);
+ }
+
+ return zeropad(min) + ":" + zeropad(sec);
+}
+
+flowplayer(function(api, root) {
+
+ var conf = api.conf,
+ support = flowplayer.support,
+ hovertimer,
+ rootClasses = ClassList(root);
+ common.find('.fp-ratio,.fp-ui', root).forEach(common.removeNode);
+ rootClasses.add('flowplayer');
+ root.appendChild(common.createElement('div', {className: 'fp-ratio'}));
+ var ui = common.createElement('div', {className: 'fp-ui'}, '\
+
\
+ \
+ \
+
\
+ \
+ \
+ 00:00 \
+ \
+ 00:00 \
+
\
+ '.replace(/class="/g, 'class="fp-'));
+ root.appendChild(ui);
+ function find(klass) {
+ return common.find(".fp-" + klass, root)[0];
+ }
+
+ // widgets
+ var progress = find("progress"),
+ buffer = find("buffer"),
+ elapsed = find("elapsed"),
+ remaining = find("remaining"),
+ waiting = find("waiting"),
+ ratio = find("ratio"),
+ speed = find("speed"),
+ speedClasses = ClassList(speed),
+ durationEl = find("duration"),
+ controls = find('controls'),
+ timelineTooltip = find('timeline-tooltip'),
+ origRatio = common.css(ratio, 'padding-top'),
+
+ // sliders
+ timeline = find("timeline"),
+ timelineApi = slider(timeline, api.rtl),
+
+ volume = find("volume"),
+ fullscreen = find("fullscreen"),
+ volumeSlider = find("volumeslider"),
+ volumeApi = slider(volumeSlider, api.rtl),
+ noToggle = rootClasses.contains('fixed-controls') || rootClasses.contains('no-toggle');
+
+ timelineApi.disableAnimation(rootClasses.contains('is-touch'));
+ api.sliders = api.sliders || {};
+ api.sliders.timeline = timelineApi;
+ api.sliders.volume = volumeApi;
+
+ // aspect ratio
+ function setRatio(val) {
+ common.css(ratio, 'padding-top', val * 100 + "%");
+ if (!support.inlineBlock) common.height(common.find('object', root)[0], common.height(root));
+ }
+
+ function hover(flag) {
+ if (flag) {
+ rootClasses.add('is-mouseover');
+ rootClasses.remove('is-mouseout');
+ } else {
+ rootClasses.add('is-mouseout');
+ rootClasses.remove('is-mouseover');
+ }
+ }
+
+ // loading...
+ if (!support.animation) common.html(waiting, "loading …
");
+
+ if (conf.ratio) setRatio(conf.ratio);
+
+ // no fullscreen in IFRAME
+ try {
+ if (!conf.fullscreen) common.removeNode(fullscreen);
+
+ } catch (e) {
+ common.removeNode(fullscreen);
+ }
+
+ api.on("ready", function(ev, api, video) {
+
+ var duration = api.video.duration;
+
+ timelineApi.disable(api.disabled || !duration);
+
+ if (conf.adaptiveRatio && !isNaN(video.height / video.width)) setRatio(video.height / video.width, true);
+
+ // initial time & volume
+ common.html([durationEl, remaining], format(duration));
+
+ // do we need additional space for showing hour
+ common.toggleClass(root, 'is-long', duration >= 3600);
+ volumeApi.slide(api.volumeLevel);
+
+ if (api.engine.engineName === 'flash') timelineApi.disableAnimation(true, true);
+ else timelineApi.disableAnimation(false);
+ common.find('.fp-title', ui).forEach(common.removeNode);
+ if (video.title) {
+ common.prepend(ui, common.createElement('div', {
+ className: 'fp-title'
+ }, video.title));
+ }
+
+
+ }).on("unload", function() {
+ if (!origRatio) common.css(ratio, "paddingTop", "");
+ timelineApi.slide(0);
+
+ // buffer
+ }).on("buffer", function() {
+ var video = api.video,
+ max = video.buffer / video.duration;
+
+ if (!video.seekable && support.seekable) timelineApi.max(max);
+ if (max < 1) common.css(buffer, "width", (max * 100) + "%");
+ else common.css(buffer, 'width', '100%');
+
+ }).on("speed", function(e, api, val) {
+ common.text(speed, val + "x");
+ speedClasses.add('fp-hilite');
+ setTimeout(function() { speedClasses.remove('fp-hilite'); }, 1000);
+
+ }).on("buffered", function() {
+ common.css(buffer, 'width', '100%');
+ timelineApi.max(1);
+
+ // progress
+ }).on("progress", function() {
+
+ var time = api.video.time,
+ duration = api.video.duration;
+
+ if (!timelineApi.dragging) {
+ timelineApi.slide(time / duration, api.seeking ? 0 : 250);
+ }
+
+ common.html(elapsed, format(time));
+ common.html(remaining, '-' + format(duration - time));
+
+ }).on("finish resume seek", function(e) {
+ common.toggleClass(root, "is-finished", e.type == "finish");
+
+ }).on("stop", function() {
+ common.html(elapsed, format(0));
+ timelineApi.slide(0, 100);
+
+ }).on("finish", function() {
+ common.html(elapsed, format(api.video.duration));
+ timelineApi.slide(1, 100);
+ rootClasses.remove('is-seeking');
+
+ // misc
+ }).on("beforeseek", function() {
+ //TODO FIXME
+ //progress.stop();
+
+ }).on("volume", function() {
+ volumeApi.slide(api.volumeLevel);
+
+
+ }).on("disable", function() {
+ var flag = api.disabled;
+ timelineApi.disable(flag);
+ volumeApi.disable(flag);
+ common.toggleClass(root, 'is-disabled', api.disabled);
+
+ }).on("mute", function(e, api, flag) {
+ common.toggleClass(root, 'is-muted', flag);
+
+ }).on("error", function(e, api, error) {
+ common.removeClass(root, 'is-loading');
+ common.addClass(root, 'is-error');
+ if (error) {
+ error.message = conf.errors[error.code];
+ api.error = true;
+
+ var el = common.find('.fp-message', root)[0],
+ video = error.video || api.video;
+ common.find('h2', el)[0].innerHTML = (api.engine && api.engine.engineName || 'html5') + ": " + error.message;
+ common.find('p', el)[0].innerHTML = error.url || video.url || video.src || conf.errorUrls[error.code];
+ api.off("mouseenter click");
+ rootClasses.remove('is-mouseover');
+ }
+
+
+ // hover
+ });
+ //Interaction events
+ bean.on(root, "mouseenter mouseleave", function(e) {
+ if (noToggle) return;
+
+ var is_over = e.type == "mouseover",
+ lastMove;
+
+ // is-mouseover/out
+ hover(is_over);
+
+ if (is_over) {
+
+ var reg = function() {
+ hover(true);
+ lastMove = new Date();
+ };
+ api.on("pause.x volume.x", reg);
+ bean.on(root, 'mousemove.x', reg);
+
+ hovertimer = setInterval(function() {
+ if (new Date() - lastMove > conf.mouseoutTimeout) {
+ hover(false);
+ lastMove = new Date();
+ }
+ }, 100);
+
+ } else {
+ bean.off(root, 'mousemove.x');
+ api.off("pause.x volume.x");
+ clearInterval(hovertimer);
+ }
+
+
+ // allow dragging over the player edge
+ });
+ bean.on(root, "mouseleave", function() {
+
+ if (timelineApi.dragging || volumeApi.dragging) {
+ rootClasses.add('is-mouseover');
+ rootClasses.remove('is-mouseout');
+ }
+
+ // click
+ });
+ bean.on(root, "click.player", function(e) {
+ if (api.disabled) return;
+ var kls = ClassList(e.target);
+ if (kls.contains('fp-ui') || kls.contains('fp-engine') || e.flash) {
+ if (e.preventDefault) e.preventDefault();
+ return api.toggle();
+ }
+ });
+
+ bean.on(root, 'mousemove', '.fp-timeline', function(ev) {
+ var x = ev.pageX || ev.clientX,
+ delta = x - common.offset(timeline).left,
+ percentage = delta / common.width(timeline),
+ seconds = percentage * api.video.duration;
+ if (percentage < 0) return;
+ common.html(timelineTooltip, format(seconds));
+ common.css(timelineTooltip, 'left', (x - common.offset(controls).left - common.width(timelineTooltip) / 2) + 'px');
+ });
+
+ bean.on(root, 'contextmenu', function(ev) {
+ var o = common.offset(common.find('.fp-player', root)[0]),
+ w = window,
+ left = ev.clientX - o.left,
+ t = ev.clientY - (o.top + w.scrollY);
+ var menu = common.find('.fp-context-menu', root)[0];
+ if (!menu) return;
+ ev.preventDefault();
+ common.css(menu,
+ {left: left + 'px',
+ top: t + 'px',
+ display: 'block'
+ });
+ bean.on(root, 'click', '.fp-context-menu', function(ev) {
+ ev.stopPropagation();
+ });
+ bean.on(document, 'click.outsidemenu', function(ev) {
+ common.css(menu, 'display', 'none');
+ bean.off(document, 'click.outsidemenu');
+ });
+ });
+ api.on('flashdisabled', function() {
+ rootClasses.add('is-flash-disabled');
+ api.one('ready', function() {
+ rootClasses.remove('is-flash-disabled');
+ common.find('.fp-flash-disabled', root).forEach(common.removeNode);
+ });
+ root.appendChild(common.createElement('div', {className: "fp-flash-disabled"}, 'Adobe Flash is disabled for this page, click player area to enable'));
+ });
+
+ // poster -> background image
+ if (conf.poster) common.css(root, 'background-image', "url(" + conf.poster + ")");
+
+ var bc = common.css(root, 'background-color'),
+ has_bg = common.css(root, 'background-image') != "none" || bc && bc != "rgba(0, 0, 0, 0)" && bc != "transparent";
+
+ // is-poster class
+ if (has_bg && !conf.splash && !conf.autoplay) {
+
+ api.on("ready stop", function() {
+ rootClasses.add("is-poster");
+ api.one("progress", function() {
+ rootClasses.remove("is-poster");
+ });
+ });
+
+ }
+
+ if (typeof conf.splash === 'string') {
+ common.css(root, 'background-image', "url('" + conf.splash + "')");
+ }
+
+ // default background color if not present
+ if (!has_bg && api.forcedSplash) {
+ common.css(root, "background-color", "#555");
+ }
+
+ bean.on(root, 'click', '.fp-toggle, .fp-play', function() {
+ if (api.disabled) return;
+ api.toggle();
+ });
+
+ /* controlbar elements */
+ bean.on(root, 'click', '.fp-mute', function() { api.mute(); });
+ bean.on(root, 'click', '.fp-fullscreen', function() { api.fullscreen(); });
+ bean.on(root, 'click', '.fp-unload', function() { api.unload(); });
+
+ bean.on(timeline, 'slide', function(val) {
+ api.seeking = true;
+ api.seek(val * api.video.duration);
+ });
+
+ bean.on(volumeSlider, 'slide', function(val) {
+ api.volume(val);
+ });
+
+ // times
+
+ var time = find('time');
+ bean.on(root, 'click', '.fp-time', function() {
+ ClassList(time).toggle('is-inverted');
+ });
+
+ hover(noToggle);
+
+ api.on('shutdown', function() {
+ bean.off(timeline);
+ bean.off(volumeSlider);
+ });
+
+});
+
+
+module.exports.format = format;
+
+},{"../common":1,"../flowplayer":18,"./slider":14,"bean":20,"class-list":22}],18:[function(_dereq_,module,exports){
+'use strict';
+var extend = _dereq_('extend-object'),
+ isFunction = _dereq_('is-function'),
+ ClassList = _dereq_('class-list'),
+ bean = _dereq_('bean'),
+ common = _dereq_('./common'),
+ events = _dereq_('./ext/events');
+
+var instances = [],
+ extensions = [],
+ UA = window.navigator.userAgent;
+
+
+var oldHandler = window.onbeforeunload;
+window.onbeforeunload = function(ev) {
+ instances.forEach(function(api) {
+ if (api.conf.splash) {
+ api.unload();
+ } else {
+ api.bind("error", function () {
+ common.find('.flowplayer.is-error .fp-message').forEach(common.removeNode);
+ });
+ }
+ });
+ if (oldHandler) return oldHandler(ev);
+};
+
+var supportLocalStorage = false;
+try {
+ if (typeof window.localStorage == "object") {
+ window.localStorage.flowplayerTestStorage = "test";
+ supportLocalStorage = true;
+ }
+} catch (ignored) {}
+
+var isSafari = /Safari/.exec(navigator.userAgent) && !/Chrome/.exec(navigator.userAgent),
+ m = /(\d+\.\d+) Safari/.exec(navigator.userAgent),
+ safariVersion = m ? Number(m[1]) : 100;
+
+/* flowplayer() */
+var flowplayer = module.exports = function(fn, opts, callback) {
+ if (isFunction(fn)) return extensions.push(fn);
+ if (typeof fn == 'number' || typeof fn === 'undefined') return instances[fn || 0];
+ if (fn.nodeType) { // Is an element
+ if (fn.getAttribute('data-flowplayer-instance-id') !== null) { // Already flowplayer instance
+ return instances[fn.getAttribute('data-flowplayer-instance-id')];
+ }
+ if (!opts) return; // Can't initialize without data
+ return initializePlayer(fn, opts, callback);
+ }
+ if (fn.jquery) return flowplayer(fn[0], opts, callback);
+ if (typeof fn === 'string') {
+ var el = common.find(fn)[0];
+ return el && flowplayer(el, opts, callback);
+ }
+};
+
+extend(flowplayer, {
+
+ version: '6.0.3',
+
+ engines: [],
+
+ conf: {},
+
+ set: function(key, value) {
+ if (typeof key === 'string') flowplayer.conf[key] = value;
+ else extend(flowplayer.conf, key);
+ },
+
+ support: {},
+
+ defaults: {
+
+ debug: supportLocalStorage ? !!localStorage.flowplayerDebug : false,
+
+ // true = forced playback
+ disabled: false,
+
+ fullscreen: window == window.top,
+
+ // keyboard shortcuts
+ keyboard: true,
+
+ // default aspect ratio
+ ratio: 9 / 16,
+
+ adaptiveRatio: false,
+
+ rtmp: 0,
+
+ proxy: 'best',
+
+ splash: false,
+
+ live: false,
+
+ swf: "//releases.flowplayer.org/6.0.3/flowplayer.swf",
+ swfHls: "//releases.flowplayer.org/6.0.3/flowplayerhls.swf",
+
+ speeds: [0.25, 0.5, 1, 1.5, 2],
+
+ tooltip: true,
+
+ mouseoutTimeout: 5000,
+
+ // initial volume level
+ volume: !supportLocalStorage ? 1 : localStorage.muted == "true" ? 0 : !isNaN(localStorage.volume) ? localStorage.volume || 1 : 1,
+
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#error-codes
+ errors: [
+
+ // video exceptions
+ '',
+ 'Video loading aborted',
+ 'Network error',
+ 'Video not properly encoded',
+ 'Video file not found',
+
+ // player exceptions
+ 'Unsupported video',
+ 'Skin not found',
+ 'SWF file not found',
+ 'Subtitles not found',
+ 'Invalid RTMP URL',
+ 'Unsupported video format. Try installing Adobe Flash.'
+ ],
+ errorUrls: ['','','','','','','','','','',
+ 'http://get.adobe.com/flashplayer/'
+ ],
+ playlist: [],
+
+ hlsFix: isSafari && safariVersion < 8
+
+ },
+ // Expose utilities for plugins
+ bean: bean,
+ common: common,
+ extend: extend
+
+
+
+});
+
+// keep track of players
+var playerCount = 0;
+
+var URLResolver = _dereq_('./ext/resolve');
+
+
+
+if (typeof window.jQuery !== 'undefined') {
+ var $ = window.jQuery;
+ // auto-install (any video tag with parent .flowplayer)
+ $(function() {
+ if (typeof $.fn.flowplayer == 'function') {
+ $('.flowplayer:has(video,script[type="application/json"])').flowplayer();
+ }
+ });
+
+ // jQuery plugin
+ var videoTagConfig = function(videoTag) {
+ if (!videoTag.length) return {};
+ var clip = videoTag.data() || {}, conf = {};
+ $.each(['autoplay', 'loop', 'preload', 'poster'], function(i, key) {
+ var val = videoTag.attr(key);
+ if (val !== undefined && ['autoplay', 'poster'].indexOf(key) !== -1) conf[key] = val ? val : true;
+ else if (val !== undefined) clip[key] = val ? val : true;
+ });
+ clip.subtitles = videoTag.find('track').map(function() {
+ var tr = $(this);
+ return {
+ src: tr.attr('src'),
+ kind: tr.attr('kind'),
+ label: tr.attr('label'),
+ srclang: tr.attr('srclang'),
+ 'default': tr.prop('default')
+ };
+ }).get();
+
+ clip.sources = (new URLResolver()).sourcesFromVideoTag(videoTag, $);
+ return extend(conf, {clip: clip});
+ };
+ $.fn.flowplayer = function(opts, callback) {
+ return this.each(function() {
+ if (typeof opts == 'string') opts = { swf: opts };
+ if (isFunction(opts)) { callback = opts; opts = {}; }
+ var root = $(this),
+ scriptConf = root.find('script[type="application/json"]'),
+ confObject = scriptConf.length ? JSON.parse(scriptConf.text()) : videoTagConfig(root.find('video')),
+ conf = $.extend({}, opts || {}, confObject, root.data());
+ var api = initializePlayer(this, conf, callback);
+ events.EVENTS.forEach(function(evName) {
+ api.on(evName + '.jquery', function(ev) {
+ root.trigger.call(root, ev.type, ev.detail && ev.detail.args);
+ });
+ });
+ root.data('flowplayer', api);
+ });
+ };
+}
+
+function initializePlayer(element, opts, callback) {
+ if (opts && opts.embed) opts.embed = extend({}, flowplayer.defaults.embed, opts.embed);
+
+ var root = element,
+ rootClasses = ClassList(root),
+ conf = extend({}, flowplayer.defaults, flowplayer.conf, opts),
+ storage = {},
+ lastSeekPosition,
+ engine,
+ url,
+ urlResolver = new URLResolver();
+
+ rootClasses.add('is-loading');
+
+ try {
+ storage = supportLocalStorage ? window.localStorage : storage;
+ } catch(e) {}
+
+ var isRTL = (root.currentStyle && root.currentStyle.direction === 'rtl') ||
+ (window.getComputedStyle && window.getComputedStyle(root, null) !== null && window.getComputedStyle(root, null).getPropertyValue('direction') === 'rtl');
+
+ if (isRTL) rootClasses.add('is-rtl');
+
+ /*** API ***/
+ var api = {
+
+ // properties
+ conf: conf,
+ currentSpeed: 1,
+ volumeLevel: conf.muted ? 0 : typeof conf.volume === "undefined" ? storage.volume * 1 : conf.volume,
+ video: {},
+
+ // states
+ disabled: false,
+ finished: false,
+ loading: false,
+ muted: storage.muted == "true" || conf.muted,
+ paused: false,
+ playing: false,
+ ready: false,
+ splash: false,
+ rtl: isRTL,
+
+ // methods
+ load: function(video, callback) {
+
+ if (api.error || api.loading) return;
+ api.video = {};
+
+ api.finished = false;
+
+ video = video || conf.clip;
+
+ // resolve URL
+ video = extend({}, urlResolver.resolve(video, conf.clip.sources));
+ if (api.playing || api.engine) video.autoplay = true;
+ var engineImpl = selectEngine(video);
+ if (!engineImpl) return api.trigger("error", [api, { code: flowplayer.support.flashVideo ? 5 : 10 }]);
+ if (!engineImpl.engineName) throw new Error('engineName property of factory should be exposed');
+ if (!api.engine || engineImpl.engineName !== api.engine.engineName) {
+ api.ready = false;
+ if (api.engine) {
+ api.engine.unload();
+ api.conf.autoplay = true;
+ }
+ engine = api.engine = engineImpl(api, root);
+ api.one('ready', function() {
+ engine.volume(api.volumeLevel);
+ });
+ }
+
+ extend(video, engine.pick(video.sources.filter(function(source) { // Filter out sources explicitely configured for some other engine
+ if (!source.engine) return true;
+ return source.engine === engine.engineName;
+ })));
+
+ if (video.src) {
+ video.src = common.createElement('a', {href: video.src}).href;
+ var e = api.trigger('load', [api, video, engine], true);
+ if (!e.defaultPrevented) {
+ engine.load(video);
+
+ // callback
+ if (isFunction(video)) callback = video;
+ if (callback) api.one("ready", callback);
+ } else {
+ api.loading = false;
+ }
+ }
+
+ return api;
+ },
+
+ pause: function(fn) {
+ if (api.ready && !api.seeking && !api.loading) {
+ engine.pause();
+ api.one("pause", fn);
+ }
+ return api;
+ },
+
+ resume: function() {
+
+ if (api.ready && api.paused) {
+ engine.resume();
+
+ // Firefox (+others?) does not fire "resume" after finish
+ if (api.finished) {
+ api.trigger("resume", [api]);
+ api.finished = false;
+ }
+ }
+
+ return api;
+ },
+
+ toggle: function() {
+ return api.ready ? api.paused ? api.resume() : api.pause() : api.load();
+ },
+
+ /*
+ seek(1.4) -> 1.4s time
+ seek(true) -> 10% forward
+ seek(false) -> 10% backward
+ */
+ seek: function(time, callback) {
+ if (api.ready && !api.live) {
+
+ if (typeof time == "boolean") {
+ var delta = api.video.duration * 0.1;
+ time = api.video.time + (time ? delta : -delta);
+ }
+ time = lastSeekPosition = Math.min(Math.max(time, 0), api.video.duration).toFixed(1);
+ var ev = api.trigger('beforeseek', [api, time], true);
+ if (!ev.defaultPrevented) {
+ engine.seek(time);
+ if (isFunction(callback)) api.one("seek", callback);
+ } else {
+ api.seeking = false;
+ common.toggleClass(root, 'is-seeking', api.seeking); // remove loading indicator
+ }
+ }
+ return api;
+ },
+
+ /*
+ seekTo(1) -> 10%
+ seekTo(2) -> 20%
+ seekTo(3) -> 30%
+ ...
+ seekTo() -> last position
+ */
+ seekTo: function(position, fn) {
+ var time = position === undefined ? lastSeekPosition : api.video.duration * 0.1 * position;
+ return api.seek(time, fn);
+ },
+
+ mute: function(flag, skipStore) {
+ if (flag === undefined) flag = !api.muted;
+ if (!skipStore) {
+ storage.muted = api.muted = flag;
+ storage.volume = !isNaN(storage.volume) ? storage.volume : conf.volume; // make sure storage has volume
+ }
+ api.volume(flag ? 0 : storage.volume, true);
+ api.trigger("mute", [api, flag]);
+ return api;
+ },
+
+ volume: function(level, skipStore) {
+ if (api.ready) {
+ level = Math.min(Math.max(level, 0), 1);
+ if (!skipStore) storage.volume = level;
+ engine.volume(level);
+ }
+
+ return api;
+ },
+
+ speed: function(val, callback) {
+
+ if (api.ready) {
+
+ // increase / decrease
+ if (typeof val == "boolean") {
+ val = conf.speeds[conf.speeds.indexOf(api.currentSpeed) + (val ? 1 : -1)] || api.currentSpeed;
+ }
+
+ engine.speed(val);
+ if (callback) root.one("speed", callback);
+ }
+
+ return api;
+ },
+
+
+ stop: function() {
+ if (api.ready) {
+ api.pause();
+ api.seek(0, function() {
+ api.trigger("stop");
+ });
+ }
+ return api;
+ },
+
+ unload: function() {
+ if (!rootClasses.contains("is-embedding")) {
+
+ if (conf.splash) {
+ api.trigger("unload", [api]);
+ if (engine) engine.unload();
+ } else {
+ api.stop();
+ }
+ }
+ return api;
+ },
+
+ shutdown: function() {
+ api.unload();
+ api.trigger('shutdown', [api]);
+ bean.off(root);
+ delete instances[root.getAttribute('data-flowplayer-instance-id')];
+ },
+
+ disable: function(flag) {
+ if (flag === undefined) flag = !api.disabled;
+
+ if (flag != api.disabled) {
+ api.disabled = flag;
+ api.trigger("disable", flag);
+ }
+ return api;
+ }
+
+ };
+
+ api.conf = extend(api.conf, conf);
+
+ /* event binding / unbinding */
+ events(api);
+
+ var selectEngine = function(clip) {
+ var engine;
+ var engines = flowplayer.engines;
+ if (conf.engine) {
+ var eng = engines.filter(function(e) { return e.engineName === conf.engine; })[0];
+ if (eng && clip.sources.some(function(source) {
+ if (source.engine && source.engine !== eng.engineName) return false;
+ return eng.canPlay(source.type, api.conf);
+ })) return eng;
+ }
+ if (conf.enginePreference) engines = flowplayer.engines.filter(function(one) { return conf.enginePreference.indexOf(one.engineName) > -1; }).sort(function(a, b) {
+ return conf.enginePreference.indexOf(a.engineName) - conf.enginePreference.indexOf(b.engineName);
+ });
+ clip.sources.some(function(source) {
+ var eng = engines.filter(function(engine) {
+ if (source.engine && source.engine !== engine.engineName) return false;
+ return engine.canPlay(source.type, api.conf);
+ }).shift();
+ if (eng) engine = eng;
+ return !!eng;
+ });
+ return engine;
+ };
+
+ /*** Behaviour ***/
+ if (!root.getAttribute('data-flowplayer-instance-id')) { // Only bind once
+ root.setAttribute('data-flowplayer-instance-id', playerCount++);
+
+
+ api.on('boot', function() {
+
+ // splash
+ if (conf.splash || rootClasses.contains("is-splash") || !flowplayer.support.firstframe) {
+ api.forcedSplash = !conf.splash && !rootClasses.contains("is-splash");
+ api.splash = conf.autoplay = true;
+ if (!conf.splash) conf.splash = true;
+ rootClasses.add("is-splash");
+ }
+
+ if (conf.splash) common.find('video', root).forEach(common.removeNode);
+
+ if (conf.live || rootClasses.contains('is-live')) {
+ api.live = conf.live = true;
+ rootClasses.add('is-live');
+ }
+
+ // extensions
+ extensions.forEach(function(e) {
+ e(api, root);
+ });
+
+ // instances
+ instances.push(api);
+
+ // start
+ if (conf.splash) api.unload(); else api.load();
+
+ // disabled
+ if (conf.disabled) api.disable();
+
+ // initial callback
+ api.one("ready", callback);
+
+
+ }).on("load", function(e, api, video) {
+
+ // unload others
+ if (conf.splash) {
+ common.find('.flowplayer.is-ready,.flowplayer.is-loading').forEach(function(el) {
+ var playerId = el.getAttribute('data-flowplayer-instance-id');
+ if (playerId === root.getAttribute('data-flowplayer-instance-id')) return;
+ var a = instances[Number(playerId)];
+ if (a && a.conf.splash) a.unload();
+ });
+
+ }
+
+ // loading
+ rootClasses.add("is-loading");
+ api.loading = true;
+
+ if (typeof video.live !== 'undefined') {
+ common.toggleClass(root, 'is-live', video.live);
+ api.live = video.live;
+ }
+
+
+ }).on("ready", function(e, api, video) {
+ video.time = 0;
+ api.video = video;
+
+ rootClasses.remove("is-loading");
+ api.loading = false;
+
+ // saved state
+ if (api.muted) api.mute(true, true);
+ else api.volume(api.volumeLevel);
+
+ // see https://github.com/flowplayer/flowplayer/issues/479
+
+ var hlsFix = api.conf.hlsFix && /mpegurl/i.exec(video.type);
+ common.toggleClass(root, 'hls-fix', !!hlsFix);
+
+ }).on("unload", function(e) {
+ rootClasses.remove("is-loading");
+ api.loading = false;
+
+
+ }).on("ready unload", function(e) {
+ var is_ready = e.type == "ready";
+ common.toggleClass(root, 'is-splash', !is_ready);
+ common.toggleClass(root, 'is-ready', is_ready);
+ api.ready = is_ready;
+ api.splash = !is_ready;
+
+
+ }).on("progress", function(e, api, time) {
+ api.video.time = time;
+
+
+ }).on("speed", function(e, api, val) {
+ api.currentSpeed = val;
+
+ }).on("volume", function(e, api, level) {
+ api.volumeLevel = Math.round(level * 100) / 100;
+ if (!api.muted) storage.volume = level;
+ else if (level) api.mute(false);
+
+
+ }).on("beforeseek seek", function(e) {
+ api.seeking = e.type == "beforeseek";
+ common.toggleClass(root, 'is-seeking', api.seeking);
+
+ }).on("ready pause resume unload finish stop", function(e, _api, video) {
+
+ // PAUSED: pause / finish
+ api.paused = /pause|finish|unload|stop/.test(e.type);
+ api.paused = api.paused || e.type === 'ready' && !conf.autoplay && !api.playing;
+
+ // the opposite
+ api.playing = !api.paused;
+
+ // CSS classes
+ common.toggleClass(root, 'is-paused', api.paused);
+ common.toggleClass(root, 'is-playing', api.playing);
+
+ // sanity check
+ if (!api.load.ed) api.pause();
+
+ }).on("finish", function(e) {
+ api.finished = true;
+
+ }).on("error", function() {
+ });
+ }
+
+ // boot
+ api.trigger('boot', [api, root]);
+ return api;
+}
+
+},{"./common":1,"./ext/events":8,"./ext/resolve":13,"bean":20,"class-list":22,"extend-object":26,"is-function":27}],19:[function(_dereq_,module,exports){
+//Flowplayer with extensions
+
+_dereq_('es5-shim');
+
+var flowplayer = module.exports = _dereq_('./flowplayer');
+//
+
+//Support needed before engines
+_dereq_('./ext/support');
+
+//Engines
+_dereq_('./engine/embed');
+_dereq_('./engine/html5');
+_dereq_('./engine/flash');
+
+//Extensions
+//require('./ext/slider'); //TODO enable
+_dereq_('./ext/ui');
+_dereq_('./ext/keyboard');
+_dereq_('./ext/playlist');
+_dereq_('./ext/cuepoint');
+_dereq_('./ext/subtitle');
+_dereq_('./ext/analytics');
+_dereq_('./ext/embed');
+//Have to add fullscreen last
+_dereq_('./ext/fullscreen');
+
+_dereq_('./ext/mobile');
+flowplayer(function(e,o){function a(e){var o=document.createElement("a");return o.href=e,t.hostname(o.hostname)}var n=function(e,o){var a=e.className.split(" ");-1===a.indexOf(o)&&(e.className+=" "+o)},r=function(e){return"none"!==window.getComputedStyle(e).display},l=e.conf,t=flowplayer.common,i=t.createElement,d=l.swf.indexOf("flowplayer.org")&&l.e&&o.getAttribute("data-origin"),s=d?a(d):t.hostname(),p=(document,l.key);"file:"==location.protocol&&(s="localhost"),e.load.ed=1,l.hostname=s,l.origin=d||location.href,d&&n(o,"is-embedded"),"string"==typeof p&&(p=p.split(/,\s*/));var f=function(e,a){var n=i("a",{href:a,className:"fp-brand"});n.innerHTML=e,t.find(".fp-controls",o)[0].appendChild(n)};if(p&&"function"==typeof key_check&&key_check(p,s)){if(l.logo){var c=i("a",{href:d,className:"fp-logo"});l.embed&&l.embed.popup&&(c.target="_blank");var h=i("img",{src:l.logo});c.appendChild(h),o.appendChild(c)}l.brand&&d||l.brand&&l.brand.showOnOrigin?f(l.brand.text||l.brand,d||location.href):t.addClass(o,"no-brand")}else{f("flowplayer","http://flowplayer.org");var c=i("a",{href:"http://flowplayer.org"});o.appendChild(c);var y=i("div",{className:"fp-context-menu"},''),u=window.location.href.indexOf("localhost"),m=t.find(".fp-player",o)[0];7!==u&&(m||o).appendChild(y),e.on("pause resume finish unload ready",function(e,a){t.removeClass(o,"no-brand");var n=-1;if(a.video.src)for(var l=[["org","flowplayer","drive"],["org","flowplayer","my"]],i=0;i 0) {
+ // off(el, 't1 t2 t3', fn) or off(el, 't1 t2 t3')
+ typeSpec = str2arr(typeSpec)
+ for (i = typeSpec.length; i--;)
+ off(element, typeSpec[i], fn)
+ return element
+ }
+
+ type = isTypeStr && typeSpec.replace(nameRegex, '')
+ if (type && customEvents[type]) type = customEvents[type].base
+
+ if (!typeSpec || isTypeStr) {
+ // off(el) or off(el, t1.ns) or off(el, .ns) or off(el, .ns1.ns2.ns3)
+ if (namespaces = isTypeStr && typeSpec.replace(namespaceRegex, '')) namespaces = str2arr(namespaces, '.')
+ removeListener(element, type, fn, namespaces)
+ } else if (isFunction(typeSpec)) {
+ // off(el, fn)
+ removeListener(element, null, typeSpec)
+ } else {
+ // off(el, { t1: fn1, t2, fn2 })
+ for (k in typeSpec) {
+ if (typeSpec.hasOwnProperty(k)) off(element, k, typeSpec[k])
+ }
+ }
+
+ return element
+ }
+
+ /**
+ * on(element, eventType(s)[, selector], handler[, args ])
+ */
+ , on = function(element, events, selector, fn) {
+ var originalFn, type, types, i, args, entry, first
+
+ //TODO: the undefined check means you can't pass an 'args' argument, fix this perhaps?
+ if (selector === undefined && typeof events == 'object') {
+ //TODO: this can't handle delegated events
+ for (type in events) {
+ if (events.hasOwnProperty(type)) {
+ on.call(this, element, type, events[type])
+ }
+ }
+ return
+ }
+
+ if (!isFunction(selector)) {
+ // delegated event
+ originalFn = fn
+ args = slice.call(arguments, 4)
+ fn = delegate(selector, originalFn, selectorEngine)
+ } else {
+ args = slice.call(arguments, 3)
+ fn = originalFn = selector
+ }
+
+ types = str2arr(events)
+
+ // special case for one(), wrap in a self-removing handler
+ if (this === ONE) {
+ fn = once(off, element, events, fn, originalFn)
+ }
+
+ for (i = types.length; i--;) {
+ // add new handler to the registry and check if it's the first for this element/type
+ first = registry.put(entry = new RegEntry(
+ element
+ , types[i].replace(nameRegex, '') // event type
+ , fn
+ , originalFn
+ , str2arr(types[i].replace(namespaceRegex, ''), '.') // namespaces
+ , args
+ , false // not root
+ ))
+ if (entry[eventSupport] && first) {
+ // first event of this type on this element, add root listener
+ listener(element, entry.eventType, true, entry.customType)
+ }
+ }
+
+ return element
+ }
+
+ /**
+ * add(element[, selector], eventType(s), handler[, args ])
+ *
+ * Deprecated: kept (for now) for backward-compatibility
+ */
+ , add = function (element, events, fn, delfn) {
+ return on.apply(
+ null
+ , !isString(fn)
+ ? slice.call(arguments)
+ : [ element, fn, events, delfn ].concat(arguments.length > 3 ? slice.call(arguments, 5) : [])
+ )
+ }
+
+ /**
+ * one(element, eventType(s)[, selector], handler[, args ])
+ */
+ , one = function () {
+ return on.apply(ONE, arguments)
+ }
+
+ /**
+ * fire(element, eventType(s)[, args ])
+ *
+ * The optional 'args' argument must be an array, if no 'args' argument is provided
+ * then we can use the browser's DOM event system, otherwise we trigger handlers manually
+ */
+ , fire = function (element, type, args) {
+ var types = str2arr(type)
+ , i, j, l, names, handlers
+
+ for (i = types.length; i--;) {
+ type = types[i].replace(nameRegex, '')
+ if (names = types[i].replace(namespaceRegex, '')) names = str2arr(names, '.')
+ if (!names && !args && element[eventSupport]) {
+ fireListener(nativeEvents[type], type, element)
+ } else {
+ // non-native event, either because of a namespace, arguments or a non DOM element
+ // iterate over all listeners and manually 'fire'
+ handlers = registry.get(element, type, null, false)
+ args = [false].concat(args)
+ for (j = 0, l = handlers.length; j < l; j++) {
+ if (handlers[j].inNamespaces(names)) {
+ handlers[j].handler.apply(element, args)
+ }
+ }
+ }
+ }
+ return element
+ }
+
+ /**
+ * clone(dstElement, srcElement[, eventType ])
+ *
+ * TODO: perhaps for consistency we should allow the same flexibility in type specifiers?
+ */
+ , clone = function (element, from, type) {
+ var handlers = registry.get(from, type, null, false)
+ , l = handlers.length
+ , i = 0
+ , args, beanDel
+
+ for (; i < l; i++) {
+ if (handlers[i].original) {
+ args = [ element, handlers[i].type ]
+ if (beanDel = handlers[i].handler.__beanDel) args.push(beanDel.selector)
+ args.push(handlers[i].original)
+ on.apply(null, args)
+ }
+ }
+ return element
+ }
+
+ , bean = {
+ 'on' : on
+ , 'add' : add
+ , 'one' : one
+ , 'off' : off
+ , 'remove' : off
+ , 'clone' : clone
+ , 'fire' : fire
+ , 'Event' : Event
+ , 'setSelectorEngine' : setSelectorEngine
+ , 'noConflict' : function () {
+ context[name] = old
+ return this
+ }
+ }
+
+ // for IE, clean up on unload to avoid leaks
+ if (win.attachEvent) {
+ var cleanup = function () {
+ var i, entries = registry.entries()
+ for (i in entries) {
+ if (entries[i].type && entries[i].type !== 'unload') off(entries[i].element, entries[i].type)
+ }
+ win.detachEvent('onunload', cleanup)
+ win.CollectGarbage && win.CollectGarbage()
+ }
+ win.attachEvent('onunload', cleanup)
+ }
+
+ // initialize selector engine to internal default (qSA or throw Error)
+ setSelectorEngine()
+
+ return bean
+});
+
+},{}],21:[function(_dereq_,module,exports){
+(function (global){
+/*! http://mths.be/punycode v1.2.4 by @mathias */
+;(function(root) {
+
+ /** Detect free variables */
+ var freeExports = typeof exports == 'object' && exports;
+ var freeModule = typeof module == 'object' && module &&
+ module.exports == freeExports && module;
+ var freeGlobal = typeof global == 'object' && global;
+ if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
+ root = freeGlobal;
+ }
+
+ /**
+ * The `punycode` object.
+ * @name punycode
+ * @type Object
+ */
+ var punycode,
+
+ /** Highest positive signed 32-bit float value */
+ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
+
+ /** Bootstring parameters */
+ base = 36,
+ tMin = 1,
+ tMax = 26,
+ skew = 38,
+ damp = 700,
+ initialBias = 72,
+ initialN = 128, // 0x80
+ delimiter = '-', // '\x2D'
+
+ /** Regular expressions */
+ regexPunycode = /^xn--/,
+ regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
+ regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
+
+ /** Error messages */
+ errors = {
+ 'overflow': 'Overflow: input needs wider integers to process',
+ 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
+ 'invalid-input': 'Invalid input'
+ },
+
+ /** Convenience shortcuts */
+ baseMinusTMin = base - tMin,
+ floor = Math.floor,
+ stringFromCharCode = String.fromCharCode,
+
+ /** Temporary variable */
+ key;
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * A generic error utility function.
+ * @private
+ * @param {String} type The error type.
+ * @returns {Error} Throws a `RangeError` with the applicable error message.
+ */
+ function error(type) {
+ throw RangeError(errors[type]);
+ }
+
+ /**
+ * A generic `Array#map` utility function.
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} callback The function that gets called for every array
+ * item.
+ * @returns {Array} A new array of values returned by the callback function.
+ */
+ function map(array, fn) {
+ var length = array.length;
+ while (length--) {
+ array[length] = fn(array[length]);
+ }
+ return array;
+ }
+
+ /**
+ * A simple `Array#map`-like wrapper to work with domain name strings.
+ * @private
+ * @param {String} domain The domain name.
+ * @param {Function} callback The function that gets called for every
+ * character.
+ * @returns {Array} A new string of characters returned by the callback
+ * function.
+ */
+ function mapDomain(string, fn) {
+ return map(string.split(regexSeparators), fn).join('.');
+ }
+
+ /**
+ * Creates an array containing the numeric code points of each Unicode
+ * character in the string. While JavaScript uses UCS-2 internally,
+ * this function will convert a pair of surrogate halves (each of which
+ * UCS-2 exposes as separate characters) into a single code point,
+ * matching UTF-16.
+ * @see `punycode.ucs2.encode`
+ * @see
+ * @memberOf punycode.ucs2
+ * @name decode
+ * @param {String} string The Unicode input string (UCS-2).
+ * @returns {Array} The new array of code points.
+ */
+ function ucs2decode(string) {
+ var output = [],
+ counter = 0,
+ length = string.length,
+ value,
+ extra;
+ while (counter < length) {
+ value = string.charCodeAt(counter++);
+ if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+ // high surrogate, and there is a next character
+ extra = string.charCodeAt(counter++);
+ if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+ output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+ } else {
+ // unmatched surrogate; only append this code unit, in case the next
+ // code unit is the high surrogate of a surrogate pair
+ output.push(value);
+ counter--;
+ }
+ } else {
+ output.push(value);
+ }
+ }
+ return output;
+ }
+
+ /**
+ * Creates a string based on an array of numeric code points.
+ * @see `punycode.ucs2.decode`
+ * @memberOf punycode.ucs2
+ * @name encode
+ * @param {Array} codePoints The array of numeric code points.
+ * @returns {String} The new Unicode string (UCS-2).
+ */
+ function ucs2encode(array) {
+ return map(array, function(value) {
+ var output = '';
+ if (value > 0xFFFF) {
+ value -= 0x10000;
+ output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+ value = 0xDC00 | value & 0x3FF;
+ }
+ output += stringFromCharCode(value);
+ return output;
+ }).join('');
+ }
+
+ /**
+ * Converts a basic code point into a digit/integer.
+ * @see `digitToBasic()`
+ * @private
+ * @param {Number} codePoint The basic numeric code point value.
+ * @returns {Number} The numeric value of a basic code point (for use in
+ * representing integers) in the range `0` to `base - 1`, or `base` if
+ * the code point does not represent a value.
+ */
+ function basicToDigit(codePoint) {
+ if (codePoint - 48 < 10) {
+ return codePoint - 22;
+ }
+ if (codePoint - 65 < 26) {
+ return codePoint - 65;
+ }
+ if (codePoint - 97 < 26) {
+ return codePoint - 97;
+ }
+ return base;
+ }
+
+ /**
+ * Converts a digit/integer into a basic code point.
+ * @see `basicToDigit()`
+ * @private
+ * @param {Number} digit The numeric value of a basic code point.
+ * @returns {Number} The basic code point whose value (when used for
+ * representing integers) is `digit`, which needs to be in the range
+ * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
+ * used; else, the lowercase form is used. The behavior is undefined
+ * if `flag` is non-zero and `digit` has no uppercase form.
+ */
+ function digitToBasic(digit, flag) {
+ // 0..25 map to ASCII a..z or A..Z
+ // 26..35 map to ASCII 0..9
+ return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
+ }
+
+ /**
+ * Bias adaptation function as per section 3.4 of RFC 3492.
+ * http://tools.ietf.org/html/rfc3492#section-3.4
+ * @private
+ */
+ function adapt(delta, numPoints, firstTime) {
+ var k = 0;
+ delta = firstTime ? floor(delta / damp) : delta >> 1;
+ delta += floor(delta / numPoints);
+ for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
+ delta = floor(delta / baseMinusTMin);
+ }
+ return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
+ }
+
+ /**
+ * Converts a Punycode string of ASCII-only symbols to a string of Unicode
+ * symbols.
+ * @memberOf punycode
+ * @param {String} input The Punycode string of ASCII-only symbols.
+ * @returns {String} The resulting string of Unicode symbols.
+ */
+ function decode(input) {
+ // Don't use UCS-2
+ var output = [],
+ inputLength = input.length,
+ out,
+ i = 0,
+ n = initialN,
+ bias = initialBias,
+ basic,
+ j,
+ index,
+ oldi,
+ w,
+ k,
+ digit,
+ t,
+ /** Cached calculation results */
+ baseMinusT;
+
+ // Handle the basic code points: let `basic` be the number of input code
+ // points before the last delimiter, or `0` if there is none, then copy
+ // the first basic code points to the output.
+
+ basic = input.lastIndexOf(delimiter);
+ if (basic < 0) {
+ basic = 0;
+ }
+
+ for (j = 0; j < basic; ++j) {
+ // if it's not a basic code point
+ if (input.charCodeAt(j) >= 0x80) {
+ error('not-basic');
+ }
+ output.push(input.charCodeAt(j));
+ }
+
+ // Main decoding loop: start just after the last delimiter if any basic code
+ // points were copied; start at the beginning otherwise.
+
+ for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
+
+ // `index` is the index of the next character to be consumed.
+ // Decode a generalized variable-length integer into `delta`,
+ // which gets added to `i`. The overflow checking is easier
+ // if we increase `i` as we go, then subtract off its starting
+ // value at the end to obtain `delta`.
+ for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
+
+ if (index >= inputLength) {
+ error('invalid-input');
+ }
+
+ digit = basicToDigit(input.charCodeAt(index++));
+
+ if (digit >= base || digit > floor((maxInt - i) / w)) {
+ error('overflow');
+ }
+
+ i += digit * w;
+ t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+
+ if (digit < t) {
+ break;
+ }
+
+ baseMinusT = base - t;
+ if (w > floor(maxInt / baseMinusT)) {
+ error('overflow');
+ }
+
+ w *= baseMinusT;
+
+ }
+
+ out = output.length + 1;
+ bias = adapt(i - oldi, out, oldi == 0);
+
+ // `i` was supposed to wrap around from `out` to `0`,
+ // incrementing `n` each time, so we'll fix that now:
+ if (floor(i / out) > maxInt - n) {
+ error('overflow');
+ }
+
+ n += floor(i / out);
+ i %= out;
+
+ // Insert `n` at position `i` of the output
+ output.splice(i++, 0, n);
+
+ }
+
+ return ucs2encode(output);
+ }
+
+ /**
+ * Converts a string of Unicode symbols to a Punycode string of ASCII-only
+ * symbols.
+ * @memberOf punycode
+ * @param {String} input The string of Unicode symbols.
+ * @returns {String} The resulting Punycode string of ASCII-only symbols.
+ */
+ function encode(input) {
+ var n,
+ delta,
+ handledCPCount,
+ basicLength,
+ bias,
+ j,
+ m,
+ q,
+ k,
+ t,
+ currentValue,
+ output = [],
+ /** `inputLength` will hold the number of code points in `input`. */
+ inputLength,
+ /** Cached calculation results */
+ handledCPCountPlusOne,
+ baseMinusT,
+ qMinusT;
+
+ // Convert the input in UCS-2 to Unicode
+ input = ucs2decode(input);
+
+ // Cache the length
+ inputLength = input.length;
+
+ // Initialize the state
+ n = initialN;
+ delta = 0;
+ bias = initialBias;
+
+ // Handle the basic code points
+ for (j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+ if (currentValue < 0x80) {
+ output.push(stringFromCharCode(currentValue));
+ }
+ }
+
+ handledCPCount = basicLength = output.length;
+
+ // `handledCPCount` is the number of code points that have been handled;
+ // `basicLength` is the number of basic code points.
+
+ // Finish the basic string - if it is not empty - with a delimiter
+ if (basicLength) {
+ output.push(delimiter);
+ }
+
+ // Main encoding loop:
+ while (handledCPCount < inputLength) {
+
+ // All non-basic code points < n have been handled already. Find the next
+ // larger one:
+ for (m = maxInt, j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+ if (currentValue >= n && currentValue < m) {
+ m = currentValue;
+ }
+ }
+
+ // Increase `delta` enough to advance the decoder's state to ,
+ // but guard against overflow
+ handledCPCountPlusOne = handledCPCount + 1;
+ if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
+ error('overflow');
+ }
+
+ delta += (m - n) * handledCPCountPlusOne;
+ n = m;
+
+ for (j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+
+ if (currentValue < n && ++delta > maxInt) {
+ error('overflow');
+ }
+
+ if (currentValue == n) {
+ // Represent delta as a generalized variable-length integer
+ for (q = delta, k = base; /* no condition */; k += base) {
+ t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+ if (q < t) {
+ break;
+ }
+ qMinusT = q - t;
+ baseMinusT = base - t;
+ output.push(
+ stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
+ );
+ q = floor(qMinusT / baseMinusT);
+ }
+
+ output.push(stringFromCharCode(digitToBasic(q, 0)));
+ bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
+ delta = 0;
+ ++handledCPCount;
+ }
+ }
+
+ ++delta;
+ ++n;
+
+ }
+ return output.join('');
+ }
+
+ /**
+ * Converts a Punycode string representing a domain name to Unicode. Only the
+ * Punycoded parts of the domain name will be converted, i.e. it doesn't
+ * matter if you call it on a string that has already been converted to
+ * Unicode.
+ * @memberOf punycode
+ * @param {String} domain The Punycode domain name to convert to Unicode.
+ * @returns {String} The Unicode representation of the given Punycode
+ * string.
+ */
+ function toUnicode(domain) {
+ return mapDomain(domain, function(string) {
+ return regexPunycode.test(string)
+ ? decode(string.slice(4).toLowerCase())
+ : string;
+ });
+ }
+
+ /**
+ * Converts a Unicode string representing a domain name to Punycode. Only the
+ * non-ASCII parts of the domain name will be converted, i.e. it doesn't
+ * matter if you call it with a domain that's already in ASCII.
+ * @memberOf punycode
+ * @param {String} domain The domain name to convert, as a Unicode string.
+ * @returns {String} The Punycode representation of the given domain name.
+ */
+ function toASCII(domain) {
+ return mapDomain(domain, function(string) {
+ return regexNonASCII.test(string)
+ ? 'xn--' + encode(string)
+ : string;
+ });
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /** Define the public API */
+ punycode = {
+ /**
+ * A string representing the current Punycode.js version number.
+ * @memberOf punycode
+ * @type String
+ */
+ 'version': '1.2.4',
+ /**
+ * An object of methods to convert from JavaScript's internal character
+ * representation (UCS-2) to Unicode code points, and back.
+ * @see
+ * @memberOf punycode
+ * @type Object
+ */
+ 'ucs2': {
+ 'decode': ucs2decode,
+ 'encode': ucs2encode
+ },
+ 'decode': decode,
+ 'encode': encode,
+ 'toASCII': toASCII,
+ 'toUnicode': toUnicode
+ };
+
+ /** Expose `punycode` */
+ // Some AMD build optimizers, like r.js, check for specific condition patterns
+ // like the following:
+ if (
+ typeof define == 'function' &&
+ typeof define.amd == 'object' &&
+ define.amd
+ ) {
+ define('punycode', function() {
+ return punycode;
+ });
+ } else if (freeExports && !freeExports.nodeType) {
+ if (freeModule) { // in Node.js or RingoJS v0.8.0+
+ freeModule.exports = punycode;
+ } else { // in Narwhal or RingoJS v0.7.0-
+ for (key in punycode) {
+ punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
+ }
+ }
+ } else { // in Rhino or a web browser
+ root.punycode = punycode;
+ }
+
+}(this));
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],22:[function(_dereq_,module,exports){
+// contains, add, remove, toggle
+var indexof = _dereq_('indexof')
+
+module.exports = ClassList
+
+function ClassList(elem) {
+ var cl = elem.classList
+
+ if (cl) {
+ return cl
+ }
+
+ var classList = {
+ add: add
+ , remove: remove
+ , contains: contains
+ , toggle: toggle
+ , toString: $toString
+ , length: 0
+ , item: item
+ }
+
+ return classList
+
+ function add(token) {
+ var list = getTokens()
+ if (indexof(list, token) > -1) {
+ return
+ }
+ list.push(token)
+ setTokens(list)
+ }
+
+ function remove(token) {
+ var list = getTokens()
+ , index = indexof(list, token)
+
+ if (index === -1) {
+ return
+ }
+
+ list.splice(index, 1)
+ setTokens(list)
+ }
+
+ function contains(token) {
+ return indexof(getTokens(), token) > -1
+ }
+
+ function toggle(token) {
+ if (contains(token)) {
+ remove(token)
+ return false
+ } else {
+ add(token)
+ return true
+ }
+ }
+
+ function $toString() {
+ return elem.className
+ }
+
+ function item(index) {
+ var tokens = getTokens()
+ return tokens[index] || null
+ }
+
+ function getTokens() {
+ var className = elem.className
+
+ return filter(className.split(" "), isTruthy)
+ }
+
+ function setTokens(list) {
+ var length = list.length
+
+ elem.className = list.join(" ")
+ classList.length = length
+
+ for (var i = 0; i < list.length; i++) {
+ classList[i] = list[i]
+ }
+
+ delete list[length]
+ }
+}
+
+function filter (arr, fn) {
+ var ret = []
+ for (var i = 0; i < arr.length; i++) {
+ if (fn(arr[i])) ret.push(arr[i])
+ }
+ return ret
+}
+
+function isTruthy(value) {
+ return !!value
+}
+
+},{"indexof":23}],23:[function(_dereq_,module,exports){
+
+var indexOf = [].indexOf;
+
+module.exports = function(arr, obj){
+ if (indexOf) return arr.indexOf(obj);
+ for (var i = 0; i < arr.length; ++i) {
+ if (arr[i] === obj) return i;
+ }
+ return -1;
+};
+},{}],24:[function(_dereq_,module,exports){
+// DEV: We don't use var but favor parameters since these play nicer with minification
+function computedStyle(el, prop, getComputedStyle, style) {
+ getComputedStyle = window.getComputedStyle;
+ style =
+ // If we have getComputedStyle
+ getComputedStyle ?
+ // Query it
+ // TODO: From CSS-Query notes, we might need (node, null) for FF
+ getComputedStyle(el) :
+
+ // Otherwise, we are in IE and use currentStyle
+ el.currentStyle;
+ if (style) {
+ return style
+ [
+ // Switch to camelCase for CSSOM
+ // DEV: Grabbed from jQuery
+ // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194
+ // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597
+ prop.replace(/-(\w)/gi, function (word, letter) {
+ return letter.toUpperCase();
+ })
+ ];
+ }
+}
+
+module.exports = computedStyle;
+
+},{}],25:[function(_dereq_,module,exports){
+/*!
+ * https://github.com/es-shims/es5-shim
+ * @license es5-shim Copyright 2009-2015 by contributors, MIT License
+ * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
+ */
+
+// vim: ts=4 sts=4 sw=4 expandtab
+
+// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
+;
+
+// UMD (Universal Module Definition)
+// see https://github.com/umdjs/umd/blob/master/returnExports.js
+(function (root, factory) {
+ 'use strict';
+
+ /* global define, exports, module */
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory);
+ } else if (typeof exports === 'object') {
+ // Node. Does not work with strict CommonJS, but
+ // only CommonJS-like enviroments that support module.exports,
+ // like Node.
+ module.exports = factory();
+ } else {
+ // Browser globals (root is window)
+ root.returnExports = factory();
+ }
+}(this, function () {
+
+/**
+ * Brings an environment as close to ECMAScript 5 compliance
+ * as is possible with the facilities of erstwhile engines.
+ *
+ * Annotated ES5: http://es5.github.com/ (specific links below)
+ * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
+ * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
+ */
+
+// Shortcut to an often accessed properties, in order to avoid multiple
+// dereference that costs universally. This also holds a reference to known-good
+// functions.
+var $Array = Array;
+var ArrayPrototype = $Array.prototype;
+var $Object = Object;
+var ObjectPrototype = $Object.prototype;
+var FunctionPrototype = Function.prototype;
+var $String = String;
+var StringPrototype = $String.prototype;
+var $Number = Number;
+var NumberPrototype = $Number.prototype;
+var array_slice = ArrayPrototype.slice;
+var array_splice = ArrayPrototype.splice;
+var array_push = ArrayPrototype.push;
+var array_unshift = ArrayPrototype.unshift;
+var array_concat = ArrayPrototype.concat;
+var call = FunctionPrototype.call;
+var max = Math.max;
+var min = Math.min;
+
+// Having a toString local variable name breaks in Opera so use to_string.
+var to_string = ObjectPrototype.toString;
+
+var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
+var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
+var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
+var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
+
+/* inlined from http://npmjs.com/define-properties */
+var defineProperties = (function (has) {
+ var supportsDescriptors = $Object.defineProperty && (function () {
+ try {
+ var obj = {};
+ $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
+ for (var _ in obj) { return false; }
+ return obj.x === obj;
+ } catch (e) { /* this is ES3 */
+ return false;
+ }
+ }());
+
+ // Define configurable, writable and non-enumerable props
+ // if they don't exist.
+ var defineProperty;
+ if (supportsDescriptors) {
+ defineProperty = function (object, name, method, forceAssign) {
+ if (!forceAssign && (name in object)) { return; }
+ $Object.defineProperty(object, name, {
+ configurable: true,
+ enumerable: false,
+ writable: true,
+ value: method
+ });
+ };
+ } else {
+ defineProperty = function (object, name, method, forceAssign) {
+ if (!forceAssign && (name in object)) { return; }
+ object[name] = method;
+ };
+ }
+ return function defineProperties(object, map, forceAssign) {
+ for (var name in map) {
+ if (has.call(map, name)) {
+ defineProperty(object, name, map[name], forceAssign);
+ }
+ }
+ };
+}(ObjectPrototype.hasOwnProperty));
+
+//
+// Util
+// ======
+//
+
+/* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
+var isPrimitive = function isPrimitive(input) {
+ var type = typeof input;
+ return input === null || (type !== 'object' && type !== 'function');
+};
+
+var ES = {
+ // ES5 9.4
+ // http://es5.github.com/#x9.4
+ // http://jsperf.com/to-integer
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
+ ToInteger: function ToInteger(num) {
+ var n = +num;
+ if (n !== n) { // isNaN
+ n = 0;
+ } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ return n;
+ },
+
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
+ ToPrimitive: function ToPrimitive(input) {
+ var val, valueOf, toStr;
+ if (isPrimitive(input)) {
+ return input;
+ }
+ valueOf = input.valueOf;
+ if (isCallable(valueOf)) {
+ val = valueOf.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ toStr = input.toString;
+ if (isCallable(toStr)) {
+ val = toStr.call(input);
+ if (isPrimitive(val)) {
+ return val;
+ }
+ }
+ throw new TypeError();
+ },
+
+ // ES5 9.9
+ // http://es5.github.com/#x9.9
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
+ ToObject: function (o) {
+ /* jshint eqnull: true */
+ if (o == null) { // this matches both null and undefined
+ throw new TypeError("can't convert " + o + ' to object');
+ }
+ return $Object(o);
+ },
+
+ /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
+ ToUint32: function ToUint32(x) {
+ return x >>> 0;
+ }
+};
+
+//
+// Function
+// ========
+//
+
+// ES-5 15.3.4.5
+// http://es5.github.com/#x15.3.4.5
+
+var Empty = function Empty() {};
+
+defineProperties(FunctionPrototype, {
+ bind: function bind(that) { // .length is 1
+ // 1. Let Target be the this value.
+ var target = this;
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
+ if (!isCallable(target)) {
+ throw new TypeError('Function.prototype.bind called on incompatible ' + target);
+ }
+ // 3. Let A be a new (possibly empty) internal list of all of the
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
+ // XXX slicedArgs will stand in for "A" if used
+ var args = array_slice.call(arguments, 1); // for normal call
+ // 4. Let F be a new native ECMAScript object.
+ // 11. Set the [[Prototype]] internal property of F to the standard
+ // built-in Function prototype object as specified in 15.3.3.1.
+ // 12. Set the [[Call]] internal property of F as described in
+ // 15.3.4.5.1.
+ // 13. Set the [[Construct]] internal property of F as described in
+ // 15.3.4.5.2.
+ // 14. Set the [[HasInstance]] internal property of F as described in
+ // 15.3.4.5.3.
+ var bound;
+ var binder = function () {
+
+ if (this instanceof bound) {
+ // 15.3.4.5.2 [[Construct]]
+ // When the [[Construct]] internal method of a function object,
+ // F that was created using the bind function is called with a
+ // list of arguments ExtraArgs, the following steps are taken:
+ // 1. Let target be the value of F's [[TargetFunction]]
+ // internal property.
+ // 2. If target has no [[Construct]] internal method, a
+ // TypeError exception is thrown.
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
+ // property.
+ // 4. Let args be a new list containing the same values as the
+ // list boundArgs in the same order followed by the same
+ // values as the list ExtraArgs in the same order.
+ // 5. Return the result of calling the [[Construct]] internal
+ // method of target providing args as the arguments.
+
+ var result = target.apply(
+ this,
+ array_concat.call(args, array_slice.call(arguments))
+ );
+ if ($Object(result) === result) {
+ return result;
+ }
+ return this;
+
+ } else {
+ // 15.3.4.5.1 [[Call]]
+ // When the [[Call]] internal method of a function object, F,
+ // which was created using the bind function is called with a
+ // this value and a list of arguments ExtraArgs, the following
+ // steps are taken:
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
+ // property.
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
+ // property.
+ // 3. Let target be the value of F's [[TargetFunction]] internal
+ // property.
+ // 4. Let args be a new list containing the same values as the
+ // list boundArgs in the same order followed by the same
+ // values as the list ExtraArgs in the same order.
+ // 5. Return the result of calling the [[Call]] internal method
+ // of target providing boundThis as the this value and
+ // providing args as the arguments.
+
+ // equiv: target.call(this, ...boundArgs, ...args)
+ return target.apply(
+ that,
+ array_concat.call(args, array_slice.call(arguments))
+ );
+
+ }
+
+ };
+
+ // 15. If the [[Class]] internal property of Target is "Function", then
+ // a. Let L be the length property of Target minus the length of A.
+ // b. Set the length own property of F to either 0 or L, whichever is
+ // larger.
+ // 16. Else set the length own property of F to 0.
+
+ var boundLength = max(0, target.length - args.length);
+
+ // 17. Set the attributes of the length own property of F to the values
+ // specified in 15.3.5.1.
+ var boundArgs = [];
+ for (var i = 0; i < boundLength; i++) {
+ array_push.call(boundArgs, '$' + i);
+ }
+
+ // XXX Build a dynamic function with desired amount of arguments is the only
+ // way to set the length property of a function.
+ // In environments where Content Security Policies enabled (Chrome extensions,
+ // for ex.) all use of eval or Function costructor throws an exception.
+ // However in all of these environments Function.prototype.bind exists
+ // and so this code will never be executed.
+ bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
+
+ if (target.prototype) {
+ Empty.prototype = target.prototype;
+ bound.prototype = new Empty();
+ // Clean up dangling references.
+ Empty.prototype = null;
+ }
+
+ // TODO
+ // 18. Set the [[Extensible]] internal property of F to true.
+
+ // TODO
+ // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
+ // 20. Call the [[DefineOwnProperty]] internal method of F with
+ // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
+ // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
+ // false.
+ // 21. Call the [[DefineOwnProperty]] internal method of F with
+ // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
+ // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
+ // and false.
+
+ // TODO
+ // NOTE Function objects created using Function.prototype.bind do not
+ // have a prototype property or the [[Code]], [[FormalParameters]], and
+ // [[Scope]] internal properties.
+ // XXX can't delete prototype in pure-js.
+
+ // 22. Return F.
+ return bound;
+ }
+});
+
+// _Please note: Shortcuts are defined after `Function.prototype.bind` as we
+// us it in defining shortcuts.
+var owns = call.bind(ObjectPrototype.hasOwnProperty);
+var toStr = call.bind(ObjectPrototype.toString);
+var strSlice = call.bind(StringPrototype.slice);
+var strSplit = call.bind(StringPrototype.split);
+
+//
+// Array
+// =====
+//
+
+var isArray = $Array.isArray || function isArray(obj) {
+ return toStr(obj) === '[object Array]';
+};
+
+// ES5 15.4.4.12
+// http://es5.github.com/#x15.4.4.13
+// Return len+argCount.
+// [bugfix, ielt8]
+// IE < 8 bug: [].unshift(0) === undefined but should be "1"
+var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
+defineProperties(ArrayPrototype, {
+ unshift: function () {
+ array_unshift.apply(this, arguments);
+ return this.length;
+ }
+}, hasUnshiftReturnValueBug);
+
+// ES5 15.4.3.2
+// http://es5.github.com/#x15.4.3.2
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
+defineProperties($Array, { isArray: isArray });
+
+// The IsCallable() check in the Array functions
+// has been replaced with a strict check on the
+// internal class of the object to trap cases where
+// the provided function was actually a regular
+// expression literal, which in V8 and
+// JavaScriptCore is a typeof "function". Only in
+// V8 are regular expression literals permitted as
+// reduce parameters, so it is desirable in the
+// general case for the shim to match the more
+// strict and common behavior of rejecting regular
+// expressions.
+
+// ES5 15.4.4.18
+// http://es5.github.com/#x15.4.4.18
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
+
+// Check failure of by-index access of string characters (IE < 9)
+// and failure of `0 in boxedString` (Rhino)
+var boxedString = $Object('a');
+var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
+
+var properlyBoxesContext = function properlyBoxed(method) {
+ // Check node 0.6.21 bug where third parameter is not boxed
+ var properlyBoxesNonStrict = true;
+ var properlyBoxesStrict = true;
+ if (method) {
+ method.call('foo', function (_, __, context) {
+ if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
+ });
+
+ method.call([1], function () {
+ 'use strict';
+
+ properlyBoxesStrict = typeof this === 'string';
+ }, 'x');
+ }
+ return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
+};
+
+defineProperties(ArrayPrototype, {
+ forEach: function forEach(callbackfn /*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var i = -1;
+ var length = self.length >>> 0;
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.forEach callback must be a function');
+ }
+
+ while (++i < length) {
+ if (i in self) {
+ // Invoke the callback function with call, passing arguments:
+ // context, property value, property key, thisArg object
+ if (typeof T !== 'undefined') {
+ callbackfn.call(T, self[i], i, object);
+ } else {
+ callbackfn(self[i], i, object);
+ }
+ }
+ }
+ }
+}, !properlyBoxesContext(ArrayPrototype.forEach));
+
+// ES5 15.4.4.19
+// http://es5.github.com/#x15.4.4.19
+// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+defineProperties(ArrayPrototype, {
+ map: function map(callbackfn/*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = self.length >>> 0;
+ var result = $Array(length);
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.map callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ if (typeof T !== 'undefined') {
+ result[i] = callbackfn.call(T, self[i], i, object);
+ } else {
+ result[i] = callbackfn(self[i], i, object);
+ }
+ }
+ }
+ return result;
+ }
+}, !properlyBoxesContext(ArrayPrototype.map));
+
+// ES5 15.4.4.20
+// http://es5.github.com/#x15.4.4.20
+// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+defineProperties(ArrayPrototype, {
+ filter: function filter(callbackfn /*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = self.length >>> 0;
+ var result = [];
+ var value;
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.filter callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self) {
+ value = self[i];
+ if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
+ array_push.call(result, value);
+ }
+ }
+ }
+ return result;
+ }
+}, !properlyBoxesContext(ArrayPrototype.filter));
+
+// ES5 15.4.4.16
+// http://es5.github.com/#x15.4.4.16
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
+defineProperties(ArrayPrototype, {
+ every: function every(callbackfn /*, thisArg*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = self.length >>> 0;
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.every callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
+ return false;
+ }
+ }
+ return true;
+ }
+}, !properlyBoxesContext(ArrayPrototype.every));
+
+// ES5 15.4.4.17
+// http://es5.github.com/#x15.4.4.17
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
+defineProperties(ArrayPrototype, {
+ some: function some(callbackfn/*, thisArg */) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = self.length >>> 0;
+ var T;
+ if (arguments.length > 1) {
+ T = arguments[1];
+ }
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.some callback must be a function');
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
+ return true;
+ }
+ }
+ return false;
+ }
+}, !properlyBoxesContext(ArrayPrototype.some));
+
+// ES5 15.4.4.21
+// http://es5.github.com/#x15.4.4.21
+// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
+var reduceCoercesToObject = false;
+if (ArrayPrototype.reduce) {
+ reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
+}
+defineProperties(ArrayPrototype, {
+ reduce: function reduce(callbackfn /*, initialValue*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = self.length >>> 0;
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.reduce callback must be a function');
+ }
+
+ // no value to return if no initial value and an empty array
+ if (length === 0 && arguments.length === 1) {
+ throw new TypeError('reduce of empty array with no initial value');
+ }
+
+ var i = 0;
+ var result;
+ if (arguments.length >= 2) {
+ result = arguments[1];
+ } else {
+ do {
+ if (i in self) {
+ result = self[i++];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (++i >= length) {
+ throw new TypeError('reduce of empty array with no initial value');
+ }
+ } while (true);
+ }
+
+ for (; i < length; i++) {
+ if (i in self) {
+ result = callbackfn(result, self[i], i, object);
+ }
+ }
+
+ return result;
+ }
+}, !reduceCoercesToObject);
+
+// ES5 15.4.4.22
+// http://es5.github.com/#x15.4.4.22
+// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
+var reduceRightCoercesToObject = false;
+if (ArrayPrototype.reduceRight) {
+ reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
+}
+defineProperties(ArrayPrototype, {
+ reduceRight: function reduceRight(callbackfn/*, initial*/) {
+ var object = ES.ToObject(this);
+ var self = splitString && isString(this) ? strSplit(this, '') : object;
+ var length = self.length >>> 0;
+
+ // If no callback function or if callback is not a callable function
+ if (!isCallable(callbackfn)) {
+ throw new TypeError('Array.prototype.reduceRight callback must be a function');
+ }
+
+ // no value to return if no initial value, empty array
+ if (length === 0 && arguments.length === 1) {
+ throw new TypeError('reduceRight of empty array with no initial value');
+ }
+
+ var result;
+ var i = length - 1;
+ if (arguments.length >= 2) {
+ result = arguments[1];
+ } else {
+ do {
+ if (i in self) {
+ result = self[i--];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (--i < 0) {
+ throw new TypeError('reduceRight of empty array with no initial value');
+ }
+ } while (true);
+ }
+
+ if (i < 0) {
+ return result;
+ }
+
+ do {
+ if (i in self) {
+ result = callbackfn(result, self[i], i, object);
+ }
+ } while (i--);
+
+ return result;
+ }
+}, !reduceRightCoercesToObject);
+
+// ES5 15.4.4.14
+// http://es5.github.com/#x15.4.4.14
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
+var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
+defineProperties(ArrayPrototype, {
+ indexOf: function indexOf(searchElement /*, fromIndex */) {
+ var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
+ var length = self.length >>> 0;
+
+ if (length === 0) {
+ return -1;
+ }
+
+ var i = 0;
+ if (arguments.length > 1) {
+ i = ES.ToInteger(arguments[1]);
+ }
+
+ // handle negative indices
+ i = i >= 0 ? i : max(0, length + i);
+ for (; i < length; i++) {
+ if (i in self && self[i] === searchElement) {
+ return i;
+ }
+ }
+ return -1;
+ }
+}, hasFirefox2IndexOfBug);
+
+// ES5 15.4.4.15
+// http://es5.github.com/#x15.4.4.15
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
+var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
+defineProperties(ArrayPrototype, {
+ lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
+ var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
+ var length = self.length >>> 0;
+
+ if (length === 0) {
+ return -1;
+ }
+ var i = length - 1;
+ if (arguments.length > 1) {
+ i = min(i, ES.ToInteger(arguments[1]));
+ }
+ // handle negative indices
+ i = i >= 0 ? i : length - Math.abs(i);
+ for (; i >= 0; i--) {
+ if (i in self && searchElement === self[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+}, hasFirefox2LastIndexOfBug);
+
+// ES5 15.4.4.12
+// http://es5.github.com/#x15.4.4.12
+var spliceNoopReturnsEmptyArray = (function () {
+ var a = [1, 2];
+ var result = a.splice();
+ return a.length === 2 && isArray(result) && result.length === 0;
+}());
+defineProperties(ArrayPrototype, {
+ // Safari 5.0 bug where .splice() returns undefined
+ splice: function splice(start, deleteCount) {
+ if (arguments.length === 0) {
+ return [];
+ } else {
+ return array_splice.apply(this, arguments);
+ }
+ }
+}, !spliceNoopReturnsEmptyArray);
+
+var spliceWorksWithEmptyObject = (function () {
+ var obj = {};
+ ArrayPrototype.splice.call(obj, 0, 0, 1);
+ return obj.length === 1;
+}());
+defineProperties(ArrayPrototype, {
+ splice: function splice(start, deleteCount) {
+ if (arguments.length === 0) { return []; }
+ var args = arguments;
+ this.length = max(ES.ToInteger(this.length), 0);
+ if (arguments.length > 0 && typeof deleteCount !== 'number') {
+ args = array_slice.call(arguments);
+ if (args.length < 2) {
+ array_push.call(args, this.length - start);
+ } else {
+ args[1] = ES.ToInteger(deleteCount);
+ }
+ }
+ return array_splice.apply(this, args);
+ }
+}, !spliceWorksWithEmptyObject);
+var spliceWorksWithLargeSparseArrays = (function () {
+ // Per https://github.com/es-shims/es5-shim/issues/295
+ // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
+ var arr = new $Array(1e5);
+ // note: the index MUST be 8 or larger or the test will false pass
+ arr[8] = 'x';
+ arr.splice(1, 1);
+ // note: this test must be defined *after* the indexOf shim
+ // per https://github.com/es-shims/es5-shim/issues/313
+ return arr.indexOf('x') === 7;
+}());
+var spliceWorksWithSmallSparseArrays = (function () {
+ // Per https://github.com/es-shims/es5-shim/issues/295
+ // Opera 12.15 breaks on this, no idea why.
+ var n = 256;
+ var arr = [];
+ arr[n] = 'a';
+ arr.splice(n + 1, 0, 'b');
+ return arr[n] === 'a';
+}());
+defineProperties(ArrayPrototype, {
+ splice: function splice(start, deleteCount) {
+ var O = ES.ToObject(this);
+ var A = [];
+ var len = ES.ToUint32(O.length);
+ var relativeStart = ES.ToInteger(start);
+ var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
+ var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
+
+ var k = 0;
+ var from;
+ while (k < actualDeleteCount) {
+ from = $String(actualStart + k);
+ if (owns(O, from)) {
+ A[k] = O[from];
+ }
+ k += 1;
+ }
+
+ var items = array_slice.call(arguments, 2);
+ var itemCount = items.length;
+ var to;
+ if (itemCount < actualDeleteCount) {
+ k = actualStart;
+ while (k < (len - actualDeleteCount)) {
+ from = $String(k + actualDeleteCount);
+ to = $String(k + itemCount);
+ if (owns(O, from)) {
+ O[to] = O[from];
+ } else {
+ delete O[to];
+ }
+ k += 1;
+ }
+ k = len;
+ while (k > (len - actualDeleteCount + itemCount)) {
+ delete O[k - 1];
+ k -= 1;
+ }
+ } else if (itemCount > actualDeleteCount) {
+ k = len - actualDeleteCount;
+ while (k > actualStart) {
+ from = $String(k + actualDeleteCount - 1);
+ to = $String(k + itemCount - 1);
+ if (owns(O, from)) {
+ O[to] = O[from];
+ } else {
+ delete O[to];
+ }
+ k -= 1;
+ }
+ }
+ k = actualStart;
+ for (var i = 0; i < items.length; ++i) {
+ O[k] = items[i];
+ k += 1;
+ }
+ O.length = len - actualDeleteCount + itemCount;
+
+ return A;
+ }
+}, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
+
+//
+// Object
+// ======
+//
+
+// ES5 15.2.3.14
+// http://es5.github.com/#x15.2.3.14
+
+// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
+var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');
+var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
+var hasStringEnumBug = !owns('x', '0');
+var equalsConstructorPrototype = function (o) {
+ var ctor = o.constructor;
+ return ctor && ctor.prototype === o;
+};
+var blacklistedKeys = {
+ $window: true,
+ $console: true,
+ $parent: true,
+ $self: true,
+ $frames: true,
+ $frameElement: true,
+ $webkitIndexedDB: true,
+ $webkitStorageInfo: true
+};
+var hasAutomationEqualityBug = (function () {
+ /* globals window */
+ if (typeof window === 'undefined') { return false; }
+ for (var k in window) {
+ if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
+ try {
+ equalsConstructorPrototype(window[k]);
+ } catch (e) {
+ return true;
+ }
+ }
+ }
+ return false;
+}());
+var equalsConstructorPrototypeIfNotBuggy = function (object) {
+ if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); }
+ try {
+ return equalsConstructorPrototype(object);
+ } catch (e) {
+ return false;
+ }
+};
+var dontEnums = [
+ 'toString',
+ 'toLocaleString',
+ 'valueOf',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'constructor'
+];
+var dontEnumsLength = dontEnums.length;
+
+var isArguments = function isArguments(value) {
+ var str = toStr(value);
+ var isArgs = str === '[object Arguments]';
+ if (!isArgs) {
+ isArgs = !isArray(value) &&
+ value !== null &&
+ typeof value === 'object' &&
+ typeof value.length === 'number' &&
+ value.length >= 0 &&
+ isCallable(value.callee);
+ }
+ return isArgs;
+};
+
+defineProperties($Object, {
+ keys: function keys(object) {
+ var isFn = isCallable(object);
+ var isArgs = isArguments(object);
+ var isObject = object !== null && typeof object === 'object';
+ var isStr = isObject && isString(object);
+
+ if (!isObject && !isFn && !isArgs) {
+ throw new TypeError('Object.keys called on a non-object');
+ }
+
+ var theKeys = [];
+ var skipProto = hasProtoEnumBug && isFn;
+ if ((isStr && hasStringEnumBug) || isArgs) {
+ for (var i = 0; i < object.length; ++i) {
+ array_push.call(theKeys, $String(i));
+ }
+ }
+
+ if (!isArgs) {
+ for (var name in object) {
+ if (!(skipProto && name === 'prototype') && owns(object, name)) {
+ array_push.call(theKeys, $String(name));
+ }
+ }
+ }
+
+ if (hasDontEnumBug) {
+ var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+ for (var j = 0; j < dontEnumsLength; j++) {
+ var dontEnum = dontEnums[j];
+ if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
+ array_push.call(theKeys, dontEnum);
+ }
+ }
+ }
+ return theKeys;
+ }
+});
+
+var keysWorksWithArguments = $Object.keys && (function () {
+ // Safari 5.0 bug
+ return $Object.keys(arguments).length === 2;
+}(1, 2));
+var originalKeys = $Object.keys;
+defineProperties($Object, {
+ keys: function keys(object) {
+ if (isArguments(object)) {
+ return originalKeys(array_slice.call(object));
+ } else {
+ return originalKeys(object);
+ }
+ }
+}, !keysWorksWithArguments);
+
+//
+// Date
+// ====
+//
+
+// ES5 15.9.5.43
+// http://es5.github.com/#x15.9.5.43
+// This function returns a String value represent the instance in time
+// represented by this Date object. The format of the String is the Date Time
+// string format defined in 15.9.1.15. All fields are present in the String.
+// The time zone is always UTC, denoted by the suffix Z. If the time value of
+// this object is not a finite Number a RangeError exception is thrown.
+var negativeDate = -62198755200000;
+var negativeYearString = '-000001';
+var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
+var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
+
+defineProperties(Date.prototype, {
+ toISOString: function toISOString() {
+ var result, length, value, year, month;
+ if (!isFinite(this)) {
+ throw new RangeError('Date.prototype.toISOString called on non-finite value.');
+ }
+
+ year = this.getUTCFullYear();
+
+ month = this.getUTCMonth();
+ // see https://github.com/es-shims/es5-shim/issues/111
+ year += Math.floor(month / 12);
+ month = (month % 12 + 12) % 12;
+
+ // the date time string format is specified in 15.9.1.15.
+ result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
+ year = (
+ (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
+ strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
+ );
+
+ length = result.length;
+ while (length--) {
+ value = result[length];
+ // pad months, days, hours, minutes, and seconds to have two
+ // digits.
+ if (value < 10) {
+ result[length] = '0' + value;
+ }
+ }
+ // pad milliseconds to have three digits.
+ return (
+ year + '-' + array_slice.call(result, 0, 2).join('-') +
+ 'T' + array_slice.call(result, 2).join(':') + '.' +
+ strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z'
+ );
+ }
+}, hasNegativeDateBug || hasSafari51DateBug);
+
+// ES5 15.9.5.44
+// http://es5.github.com/#x15.9.5.44
+// This function provides a String representation of a Date object for use by
+// JSON.stringify (15.12.3).
+var dateToJSONIsSupported = (function () {
+ try {
+ return Date.prototype.toJSON &&
+ new Date(NaN).toJSON() === null &&
+ new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
+ Date.prototype.toJSON.call({ // generic
+ toISOString: function () { return true; }
+ });
+ } catch (e) {
+ return false;
+ }
+}());
+if (!dateToJSONIsSupported) {
+ Date.prototype.toJSON = function toJSON(key) {
+ // When the toJSON method is called with argument key, the following
+ // steps are taken:
+
+ // 1. Let O be the result of calling ToObject, giving it the this
+ // value as its argument.
+ // 2. Let tv be ES.ToPrimitive(O, hint Number).
+ var O = $Object(this);
+ var tv = ES.ToPrimitive(O);
+ // 3. If tv is a Number and is not finite, return null.
+ if (typeof tv === 'number' && !isFinite(tv)) {
+ return null;
+ }
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
+ // O with argument "toISOString".
+ var toISO = O.toISOString;
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
+ if (!isCallable(toISO)) {
+ throw new TypeError('toISOString property is not callable');
+ }
+ // 6. Return the result of calling the [[Call]] internal method of
+ // toISO with O as the this value and an empty argument list.
+ return toISO.call(O);
+
+ // NOTE 1 The argument is ignored.
+
+ // NOTE 2 The toJSON function is intentionally generic; it does not
+ // require that its this value be a Date object. Therefore, it can be
+ // transferred to other kinds of objects for use as a method. However,
+ // it does require that any such object have a toISOString method. An
+ // object is free to use the argument key to filter its
+ // stringification.
+ };
+}
+
+// ES5 15.9.4.2
+// http://es5.github.com/#x15.9.4.2
+// based on work shared by Daniel Friesen (dantman)
+// http://gist.github.com/303249
+var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
+var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
+var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
+if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
+ // XXX global assignment won't work in embeddings that use
+ // an alternate object for the context.
+ /* global Date: true */
+ /* eslint-disable no-undef */
+ Date = (function (NativeDate) {
+ /* eslint-enable no-undef */
+ // Date.length === 7
+ var DateShim = function Date(Y, M, D, h, m, s, ms) {
+ var length = arguments.length;
+ var date;
+ if (this instanceof NativeDate) {
+ date = length === 1 && $String(Y) === Y ? // isString(Y)
+ // We explicitly pass it through parse:
+ new NativeDate(DateShim.parse(Y)) :
+ // We have to manually make calls depending on argument
+ // length here
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
+ length >= 4 ? new NativeDate(Y, M, D, h) :
+ length >= 3 ? new NativeDate(Y, M, D) :
+ length >= 2 ? new NativeDate(Y, M) :
+ length >= 1 ? new NativeDate(Y) :
+ new NativeDate();
+ } else {
+ date = NativeDate.apply(this, arguments);
+ }
+ // Prevent mixups with unfixed Date object
+ defineProperties(date, { constructor: DateShim }, true);
+ return date;
+ };
+
+ // 15.9.1.15 Date Time String Format.
+ var isoDateExpression = new RegExp('^' +
+ '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
+ // 6-digit extended year
+ '(?:-(\\d{2})' + // optional month capture
+ '(?:-(\\d{2})' + // optional day capture
+ '(?:' + // capture hours:minutes:seconds.milliseconds
+ 'T(\\d{2})' + // hours capture
+ ':(\\d{2})' + // minutes capture
+ '(?:' + // optional :seconds.milliseconds
+ ':(\\d{2})' + // seconds capture
+ '(?:(\\.\\d{1,}))?' + // milliseconds capture
+ ')?' +
+ '(' + // capture UTC offset component
+ 'Z|' + // UTC capture
+ '(?:' + // offset specifier +/-hours:minutes
+ '([-+])' + // sign capture
+ '(\\d{2})' + // hours offset capture
+ ':(\\d{2})' + // minutes offset capture
+ ')' +
+ ')?)?)?)?' +
+ '$');
+
+ var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
+
+ var dayFromMonth = function dayFromMonth(year, month) {
+ var t = month > 1 ? 1 : 0;
+ return (
+ months[month] +
+ Math.floor((year - 1969 + t) / 4) -
+ Math.floor((year - 1901 + t) / 100) +
+ Math.floor((year - 1601 + t) / 400) +
+ 365 * (year - 1970)
+ );
+ };
+
+ var toUTC = function toUTC(t) {
+ return $Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
+ };
+
+ // Copy any custom methods a 3rd party library may have added
+ for (var key in NativeDate) {
+ if (owns(NativeDate, key)) {
+ DateShim[key] = NativeDate[key];
+ }
+ }
+
+ // Copy "native" methods explicitly; they may be non-enumerable
+ defineProperties(DateShim, {
+ now: NativeDate.now,
+ UTC: NativeDate.UTC
+ }, true);
+ DateShim.prototype = NativeDate.prototype;
+ defineProperties(DateShim.prototype, {
+ constructor: DateShim
+ }, true);
+
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
+ var parseShim = function parse(string) {
+ var match = isoDateExpression.exec(string);
+ if (match) {
+ // parse months, days, hours, minutes, seconds, and milliseconds
+ // provide default values if necessary
+ // parse the UTC offset component
+ var year = $Number(match[1]),
+ month = $Number(match[2] || 1) - 1,
+ day = $Number(match[3] || 1) - 1,
+ hour = $Number(match[4] || 0),
+ minute = $Number(match[5] || 0),
+ second = $Number(match[6] || 0),
+ millisecond = Math.floor($Number(match[7] || 0) * 1000),
+ // When time zone is missed, local offset should be used
+ // (ES 5.1 bug)
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=112
+ isLocalTime = Boolean(match[4] && !match[8]),
+ signOffset = match[9] === '-' ? 1 : -1,
+ hourOffset = $Number(match[10] || 0),
+ minuteOffset = $Number(match[11] || 0),
+ result;
+ if (
+ hour < (
+ minute > 0 || second > 0 || millisecond > 0 ?
+ 24 : 25
+ ) &&
+ minute < 60 && second < 60 && millisecond < 1000 &&
+ month > -1 && month < 12 && hourOffset < 24 &&
+ minuteOffset < 60 && // detect invalid offsets
+ day > -1 &&
+ day < (
+ dayFromMonth(year, month + 1) -
+ dayFromMonth(year, month)
+ )
+ ) {
+ result = (
+ (dayFromMonth(year, month) + day) * 24 +
+ hour +
+ hourOffset * signOffset
+ ) * 60;
+ result = (
+ (result + minute + minuteOffset * signOffset) * 60 +
+ second
+ ) * 1000 + millisecond;
+ if (isLocalTime) {
+ result = toUTC(result);
+ }
+ if (-8.64e15 <= result && result <= 8.64e15) {
+ return result;
+ }
+ }
+ return NaN;
+ }
+ return NativeDate.parse.apply(this, arguments);
+ };
+ defineProperties(DateShim, { parse: parseShim });
+
+ return DateShim;
+ }(Date));
+ /* global Date: false */
+}
+
+// ES5 15.9.4.4
+// http://es5.github.com/#x15.9.4.4
+if (!Date.now) {
+ Date.now = function now() {
+ return new Date().getTime();
+ };
+}
+
+//
+// Number
+// ======
+//
+
+// ES5.1 15.7.4.5
+// http://es5.github.com/#x15.7.4.5
+var hasToFixedBugs = NumberPrototype.toFixed && (
+ (0.00008).toFixed(3) !== '0.000' ||
+ (0.9).toFixed(0) !== '1' ||
+ (1.255).toFixed(2) !== '1.25' ||
+ (1000000000000000128).toFixed(0) !== '1000000000000000128'
+);
+
+var toFixedHelpers = {
+ base: 1e7,
+ size: 6,
+ data: [0, 0, 0, 0, 0, 0],
+ multiply: function multiply(n, c) {
+ var i = -1;
+ var c2 = c;
+ while (++i < toFixedHelpers.size) {
+ c2 += n * toFixedHelpers.data[i];
+ toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
+ c2 = Math.floor(c2 / toFixedHelpers.base);
+ }
+ },
+ divide: function divide(n) {
+ var i = toFixedHelpers.size, c = 0;
+ while (--i >= 0) {
+ c += toFixedHelpers.data[i];
+ toFixedHelpers.data[i] = Math.floor(c / n);
+ c = (c % n) * toFixedHelpers.base;
+ }
+ },
+ numToString: function numToString() {
+ var i = toFixedHelpers.size;
+ var s = '';
+ while (--i >= 0) {
+ if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
+ var t = $String(toFixedHelpers.data[i]);
+ if (s === '') {
+ s = t;
+ } else {
+ s += strSlice('0000000', 0, 7 - t.length) + t;
+ }
+ }
+ }
+ return s;
+ },
+ pow: function pow(x, n, acc) {
+ return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
+ },
+ log: function log(x) {
+ var n = 0;
+ var x2 = x;
+ while (x2 >= 4096) {
+ n += 12;
+ x2 /= 4096;
+ }
+ while (x2 >= 2) {
+ n += 1;
+ x2 /= 2;
+ }
+ return n;
+ }
+};
+
+defineProperties(NumberPrototype, {
+ toFixed: function toFixed(fractionDigits) {
+ var f, x, s, m, e, z, j, k;
+
+ // Test for NaN and round fractionDigits down
+ f = $Number(fractionDigits);
+ f = f !== f ? 0 : Math.floor(f);
+
+ if (f < 0 || f > 20) {
+ throw new RangeError('Number.toFixed called with invalid number of decimals');
+ }
+
+ x = $Number(this);
+
+ // Test for NaN
+ if (x !== x) {
+ return 'NaN';
+ }
+
+ // If it is too big or small, return the string value of the number
+ if (x <= -1e21 || x >= 1e21) {
+ return $String(x);
+ }
+
+ s = '';
+
+ if (x < 0) {
+ s = '-';
+ x = -x;
+ }
+
+ m = '0';
+
+ if (x > 1e-21) {
+ // 1e-21 < x < 1e21
+ // -70 < log2(x) < 70
+ e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
+ z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
+ z *= 0x10000000000000; // Math.pow(2, 52);
+ e = 52 - e;
+
+ // -18 < e < 122
+ // x = z / 2 ^ e
+ if (e > 0) {
+ toFixedHelpers.multiply(0, z);
+ j = f;
+
+ while (j >= 7) {
+ toFixedHelpers.multiply(1e7, 0);
+ j -= 7;
+ }
+
+ toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
+ j = e - 1;
+
+ while (j >= 23) {
+ toFixedHelpers.divide(1 << 23);
+ j -= 23;
+ }
+
+ toFixedHelpers.divide(1 << j);
+ toFixedHelpers.multiply(1, 1);
+ toFixedHelpers.divide(2);
+ m = toFixedHelpers.numToString();
+ } else {
+ toFixedHelpers.multiply(0, z);
+ toFixedHelpers.multiply(1 << (-e), 0);
+ m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
+ }
+ }
+
+ if (f > 0) {
+ k = m.length;
+
+ if (k <= f) {
+ m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
+ } else {
+ m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
+ }
+ } else {
+ m = s + m;
+ }
+
+ return m;
+ }
+}, hasToFixedBugs);
+
+//
+// String
+// ======
+//
+
+// ES5 15.5.4.14
+// http://es5.github.com/#x15.5.4.14
+
+// [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
+// Many browsers do not split properly with regular expressions or they
+// do not perform the split correctly under obscure conditions.
+// See http://blog.stevenlevithan.com/archives/cross-browser-split
+// I've tested in many browsers and this seems to cover the deviant ones:
+// 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
+// '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
+// 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
+// [undefined, "t", undefined, "e", ...]
+// ''.split(/.?/) should be [], not [""]
+// '.'.split(/()()/) should be ["."], not ["", "", "."]
+
+if (
+ 'ab'.split(/(?:ab)*/).length !== 2 ||
+ '.'.split(/(.?)(.?)/).length !== 4 ||
+ 'tesst'.split(/(s)*/)[1] === 't' ||
+ 'test'.split(/(?:)/, -1).length !== 4 ||
+ ''.split(/.?/).length ||
+ '.'.split(/()()/).length > 1
+) {
+ (function () {
+ var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
+
+ StringPrototype.split = function (separator, limit) {
+ var string = this;
+ if (typeof separator === 'undefined' && limit === 0) {
+ return [];
+ }
+
+ // If `separator` is not a regex, use native split
+ if (!isRegex(separator)) {
+ return strSplit(this, separator, limit);
+ }
+
+ var output = [];
+ var flags = (separator.ignoreCase ? 'i' : '') +
+ (separator.multiline ? 'm' : '') +
+ (separator.unicode ? 'u' : '') + // in ES6
+ (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
+ lastLastIndex = 0,
+ // Make `global` and avoid `lastIndex` issues by working with a copy
+ separator2, match, lastIndex, lastLength;
+ var separatorCopy = new RegExp(separator.source, flags + 'g');
+ string += ''; // Type-convert
+ if (!compliantExecNpcg) {
+ // Doesn't need flags gy, but they don't hurt
+ separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
+ }
+ /* Values for `limit`, per the spec:
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
+ * If 0, Infinity, or NaN: 0
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
+ * If other: Type-convert, then use the above rules
+ */
+ var splitLimit = typeof limit === 'undefined' ?
+ -1 >>> 0 : // Math.pow(2, 32) - 1
+ ES.ToUint32(limit);
+ match = separatorCopy.exec(string);
+ while (match) {
+ // `separatorCopy.lastIndex` is not reliable cross-browser
+ lastIndex = match.index + match[0].length;
+ if (lastIndex > lastLastIndex) {
+ array_push.call(output, strSlice(string, lastLastIndex, match.index));
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
+ // nonparticipating capturing groups
+ if (!compliantExecNpcg && match.length > 1) {
+ /* eslint-disable no-loop-func */
+ match[0].replace(separator2, function () {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (typeof arguments[i] === 'undefined') {
+ match[i] = void 0;
+ }
+ }
+ });
+ /* eslint-enable no-loop-func */
+ }
+ if (match.length > 1 && match.index < string.length) {
+ array_push.apply(output, array_slice.call(match, 1));
+ }
+ lastLength = match[0].length;
+ lastLastIndex = lastIndex;
+ if (output.length >= splitLimit) {
+ break;
+ }
+ }
+ if (separatorCopy.lastIndex === match.index) {
+ separatorCopy.lastIndex++; // Avoid an infinite loop
+ }
+ match = separatorCopy.exec(string);
+ }
+ if (lastLastIndex === string.length) {
+ if (lastLength || !separatorCopy.test('')) {
+ array_push.call(output, '');
+ }
+ } else {
+ array_push.call(output, strSlice(string, lastLastIndex));
+ }
+ return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output;
+ };
+ }());
+
+// [bugfix, chrome]
+// If separator is undefined, then the result array contains just one String,
+// which is the this value (converted to a String). If limit is not undefined,
+// then the output array is truncated so that it contains no more than limit
+// elements.
+// "0".split(undefined, 0) -> []
+} else if ('0'.split(void 0, 0).length) {
+ StringPrototype.split = function split(separator, limit) {
+ if (typeof separator === 'undefined' && limit === 0) { return []; }
+ return strSplit(this, separator, limit);
+ };
+}
+
+var str_replace = StringPrototype.replace;
+var replaceReportsGroupsCorrectly = (function () {
+ var groups = [];
+ 'x'.replace(/x(.)?/g, function (match, group) {
+ array_push.call(groups, group);
+ });
+ return groups.length === 1 && typeof groups[0] === 'undefined';
+}());
+
+if (!replaceReportsGroupsCorrectly) {
+ StringPrototype.replace = function replace(searchValue, replaceValue) {
+ var isFn = isCallable(replaceValue);
+ var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
+ if (!isFn || !hasCapturingGroups) {
+ return str_replace.call(this, searchValue, replaceValue);
+ } else {
+ var wrappedReplaceValue = function (match) {
+ var length = arguments.length;
+ var originalLastIndex = searchValue.lastIndex;
+ searchValue.lastIndex = 0;
+ var args = searchValue.exec(match) || [];
+ searchValue.lastIndex = originalLastIndex;
+ array_push.call(args, arguments[length - 2], arguments[length - 1]);
+ return replaceValue.apply(this, args);
+ };
+ return str_replace.call(this, searchValue, wrappedReplaceValue);
+ }
+ };
+}
+
+// ECMA-262, 3rd B.2.3
+// Not an ECMAScript standard, although ECMAScript 3rd Edition has a
+// non-normative section suggesting uniform semantics and it should be
+// normalized across all browsers
+// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
+var string_substr = StringPrototype.substr;
+var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
+defineProperties(StringPrototype, {
+ substr: function substr(start, length) {
+ var normalizedStart = start;
+ if (start < 0) {
+ normalizedStart = max(this.length + start, 0);
+ }
+ return string_substr.call(this, normalizedStart, length);
+ }
+}, hasNegativeSubstrBug);
+
+// ES5 15.5.4.20
+// whitespace from: http://es5.github.io/#x15.5.4.20
+var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
+ '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
+ '\u2029\uFEFF';
+var zeroWidth = '\u200b';
+var wsRegexChars = '[' + ws + ']';
+var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
+var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
+var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
+defineProperties(StringPrototype, {
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
+ // http://perfectionkills.com/whitespace-deviations/
+ trim: function trim() {
+ if (typeof this === 'undefined' || this === null) {
+ throw new TypeError("can't convert " + this + ' to object');
+ }
+ return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
+ }
+}, hasTrimWhitespaceBug);
+
+// ES-5 15.1.2.2
+if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
+ /* global parseInt: true */
+ parseInt = (function (origParseInt) {
+ var hexRegex = /^0[xX]/;
+ return function parseInt(str, radix) {
+ var string = $String(str).trim();
+ var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
+ return origParseInt(string, defaultedRadix);
+ };
+ }(parseInt));
+}
+
+}));
+
+},{}],26:[function(_dereq_,module,exports){
+var arr = [];
+var each = arr.forEach;
+var slice = arr.slice;
+
+
+module.exports = function(obj) {
+ each.call(slice.call(arguments, 1), function(source) {
+ if (source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ }
+ });
+ return obj;
+};
+
+},{}],27:[function(_dereq_,module,exports){
+module.exports = isFunction
+
+var toString = Object.prototype.toString
+
+function isFunction (fn) {
+ var string = toString.call(fn)
+ return string === '[object Function]' ||
+ (typeof fn === 'function' && string !== '[object RegExp]') ||
+ (typeof window !== 'undefined' &&
+ // IE8 and below
+ (fn === window.setTimeout ||
+ fn === window.alert ||
+ fn === window.confirm ||
+ fn === window.prompt))
+};
+
+},{}],28:[function(_dereq_,module,exports){
+"use strict";
+
+module.exports = function isObject(x) {
+ return typeof x === "object" && x !== null;
+};
+
+},{}],29:[function(_dereq_,module,exports){
+/*!
+ * $script.js JS loader & dependency manager
+ * https://github.com/ded/script.js
+ * (c) Dustin Diaz 2014 | License MIT
+ */
+
+(function (name, definition) {
+ if (typeof module != 'undefined' && module.exports) module.exports = definition()
+ else if (typeof define == 'function' && define.amd) define(definition)
+ else this[name] = definition()
+})('$script', function () {
+ var doc = document
+ , head = doc.getElementsByTagName('head')[0]
+ , s = 'string'
+ , f = false
+ , push = 'push'
+ , readyState = 'readyState'
+ , onreadystatechange = 'onreadystatechange'
+ , list = {}
+ , ids = {}
+ , delay = {}
+ , scripts = {}
+ , scriptpath
+ , urlArgs
+
+ function every(ar, fn) {
+ for (var i = 0, j = ar.length; i < j; ++i) if (!fn(ar[i])) return f
+ return 1
+ }
+ function each(ar, fn) {
+ every(ar, function (el) {
+ return !fn(el)
+ })
+ }
+
+ function $script(paths, idOrDone, optDone) {
+ paths = paths[push] ? paths : [paths]
+ var idOrDoneIsDone = idOrDone && idOrDone.call
+ , done = idOrDoneIsDone ? idOrDone : optDone
+ , id = idOrDoneIsDone ? paths.join('') : idOrDone
+ , queue = paths.length
+ function loopFn(item) {
+ return item.call ? item() : list[item]
+ }
+ function callback() {
+ if (!--queue) {
+ list[id] = 1
+ done && done()
+ for (var dset in delay) {
+ every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = [])
+ }
+ }
+ }
+ setTimeout(function () {
+ each(paths, function loading(path, force) {
+ if (path === null) return callback()
+ path = !force && path.indexOf('.js') === -1 && !/^https?:\/\//.test(path) && scriptpath ? scriptpath + path + '.js' : path
+ if (scripts[path]) {
+ if (id) ids[id] = 1
+ return (scripts[path] == 2) ? callback() : setTimeout(function () { loading(path, true) }, 0)
+ }
+
+ scripts[path] = 1
+ if (id) ids[id] = 1
+ create(path, callback)
+ })
+ }, 0)
+ return $script
+ }
+
+ function create(path, fn) {
+ var el = doc.createElement('script'), loaded
+ el.onload = el.onerror = el[onreadystatechange] = function () {
+ if ((el[readyState] && !(/^c|loade/.test(el[readyState]))) || loaded) return;
+ el.onload = el[onreadystatechange] = null
+ loaded = 1
+ scripts[path] = 2
+ fn()
+ }
+ el.async = 1
+ el.src = urlArgs ? path + (path.indexOf('?') === -1 ? '?' : '&') + urlArgs : path;
+ head.insertBefore(el, head.lastChild)
+ }
+
+ $script.get = create
+
+ $script.order = function (scripts, id, done) {
+ (function callback(s) {
+ s = scripts.shift()
+ !scripts.length ? $script(s, id, done) : $script(s, callback)
+ }())
+ }
+
+ $script.path = function (p) {
+ scriptpath = p
+ }
+ $script.urlArgs = function (str) {
+ urlArgs = str;
+ }
+ $script.ready = function (deps, ready, req) {
+ deps = deps[push] ? deps : [deps]
+ var missing = [];
+ !each(deps, function (dep) {
+ list[dep] || missing[push](dep);
+ }) && every(deps, function (dep) {return list[dep]}) ?
+ ready() : !function (key) {
+ delay[key] = delay[key] || []
+ delay[key][push](ready)
+ req && req(missing)
+ }(deps.join('|'))
+ return $script
+ }
+
+ $script.done = function (idOrDone) {
+ $script([null], idOrDone)
+ }
+
+ return $script
+});
+
+},{}]},{},[19])(19)
+});
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/flowplayer.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/flowplayer.min.js Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,8 @@
+/*!
+
+ Flowplayer v6.0.3 (Thursday, 23. July 2015 09:32PM) | flowplayer.org/license
+
+*/
+!function(e){function t(e,t,n,r){for(var i,a=n.slice(),l=o(t,e),s=0,u=a.length;u>s&&(handler=a[s],"object"==typeof handler&&"function"==typeof handler.handleEvent?handler.handleEvent(l):handler.call(e,l),!l.stoppedImmediatePropagation);s++);return i=!l.stoppedPropagation,r&&i&&e.parentNode?e.parentNode.dispatchEvent(l):!l.defaultPrevented}function n(e,t){return{configurable:!0,get:e,set:t}}function r(e,t,r){var o=y(t||e,r);h(e,"textContent",n(function(){return o.get.call(this)},function(e){o.set.call(this,e)}))}function o(e,t){return e.currentTarget=t,e.eventPhase=e.target===e.currentTarget?2:3,e}function i(e,t){for(var n=e.length;n--&&e[n]!==t;);return n}function a(){if("BR"===this.tagName)return"\n";for(var e=this.firstChild,t=[];e;)8!==e.nodeType&&7!==e.nodeType&&t.push(e.textContent),e=e.nextSibling;return t.join("")}function l(e){var t=document.createEvent("Event");t.initEvent("input",!0,!0),(e.srcElement||e.fromElement||document).dispatchEvent(t)}function s(e){!d&&k.test(document.readyState)&&(d=!d,document.detachEvent(p,s),e=document.createEvent("Event"),e.initEvent(v,!0,!0),document.dispatchEvent(e))}function u(e){for(var t;t=this.lastChild;)this.removeChild(t);null!=e&&this.appendChild(document.createTextNode(e))}function c(t,n){return n||(n=e.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(!document.createEvent){var f=!0,d=!1,p="onreadystatechange",v="DOMContentLoaded",m="__IE8__"+Math.random(),h=Object.defineProperty||function(e,t,n){e[t]=n.value},g=Object.defineProperties||function(t,n){for(var r in n)if(b.call(n,r))try{h(t,r,n[r])}catch(o){e.console&&console.log(r+" failed on object:",t,o.message)}},y=Object.getOwnPropertyDescriptor,b=Object.prototype.hasOwnProperty,w=e.Element.prototype,x=e.Text.prototype,E=/^[a-z]+$/,k=/loaded|complete/,T={},S=document.createElement("div");r(e.HTMLCommentElement.prototype,w,"nodeValue"),r(e.HTMLScriptElement.prototype,null,"text"),r(x,null,"nodeValue"),r(e.HTMLTitleElement.prototype,null,"text"),h(e.HTMLStyleElement.prototype,"textContent",function(e){return n(function(){return e.get.call(this.styleSheet)},function(t){e.set.call(this.styleSheet,t)})}(y(e.CSSStyleSheet.prototype,"cssText"))),g(w,{textContent:{get:a,set:u},firstElementChild:{get:function(){for(var e=this.childNodes||[],t=0,n=e.length;n>t;t++)if(1==e[t].nodeType)return e[t]}},lastElementChild:{get:function(){for(var e=this.childNodes||[],t=e.length;t--;)if(1==e[t].nodeType)return e[t]}},oninput:{get:function(){return this._oninput||null},set:function(e){this._oninput&&(this.removeEventListener("input",this._oninput),this._oninput=e,e&&this.addEventListener("input",e))}},previousElementSibling:{get:function(){for(var e=this.previousSibling;e&&1!=e.nodeType;)e=e.previousSibling;return e}},nextElementSibling:{get:function(){for(var e=this.nextSibling;e&&1!=e.nodeType;)e=e.nextSibling;return e}},childElementCount:{get:function(){for(var e=0,t=this.childNodes||[],n=t.length;n--;e+=1==t[n].nodeType);return e}},addEventListener:{value:function(e,n,r){var o,a=this,s="on"+e,u=a[m]||h(a,m,{value:{}})[m],f=u[s]||(u[s]={}),d=f.h||(f.h=[]);if(!b.call(f,"w")){if(f.w=function(e){return e[m]||t(a,c(a,e),d,!1)},!b.call(T,s))if(E.test(e))try{o=document.createEventObject(),o[m]=!0,9!=a.nodeType&&null==a.parentNode&&S.appendChild(a),a.fireEvent(s,o),T[s]=!0}catch(o){for(T[s]=!1;S.hasChildNodes();)S.removeChild(S.firstChild)}else T[s]=!1;(f.n=T[s])&&a.attachEvent(s,f.w)}i(d,n)<0&&d[r?"unshift":"push"](n),"input"===e&&a.attachEvent("onkeyup",l)}},dispatchEvent:{value:function(e){var n,r=this,o="on"+e.type,i=r[m],a=i&&i[o],l=!!a;return e.target||(e.target=r),l?a.n?r.fireEvent(o,e):t(r,e,a.h,!0):(n=r.parentNode)?n.dispatchEvent(e):!0,!e.defaultPrevented}},removeEventListener:{value:function(e,t,n){var r=this,o="on"+e,a=r[m],l=a&&a[o],s=l&&l.h,u=s?i(s,t):-1;u>-1&&s.splice(u,1)}}}),g(x,{addEventListener:{value:w.addEventListener},dispatchEvent:{value:w.dispatchEvent},removeEventListener:{value:w.removeEventListener}}),g(e.XMLHttpRequest.prototype,{addEventListener:{value:function(e,t,n){var r=this,o="on"+e,a=r[m]||h(r,m,{value:{}})[m],l=a[o]||(a[o]={}),s=l.h||(l.h=[]);i(s,t)<0&&(r[o]||(r[o]=function(){var t=document.createEvent("Event");t.initEvent(e,!0,!0),r.dispatchEvent(t)}),s[n?"unshift":"push"](t))}},dispatchEvent:{value:function(e){var n=this,r="on"+e.type,o=n[m],i=o&&o[r],a=!!i;return a&&(i.n?n.fireEvent(r,e):t(n,e,i.h,!0))}},removeEventListener:{value:w.removeEventListener}}),g(e.Event.prototype,{bubbles:{value:!0,writable:!0},cancelable:{value:!0,writable:!0},preventDefault:{value:function(){this.cancelable&&(this.defaultPrevented=!0,this.returnValue=!1)}},stopPropagation:{value:function(){this.stoppedPropagation=!0,this.cancelBubble=!0}},stopImmediatePropagation:{value:function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}},initEvent:{value:function(e,t,n){this.type=e,this.bubbles=!!t,this.cancelable=!!n,this.bubbles||this.stopPropagation()}}}),g(e.HTMLDocument.prototype,{defaultView:{get:function(){return this.parentWindow}},textContent:{get:function(){return 11===this.nodeType?a.call(this):null},set:function(e){11===this.nodeType&&u.call(this,e)}},addEventListener:{value:function(t,n,r){var o=this;w.addEventListener.call(o,t,n,r),f&&t===v&&!k.test(o.readyState)&&(f=!1,o.attachEvent(p,s),e==top&&function i(e){try{o.documentElement.doScroll("left"),s()}catch(t){setTimeout(i,50)}}())}},dispatchEvent:{value:w.dispatchEvent},removeEventListener:{value:w.removeEventListener},createEvent:{value:function(e){var t;if("Event"!==e)throw new Error("unsupported "+e);return t=document.createEventObject(),t.timeStamp=(new Date).getTime(),t}}}),g(e.Window.prototype,{getComputedStyle:{value:function(){function e(e){this._=e}function t(){}var n=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,r=/^(top|right|bottom|left)$/,o=/\-([a-z])/g,i=function(e,t){return t.toUpperCase()};return e.prototype.getPropertyValue=function(e){var t,a,l,s=this._,u=s.style,c=s.currentStyle,f=s.runtimeStyle;return e=("float"===e?"style-float":e).replace(o,i),t=c?c[e]:u[e],n.test(t)&&!r.test(e)&&(a=u.left,l=f&&f.left,l&&(f.left=c.left),u.left="fontSize"===e?"1em":t,t=u.pixelLeft+"px",u.left=a,l&&(f.left=l)),null==t?t:t+""||"auto"},t.prototype.getPropertyValue=function(){return null},function(n,r){return r?new t(n):new e(n)}}()},addEventListener:{value:function(n,r,o){var a,l=e,s="on"+n;l[s]||(l[s]=function(e){return t(l,c(l,e),a,!1)}),a=l[s][m]||(l[s][m]=[]),i(a,r)<0&&a[o?"unshift":"push"](r)}},dispatchEvent:{value:function(t){var n=e["on"+t.type];return n?n.call(e,t)!==!1&&!t.defaultPrevented:!0}},removeEventListener:{value:function(t,n,r){var o="on"+t,a=(e[o]||Object)[m],l=a?i(a,n):-1;l>-1&&a.splice(l,1)}}})}}(this),!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.flowplayer=e()}}(function(){var e;return function t(e,n,r){function o(a,l){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[a]={exports:{}};e[a][0].call(c.exports,function(t){var n=e[a][1][t];return o(n?n:t)},c,c.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a"+n+""+e+">").attr(t)[0]}},r.toggleClass=function(e,t,n){if(e){var r=o(e);"undefined"==typeof n?r.toggle(t):n?r.add(t):n||r.remove(t)}},r.addClass=function(e,t){return r.toggleClass(e,t,!0)},r.removeClass=function(e,t){return r.toggleClass(e,t,!1)},r.append=function(e,t){return e.appendChild(t),e},r.appendTo=function(e,t){return r.append(t,e),e},r.prepend=function(e,t){e.insertBefore(t,e.firstChild)},r.insertAfter=function(e,t,n){t==r.lastChild(e)&&e.appendChild(n);var o=Array.prototype.indexOf.call(e.children,t);e.insertBefore(n,e.children[o+1])},r.html=function(e,t){e=e.length?e:[e],e.forEach(function(e){e.innerHTML=t})},r.attr=function(e,t,n){if("class"===t&&(t="className"),r.hasOwnOrPrototypeProperty(e,t))try{e[t]=n}catch(o){if(!i)throw o;i(e).attr(t,n)}else n===!1?e.removeAttribute(t):e.setAttribute(t,n);return e},r.prop=function(e,t,n){return"undefined"==typeof n?e&&e[t]:void(e[t]=n)},r.offset=function(e){var t=e.getBoundingClientRect();return e.offsetWidth/e.offsetHeight>e.clientWidth/e.clientHeight&&(t={left:100*t.left,right:100*t.right,top:100*t.top,bottom:100*t.bottom,width:100*t.width,height:100*t.height}),t},r.width=function(e,t){if(t)return e.style.width=(""+t).replace(/px$/,"")+"px";var n=r.offset(e).width;return"undefined"==typeof n?e.offsetWidth:n},r.height=function(e,t){if(t)return e.style.height=(""+t).replace(/px$/,"")+"px";var n=r.offset(e).height;return"undefined"==typeof n?e.offsetHeight:n},r.lastChild=function(e){return e.children[e.children.length-1]},r.hasParent=function(e,t){for(var n=e.parentElement;n;){if(r.matches(n,t))return!0;n=n.parentElement}return!1},r.createAbsoluteUrl=function(e){return r.createElement("a",{href:e}).href},r.xhrGet=function(e,t,n){var r=new XMLHttpRequest;r.onreadystatechange=function(){return 4===this.readyState?this.status>=400?n():void t(this.responseText):void 0},r.open("get",e,!0),r.send()},r.pick=function(e,t){var n={};return t.forEach(function(t){e.hasOwnProperty(t)&&(n[t]=e[t])}),n},r.hostname=function(e){return a.toUnicode(e||window.location.hostname)},r.browser={webkit:"WebkitAppearance"in document.documentElement.style},r.getPrototype=function(e){return Object.getPrototypeOf?Object.getPrototypeOf(e):e.__proto__},r.hasOwnOrPrototypeProperty=function(e,t){for(var n=e;n;){if(Object.prototype.hasOwnProperty.call(n,t))return!0;n=r.getPrototype(n)}return!1},r.matches=function(e,t){var n=Element.prototype,r=n.matches||n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector||function(e){for(var t=this,n=(t.document||t.ownerDocument).querySelectorAll(e),r=0;n[r]&&n[r]!==t;)r++;return n[r]?!0:!1};return r.call(e,t)},function(e){function t(e){return e.replace(/-[a-z]/g,function(e){return e[1].toUpperCase()})}"undefined"!=typeof e.setAttribute&&(e.setProperty=function(e,n){return this.setAttribute(t(e),String(n))},e.getPropertyValue=function(e){return this.getAttribute(t(e))||null},e.removeProperty=function(e){var n=this.getPropertyValue(e);return this.removeAttribute(t(e)),n})}(window.CSSStyleDeclaration.prototype)},{"class-list":22,"computed-style":24,punycode:21}],2:[function(e,t,n){"use strict";var r=e("../common");t.exports=function(e,t,n,o){n=n||"opaque";var i="obj"+(""+Math.random()).slice(2,15),a='-1;a+=l?'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">':' data="'+e+'" type="application/x-shockwave-flash">';var s={width:"100%",height:"100%",allowscriptaccess:"always",wmode:n,quality:"high",flashvars:"",movie:e+(l?"?"+i:""),name:i};"transparent"!==n&&(s.bgcolor=o||"#333333"),Object.keys(t).forEach(function(e){s.flashvars+=e+"="+t[e]+"&"}),Object.keys(s).forEach(function(e){a+=' '}),a+=" ";var u=r.createElement("div",{},a);return r.find("object",u)},window.attachEvent&&window.attachEvent("onbeforeunload",function(){__flash_savedUnloadHandler=__flash_unloadHandler=function(){}})},{"../common":1}],3:[function(e,t,n){"use strict";var r,o=e("../flowplayer"),i=e("../common"),a=e("./embed"),l=e("extend-object"),s=e("bean");r=function(e,t){function n(e){function t(e){return("0"+parseInt(e).toString(16)).slice(-2)}return(e=e.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/))?"#"+t(e[1])+t(e[2])+t(e[3]):void 0}function u(e){if(7===e.length)return e;var t=e.split("").slice(1);return"#"+t.map(function(e){return e+e}).join("")}function c(e){return/application\/x-mpegurl/i.test(e.type)}var f,d,p,v=e.conf,m=(e.video,window,{engineName:r.engineName,pick:function(t){if(o.support.flashVideo){for(var n,r,i=0;i video",t)[0],y=h(r.src),b=/^https?:/.test(y),w=function(){i.removeNode(g)},x=function(e){return e.some(function(e){return!!g.canPlayType(e.type)})};o.support.video&&i.prop(g,"autoplay")&&x(r.sources)?s.one(g,"timeupdate",w):w();var E=r.rtmp||v.rtmp;if(b||E||(y=i.createAbsoluteUrl(y)),p&&c(r)&&p.data!==v.swfHls&&m.unload(),p){["live","preload","loop"].forEach(function(e){r.hasOwnProperty(e)&&p.__set(e,r[e])}),Object.keys(r.flashls||{}).forEach(function(e){p.__set("hls_"+e,r.flashls[e])});var k=!1;if(!b&&E)p.__set("rtmp",E.url||E);else{var T=p.__get("rtmp");k=!!T,p.__set("rtmp",null)}p.__play(y,k||r.rtmp&&r.rtmp!==v.rtmp)}else{d="fpCallback"+(""+Math.random()).slice(3,15);var S={hostname:v.embedded?i.hostname(v.hostname):i.hostname(location.hostname),url:y,callback:d};t.getAttribute("data-origin")&&(S.origin=t.getAttribute("data-origin")),["proxy","key","autoplay","preload","subscribe","live","loop","debug","splash","poster","rtmpt"].forEach(function(e){v.hasOwnProperty(e)&&(S[e]=v[e]),r.hasOwnProperty(e)&&(S[e]=r[e]),(v.rtmp||{}).hasOwnProperty(e)&&(S[e]=(v.rtmp||{})[e]),(r.rtmp||{}).hasOwnProperty(e)&&(S[e]=(r.rtmp||{})[e])}),v.rtmp&&(S.rtmp=v.rtmp.url||v.rtmp),r.rtmp&&(S.rtmp=r.rtmp.url||r.rtmp),Object.keys(r.flashls||{}).forEach(function(e){var t=r.flashls[e];S["hls_"+e]=t}),void 0!==v.bufferTime&&(S.bufferTime=v.bufferTime),b&&delete S.rtmp,S.rtmp&&(S.rtmp=h(S.rtmp));var C,N=i.css(t,"background-color")||"";0===N.indexOf("rgb")?C=n(N):0===N.indexOf("#")&&(C=u(N)),S.initialVolume=e.volumeLevel;var O=c(r)?v.swfHls:v.swf;p=a(O,S,v.wmode,C)[0];var j=i.find(".fp-player",t)[0];i.prepend(j,p),setTimeout(function(){try{if(!p.PercentLoaded())return e.trigger("error",[e,{code:7,url:v.swf}])}catch(t){}},5e3),setTimeout(function(){"undefined"==typeof p.PercentLoaded&&e.trigger("flashdisabled",[e])},1e3),p.pollInterval=setInterval(function(){if(p){var t=p.__status?p.__status():null;t&&(e.playing&&t.time&&t.time!==e.video.time&&e.trigger("progress",[e,t.time]),r.buffer=t.buffer/r.bytes*r.duration,e.trigger("buffer",[e,r.buffer]),!r.buffered&&t.time>0&&(r.buffered=!0,e.trigger("buffered",[e])))}},250),window[d]=function(n,r){var o=f;v.debug&&(0===n.indexOf("debug")&&r&&r.length?console.log.apply(console,["-- "+n].concat(r)):console.log("--",n,r));var i={type:n};switch(n){case"ready":r=l(o,r);break;case"click":i.flash=!0;break;case"keydown":i.which=r;break;case"seek":o.time=r;break;case"status":e.trigger("progress",[e,r.time]),r.buffer",i,s),(e.ready||/ready|error/.test(i))&&i&&p.find("video",t).length)){var u;if("unload"===i)return void e.unload();var c=function(){e.trigger(i,[e,u])};switch(i){case"ready":u=d(a,{duration:n.duration,width:n.videoWidth,height:n.videoHeight,url:n.currentSrc,src:n.currentSrc});try{u.seekable=!w.live&&/mpegurl/i.test(a?a.type||"":"")&&n.duration||n.seekable&&n.seekable.end(null)}catch(m){}if(v=v||setInterval(function(){try{u.buffer=n.buffered.end(null)}catch(t){}u.buffer&&(r(u.buffer,1e3)0||e.live)u=Math.max(n.currentTime,0);else if("progress"==i)return;break;case"speed":u=r(n.playbackRate);break;case"volume":u=r(n.volume);break;case"error":try{u=(s.srcElement||s.originalTarget).error,u.video=d(a,{src:n.src,url:n.src})}catch(y){return}}c()}},!0)}))}var o,v,g,y=p.findDirect("video",t)[0]||p.find(".fp-player > video",t)[0],b=u.support,w=(p.find("track",y)[0],e.conf);return o={engineName:s.engineName,pick:function(e){if(b.video){if(w.videoTypePreference){var t=a(e,w.videoTypePreference);if(t)return t}for(var n=0;n=0&&o(t).add("cue"+e)}function r(t){var n=t&&!isNaN(t.time)?t.time:t;return 0>n&&(n=e.video.duration+n),.125*Math.round(n/.125)}var l=/ ?cue\d+ ?/,s=!1,u={},c=-.125,f=function(t){var r=e.cuepoints.indexOf(t);isNaN(t)||(t={time:t}),t.index=r,n(r),e.trigger("cuepoint",[e,t])};e.on("progress",function(e,t,n){if(!s)for(var o=r(n);o>c;)c+=.125,u[c]&&u[c].forEach(f)}).on("unload",n).on("beforeseek",function(){s=!0}).on("seek",function(e,t,o){n(),c=r(o||0)-.125,s=!1,!o&&u[0]&&u[0].forEach(f)}).on("ready",function(t,n,r){c=-.125;var o=r.cuepoints||e.conf.cuepoints||[];e.setCuepoints(o)}).on("finish",function(){c=-.125}),e.conf.generate_cuepoints&&e.bind("load",function(){i.find(".fp-cuepoint",t).forEach(i.removeNode)}),e.setCuepoints=function(t){return e.cuepoints=[],u={},t.forEach(e.addCuepoint),e},e.addCuepoint=function(n){e.cuepoints||(e.cuepoints=[]);var o=r(n);if(u[o]||(u[o]=[]),u[o].push(n),e.cuepoints.push(n),e.conf.generate_cuepoints&&n.visible!==!1){var l=e.video.duration,s=i.find(".fp-timeline",t)[0];i.css(s,"overflow","visible");var c=n.time||n;0>c&&(c=l+n);var f=i.createElement("a",{className:"fp-cuepoint fp-cuepoint"+(e.cuepoints.length-1)});i.css(f,"left",c/l*100+"%"),s.appendChild(f),a.on(f,"mousedown",function(t){return t.preventDefault(),e.seek(c),!1})}return e},e.removeCuepoint=function(t){var n=e.cuepoints.indexOf(t),o=r(t);if(-1!==n){e.cuepoints=e.cuepoints.slice(0,n).concat(e.cuepoints.slice(n+1));var i=u[o].indexOf(t);if(-1!==i)return u[o]=u[o].slice(0,i).concat(u[o].slice(i+1)),e}}})},{"../common":1,"../flowplayer":18,bean:20,"class-list":22}],7:[function(e,t,n){"use strict";var r=e("../flowplayer"),o=e("bean"),i=e("../common"),a=(e("is-object"),e("extend-object")),l=e("class-list");r(function(e,t){if(e.conf.embed!==!1){var n=(e.conf,i.find(".fp-ui",t)[0]),r=i.createElement("a",{"class":"fp-embed",title:"Copy to your site"}),l=i.createElement("div",{"class":"fp-embed-code"},"Paste this HTML code on your site to embed. "),u=i.find("textarea",l)[0];n.appendChild(r),n.appendChild(l),e.embedCode=function(){var n=e.conf.embed||{},r=e.video;if(n.iframe){var o=(e.conf.embed.iframe,n.width||r.width||i.width(t)),l=n.height||r.height||i.height(t);return''}var s=["ratio","rtmp","live","bufferTime","origin","analytics","key","subscribe","swf","swfHls","embed","adaptiveRatio","logo"];n.playlist&&s.push("playlist");var u=i.pick(e.conf,s);u.logo&&(u.logo=i.createElement("img",{src:u.logo}).src),n.playlist&&e.conf.playlist.length||(u.clip=a({},e.conf.clip,i.pick(e.video,["sources"])));var c='var w=window,d=document,e;w._fpes||(w._fpes=[],w.addEventListener("load",function(){var s=d.createElement("script");s.src="//embed.flowplayer.org/6.0.3/embed.min.js",d.body.appendChild(s)})),e=[].slice.call(d.getElementsByTagName("script"),-1)[0].parentNode,w._fpes.push({e:e,l:"$library",c:$conf});\n'.replace("$conf",JSON.stringify(u)).replace("$library",n.library||"");return'Watch video!\n '.replace("$href",e.conf.origin||window.location.href).replace("$script",c)},s(t,".fp-embed","is-embedding"),o.on(t,"click",".fp-embed-code textarea",function(){u.select()}),o.on(t,"click",".fp-embed",function(){u.textContent=e.embedCode().replace(/(\r\n|\n|\r)/gm,""),u.focus(),u.select()})}});var s=function(e,t,n){function r(){a.remove(n),o.off(document,".st")}var a=l(e);o.on(e,"click",t||"a",function(e){e.preventDefault(),a.toggle(n),a.contains(n)&&(o.on(document,"keydown.st",function(e){27==e.which&&r()}),o.on(document,"click.st",function(e){i.hasParent(e.target,"."+n)||r()}))})}},{"../common":1,"../flowplayer":18,bean:20,"class-list":22,"extend-object":26,"is-object":28}],8:[function(e,t,n){"use strict";t.exports=function(e,t){t||(t=document.createElement("div"));var n={},r={},o=function(e,o,i){var a=e.split(".")[0],l=function(s){i&&(t.removeEventListener(a,l),n[e].splice(n[e].indexOf(l),1));var u=[s].concat(r[s.timeStamp+s.type]||[]);o&&o.apply(void 0,u)};t.addEventListener(a,l),n[e]||(n[e]=[]),n[e].push(l)};e.on=e.bind=function(t,n){var r=t.split(" ");return r.forEach(function(e){o(e,n)}),e},e.one=function(t,n){var r=t.split(" ");return r.forEach(function(e){o(e,n,!0)}),e};var i=function(e,t){return 0===t.filter(function(t){return-1===e.indexOf(t)}).length};e.off=e.unbind=function(r){var o=r.split(" ");return o.forEach(function(e){var r=e.split(".").slice(1),o=e.split(".")[0];Object.keys(n).filter(function(e){var t=e.split(".").slice(1);return(!o||0===e.indexOf(o))&&i(t,r)}).forEach(function(e){var r=n[e],o=e.split(".")[0];r.forEach(function(e){t.removeEventListener(o,e),r.splice(r.indexOf(e),1)})})}),e},e.trigger=function(n,o,i){if(n){o=(o||[]).length?o||[]:[o];var a,l=document.createEvent("Event");return a=n.type||n,l.initEvent(a,!1,!0),r[l.timeStamp+l.type]=o,t.dispatchEvent(l),i?l:e}}},t.exports.EVENTS=["beforeseek","disable","error","finish","fullscreen","fullscreen-exit","load","mute","pause","progress","ready","resume","seek","speed","stop","unload","volume","boot","shutdown"]},{}],9:[function(e,t,n){"use strict";var r,o=e("../flowplayer"),i=e("bean"),a=e("class-list"),l=(e("extend-object"),e("../common")),s=(o.support.browser.mozilla?"moz":"webkit","fullscreen"),u="fullscreen-exit",c=o.support.fullscreen,f=("function"==typeof document.exitFullscreen,navigator.userAgent.toLowerCase()),d=/(safari)[ \/]([\w.]+)/.exec(f)&&!/(chrome)[ \/]([\w.]+)/.exec(f);i.on(document,"fullscreenchange.ffscr webkitfullscreenchange.ffscr mozfullscreenchange.ffscr MSFullscreenChange.ffscr",function(e){var t=document.webkitCurrentFullScreenElement||document.mozFullScreenElement||document.fullscreenElement||document.msFullscreenElement||e.target;if(r||t.parentNode&&t.parentNode.getAttribute("data-flowplayer-instance-id")){var n=r||o(t.parentNode);t&&!r?r=n.trigger(s,[t]):(r.trigger(u,[r]),r=null)}}),o(function(e,t){var n=l.createElement("div",{className:"fp-player"});if(Array.prototype.map.call(t.children,l.identity).forEach(function(e){l.matches(e,".fp-ratio,script")||n.appendChild(e)}),t.appendChild(n),e.conf.fullscreen){var o,f,p=window,v=a(t);e.isFullscreen=!1,e.fullscreen=function(t){return e.disabled?void 0:(void 0===t&&(t=!e.isFullscreen),t&&(o=p.scrollY,f=p.scrollX),c?t?["requestFullScreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen"].forEach(function(e){return"function"==typeof n[e]?(n[e](Element.ALLOW_KEYBOARD_INPUT),!d||document.webkitCurrentFullScreenElement||document.mozFullScreenElement||n[e](),!1):void 0}):["exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"].forEach(function(e){return"function"==typeof document[e]?(document[e](),!1):void 0}):e.trigger(t?s:u,[e]),e)};var m;e.on("mousedown.fs",function(){+new Date-m<150&&e.ready&&e.fullscreen(),m=+new Date}),e.on(s,function(n){v.add("is-fullscreen"),c||l.css(t,"position","fixed"),e.isFullscreen=!0}).on(u,function(n){var r;c||"html5"!==e.engine||(r=t.css("opacity")||"",l.css(t,"opacity",0)),c||l.css(t,"position",""),v.remove("is-fullscreen"),c||"html5"!==e.engine||setTimeout(function(){t.css("opacity",r)}),e.isFullscreen=!1,p.scrollTo(f,o)}).on("unload",function(){e.isFullscreen&&e.fullscreen()}),e.on("shutdown",function(){i.off(document,".ffscr"),r=null})}})},{"../common":1,"../flowplayer":18,bean:20,"class-list":22,"extend-object":26}],10:[function(e,t,n){"use strict";var r,o,i=e("../flowplayer"),a=e("bean"),l="is-help",s=e("../common"),u=e("class-list");a.on(document,"keydown.fp",function(e){var t=r,n=e.ctrlKey||e.metaKey||e.altKey,i=e.which,a=t&&t.conf,s=o&&u(o);if(t&&a.keyboard&&!t.disabled){if(-1!=[63,187,191].indexOf(i))return s.toggle(l),!1;if(27==i&&s.contains(l))return s.toggle(l),!1;if(!n&&t.ready){if(e.preventDefault(),e.shiftKey)return void(39==i?t.speed(!0):37==i&&t.speed(!1));if(58>i&&i>47)return t.seekTo(i-48);switch(i){case 38:case 75:t.volume(t.volumeLevel+.15);break;case 40:case 74:t.volume(t.volumeLevel-.15);break;case 39:case 76:t.seeking=!0,t.seek(!0);break;case 37:case 72:t.seeking=!0,t.seek(!1);break;case 190:t.seekTo();break;case 32:t.toggle();break;case 70:a.fullscreen&&t.fullscreen();break;case 77:t.mute();break;case 81:t.unload()}}}}),i(function(e,t){if(e.conf.keyboard){a.on(t,"mouseenter mouseleave",function(n){r=e.disabled||"mouseover"!=n.type?0:e,r&&(o=t)});var n=i.support.video&&"flash"!==e.conf.engine&&document.createElement("video").playbackRate?"shift + ← → slower / faster
":"";if(t.appendChild(s.createElement("div",{className:"fp-help"},' space play / pause
q unload | stop
f fullscreen
'+n+'
← → seek
. seek to previous
1 2 … 6 seek to 10%, 20% … 60%
')),
+e.conf.tooltip){var c=s.find(".fp-ui",t)[0];c.setAttribute("title","Hit ? for help"),a.one(t,"mouseout.tip",".fp-ui",function(){c.removeAttribute("title")})}a.on(t,"click",".fp-close",function(){u(t).toggle(l)}),e.bind("shutdown",function(){o==t&&(o=null)})}})},{"../common":1,"../flowplayer":18,bean:20,"class-list":22}],11:[function(e,t,n){"use strict";var r=e("../flowplayer"),o=/IEMobile/.test(window.navigator.userAgent),i=e("class-list"),a=e("../common"),l=e("bean"),s=e("./ui").format,u=window.navigator.userAgent;(r.support.touch||o)&&r(function(e,t){var n=/Android/.test(u)&&!/Firefox/.test(u)&&!/Opera/.test(u),c=/Silk/.test(u),f=n?parseFloat(/Android\ (\d\.\d)/.exec(u)[1],10):0,d=i(t);if(n&&!o){if(!/Chrome/.test(u)&&4>f){var p=e.load;e.load=function(t,n){var r=p.apply(e,arguments);return e.trigger("ready",[e,e.video]),r}}var v,m=0,h=function(e){v=setInterval(function(){e.video.time=++m,e.trigger("progress",[e,m])},1e3)};e.bind("ready pause unload",function(){v&&(clearInterval(v),v=null)}),e.bind("ready",function(){m=0}),e.bind("resume",function(t,n){return n.live?m?h(n):void e.one("progress",function(e,t,n){0===n&&h(t)}):void 0})}r.support.volume||(d.add("no-volume"),d.add("no-mute")),d.add("is-touch"),e.sliders&&e.sliders.timeline&&e.sliders.timeline.disableAnimation(),(!r.support.inlineVideo||e.conf.native_fullscreen)&&(e.conf.nativesubtitles=!0);var g=!1;l.on(t,"touchmove",function(){g=!0}),l.on(t,"touchend click",function(t){return g?void(g=!1):e.playing&&!d.contains("is-mouseover")?(d.add("is-mouseover"),d.remove("is-mouseout"),t.preventDefault(),void t.stopPropagation()):void(e.playing||e.splash||!d.contains("is-mouseout")||d.contains("is-mouseover")||setTimeout(function(){e.playing||e.splash||e.resume()},400))}),e.conf.native_fullscreen&&"function"==typeof document.createElement("video").webkitEnterFullScreen&&(e.fullscreen=function(){var e=a.find("video.fp-engine",t)[0];e.webkitEnterFullScreen(),l.one(e,"webkitendfullscreen",function(){a.prop(e,"controls",!0),a.prop(e,"controls",!1)})}),(n||c)&&e.bind("ready",function(){var n=a.find("video.fp-engine",t)[0];l.one(n,"canplay",function(){n.play()}),n.play(),e.bind("progress.dur",function(){var r=n.duration;1!==r&&(e.video.duration=r,a.find(".fp-duration",t)[0].innerHTML=s(r),e.unbind("progress.dur"))})})})},{"../common":1,"../flowplayer":18,"./ui":17,bean:20,"class-list":22}],12:[function(e,t,n){"use strict";var r=e("../flowplayer"),o=e("extend-object"),i=e("bean"),a=e("class-list"),l=e("../common"),s=e("./resolve"),u=new s,c=window.jQuery,f=/^#/;r(function(e,t){function n(){return l.find(v.query,r())}function r(){return f.test(v.query)?void 0:t}function d(){return l.find(v.query+"."+m,r())}function p(){var n=l.find(".fp-playlist",t)[0];if(!n){n=l.createElement("div",{className:"fp-playlist"});var r=l.find(".fp-next,.fp-prev",t);r.length?r[0].parentElement.insertBefore(n,r[0]):l.insertAfter(t,l.find("video",t)[0],n)}n.innerHTML="",e.conf.playlist[0].length&&(e.conf.playlist=e.conf.playlist.map(function(e){if("string"==typeof e){var t=e.split(s.TYPE_RE)[1];return{sources:[{type:"m3u8"===t.toLowerCase()?"application/x-mpegurl":"video/"+t,src:e}]}}return{sources:e.map(function(e){var t={};return Object.keys(e).forEach(function(n){t.type=/mpegurl/i.test(n)?"application/x-mpegurl":"video/"+n,t.src=e[n]}),t})}})),e.conf.playlist.forEach(function(e,t){var r=e.sources[0].src;n.appendChild(l.createElement("a",{href:r,"data-index":t}))})}var v=o({active:"is-active",advance:!0,query:".fp-playlist a"},e.conf),m=v.active,h=a(t);e.play=function(t){if(void 0===t)return e.resume();if("number"==typeof t&&!e.conf.playlist[t])return e;if("number"!=typeof t)return e.load.apply(null,arguments);var n=o({index:t},e.conf.playlist[t]);return t===e.video.index?e.load(n,function(){e.resume()}):(e.off("resume.fromfirst"),e.load(n,function(){e.video.index=t}),e)},e.next=function(t){t&&t.preventDefault();var n=e.video.index;return-1!=n&&(n=n===e.conf.playlist.length-1?0:n+1,e.play(n)),e},e.prev=function(t){t&&t.preventDefault();var n=e.video.index;return-1!=n&&(n=0===n?e.conf.playlist.length-1:n-1,e.play(n)),e},e.setPlaylist=function(t){return e.conf.playlist=t,delete e.video.index,p(),e},e.addPlaylistItem=function(t){return e.setPlaylist(e.conf.playlist.concat([t]))},e.removePlaylistItem=function(t){var n=e.conf.playlist;return e.setPlaylist(n.slice(0,t).concat(n.slice(t+1)))},i.on(t,"click",".fp-next",e.next),i.on(t,"click",".fp-prev",e.prev),v.advance&&e.off("finish.pl").on("finish.pl",function(e,t){if(t.video.loop)return t.seek(0,function(){t.resume()});var n=t.video.index>=0?t.video.index+1:void 0;n1&&t.one("resume.fromfirst",function(){return t.play(0),!1})});var g=!1;e.conf.playlist.length&&(g=!0,p(),e.conf.clip&&e.conf.clip.sources.length||(e.conf.clip=e.conf.playlist[0])),n().length&&!g&&(e.conf.playlist=[],n().forEach(function(t){var n=t.href;t.setAttribute("data-index",e.conf.playlist.length);var r=u.resolve(n,e.conf.clip.sources);c&&o(r,c(t).data()),e.conf.playlist.push(r)})),i.on(f.test(v.query)?document:t,"click",v.query,function(t){t.preventDefault();var n=t.currentTarget,r=Number(n.getAttribute("data-index"));-1!=r&&e.play(r)}),e.on("load",function(n,o,i){if(e.conf.playlist.length){var s=d()[0],u=s&&s.getAttribute("data-index"),c=i.index=i.index||e.video.index||0,f=l.find(v.query+'[data-index="'+c+'"]',r())[0],p=c==e.conf.playlist.length-1;s&&a(s).remove(m),f&&a(f).add(m),h.remove("video"+u),h.add("video"+c),l.toggleClass(t,"last-video",p),i.index=o.video.index=c,i.is_last=o.video.is_last=p}}).on("unload.pl",function(){e.conf.playlist.length&&(d().forEach(function(e){a(e).toggle(m)}),e.conf.playlist.forEach(function(e,t){h.remove("video"+t)}))}),e.conf.playlist.length&&(e.conf.loop=!1)})},{"../common":1,"../flowplayer":18,"./resolve":13,bean:20,"class-list":22,"extend-object":26}],13:[function(e,t,n){"use strict";function r(e){var t=e.attr("src"),n=e.attr("type")||"",r=t.split(i)[1];return n=n.toLowerCase(),a(e.data(),{src:t,suffix:r||n,type:n||r})}function o(e){return/mpegurl/i.test(e)?"application/x-mpegurl":"video/"+e}var i=/\.(\w{3,4})(\?.*)?$/i,a=e("extend-object");t.exports=function(){var e=this;e.sourcesFromVideoTag=function(e,t){var n=[];return t("source",e).each(function(){n.push(r(t(this)))}),!n.length&&e.length&&n.push(r(e)),n},e.resolve=function(e,t){return e?("string"==typeof e&&(e={src:e,sources:[]},e.sources=(t||[]).map(function(t){var n=t.src.split(i)[1];return{type:t.type,src:e.src.replace(i,"."+n+"$2")}})),e instanceof Array&&(e={sources:e.map(function(e){return e.type&&e.src?e:Object.keys(e).reduce(function(t,n){return a(t,{type:o(n),src:e[n]})},{})})}),e):{sources:t}}},t.exports.TYPE_RE=i},{"extend-object":26}],14:[function(e,t,n){"use strict";var r=e("class-list"),o=e("bean"),i=e("../common"),a=function(e,t){var n;return function(){n||(e.apply(this,arguments),n=1,setTimeout(function(){n=0},t))}},l=function(e,t){var n,l,s,u,c,f,d,p,v=(/iPad/.test(navigator.userAgent)&&!/CriOS/.test(navigator.userAgent),i.lastChild(e)),m=r(e),h=r(v),g=!1,y=function(){l=i.offset(e),s=i.width(e),u=i.height(e),f=c?u:s,p=E(d)},b=function(t){n||t==k.value||d&&!(d>t)||(o.fire(e,"slide",[t]),k.value=t)},w=function(e){var n=e.pageX||e.clientX;!n&&e.originalEvent&&e.originalEvent.touches&&e.originalEvent.touches.length&&(n=e.originalEvent.touches[0].pageX);var r=c?e.pageY-l.top:n-l.left;r=Math.max(0,Math.min(p||f,r));var o=r/f;return c&&(o=1-o),t&&(o=1-o),x(o,0,!0)},x=function(e,t){void 0===t&&(t=0),e>1&&(e=1);var n=Math.round(1e3*e)/10+"%";return(!d||d>=e)&&(h.remove("animated"),g?h.remove("animated"):(h.add("animated"),i.css(v,"transition-duration",(t||0)+"ms")),i.css(v,"width",n)),e},E=function(e){return Math.max(0,Math.min(f,c?(1-e)*u:e*s))},k={max:function(e){d=e},disable:function(e){n=e},slide:function(e,t,n){y(),n&&b(e),x(e,t)},disableAnimation:function(t,n){g=t!==!1,i.toggleClass(e,"no-animation",!!n)}};return y(),o.on(e,"mousedown.sld touchstart",function(e){if(e.preventDefault(),!n){var t=a(b,100);y(),k.dragging=!0,m.add("is-dragging"),b(w(e)),o.on(document,"mousemove.sld touchmove.sld",function(e){e.preventDefault(),t(w(e))}),o.one(document,"mouseup touchend",function(){k.dragging=!1,m.remove("is-dragging"),o.off(document,"mousemove.sld touchmove.sld")})}}),k};t.exports=l},{"../common":1,bean:20,"class-list":22}],15:[function(e,t,n){"use strict";var r=e("../flowplayer"),o=e("../common"),i=e("bean"),a=e("class-list");r.defaults.subtitleParser=function(e){function t(e){var t=e.split(":");return 2==t.length&&t.unshift(0),60*t[0]*60+60*t[1]+parseFloat(t[2].replace(",","."))}for(var n,r,o,i=/^(([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3}) --\> (([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3})(.*)/,a=[],l=0,s=e.split("\n"),u=s.length,c={};u>l;l++)if(r=i.exec(s[l])){for(n=s[l-1],o=""+s[++l]+"
";"string"==typeof s[++l]&&s[l].trim()&&l"+s[l]+"
";c={title:n,startTime:t(r[1]),endTime:t(r[3]),text:o},a.push(c)}return a},r(function(e,t){var n,l,s,u,c=a(t),f=function(){u=o.createElement("a",{className:"fp-menu"});var n=o.createElement("ul",{className:"fp-dropdown fp-dropup"});return n.appendChild(o.createElement("li",{"data-subtitle-index":-1},"No subtitles")),(e.video.subtitles||[]).forEach(function(e,t){var r=e.srclang||"en",i=e.label||"Default ("+r+")",a=o.createElement("li",{"data-subtitle-index":t},i);n.appendChild(a)}),u.appendChild(n),o.find(".fp-controls",t)[0].appendChild(u),u};i.on(t,"click",".fp-menu",function(e){a(u).toggle("dropdown-open")}),i.on(t,"click",".fp-menu li[data-subtitle-index]",function(t){var n=t.target.getAttribute("data-subtitle-index");return"-1"===n?e.disableSubtitles():void e.loadSubtitles(n)});var d=function(){var e=o.find(".fp-player",t)[0];s=o.find(".fp-subtitle",t)[0],s=s||o.appendTo(o.createElement("div",{"class":"fp-subtitle"}),e),Array.prototype.forEach.call(s.children,o.removeNode),n=a(s),o.find(".fp-menu",t).forEach(o.removeNode),f()};e.on("ready",function(n,i,a){var l=i.conf;if(r.support.subtitles&&l.nativesubtitles&&"html5"==i.engine.engineName){var s=function(e){var n=o.find("video",t)[0].textTracks;n.length&&(n[0].mode=e)};if(!a.subtitles||!a.subtitles.length)return;var u=o.find("video.fp-engine",t)[0];return a.subtitles.forEach(function(e){u.appendChild(o.createElement("track",{kind:"subtitles",srclang:e.srclang||"en",label:e.label||"en",src:e.src,"default":e["default"]}))}),s("disabled"),void s("showing")}if(i.subtitles=[],d(),c.remove("has-menu"),e.disableSubtitles(),a.subtitles&&a.subtitles.length){c.add("has-menu");var f=a.subtitles.filter(function(e){return e["default"]})[0];f&&i.loadSubtitles(a.subtitles.indexOf(f))}}),e.bind("cuepoint",function(e,t,r){r.subtitle?(l=r.index,o.html(s,r.subtitle.text),n.add("fp-active")):r.subtitleEnd&&(n.remove("fp-active"),l=r.index)}),e.bind("seek",function(t,r,o){l&&e.cuepoints[l]&&e.cuepoints[l].time>o&&(n.remove("fp-active"),l=null),(e.cuepoints||[]).forEach(function(t){var n=t.subtitle;n&&l!=t.index?o>=t.time&&(!n.endTime||o<=n.endTime)&&e.trigger("cuepoint",[e,t]):t.subtitleEnd&&o>=t.time&&t.index==l+1&&e.trigger("cuepoint",[e,t])})});var p=function(e){o.toggleClass(o.find("li.active",t)[0],"active"),o.toggleClass(o.find('li[data-subtitle-index="'+e+'"]',t)[0],"active")};e.disableSubtitles=function(){return e.subtitles=[],(e.cuepoints||[]).forEach(function(t){(t.subtitle||t.subtitleEnd)&&e.removeCuepoint(t)}),s&&Array.prototype.forEach.call(s.children,o.removeNode),p(-1),e},e.loadSubtitles=function(t){e.disableSubtitles();var n=e.video.subtitles[t],r=n.src;return r?(p(t),o.xhrGet(r,function(t){var n=e.conf.subtitleParser(t);n.forEach(function(t){var n={time:t.startTime,subtitle:t,visible:!1};e.subtitles.push(t),e.addCuepoint(n),e.addCuepoint({time:t.endTime,subtitleEnd:t.title,visible:!1}),0!==t.startTime||e.video.time||e.trigger("cuepoint",[e,n])})},function(){return e.trigger("error",{code:8,url:r}),!1}),e):void 0}})},{"../common":1,"../flowplayer":18,bean:20,"class-list":22}],16:[function(e,t,n){"use strict";var r=e("../flowplayer"),o=e("extend-object");!function(){var e=function(e){var t=/Version\/(\d\.\d)/.exec(e);return t&&t.length>1?parseFloat(t[1],10):0},t=function(){var e=document.createElement("video");return e.loop=!0,e.autoplay=!0,e.preload=!0,e},n={},i=navigator.userAgent.toLowerCase(),a=/(chrome)[ \/]([\w.]+)/.exec(i)||/(safari)[ \/]([\w.]+)/.exec(i)||/(webkit)[ \/]([\w.]+)/.exec(i)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(i)||/(msie) ([\w.]+)/.exec(i)||i.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(i)||[];a[1]&&(n[a[1]]=!0,n.version=a[2]||"0");var l=t(),s=navigator.userAgent,u=n.msie||/Trident\/7/.test(s),c=/iPad|MeeGo/.test(s)&&!/CriOS/.test(s),f=/iPad/.test(s)&&/CriOS/.test(s),d=/iP(hone|od)/i.test(s)&&!/iPad/.test(s)&&!/IEMobile/i.test(s),p=/Android/.test(s)&&!/Firefox/.test(s),v=/Android/.test(s)&&/Firefox/.test(s),m=/Silk/.test(s),h=/IEMobile/.test(s),g=h?parseFloat(/Windows\ Phone\ (\d+\.\d+)/.exec(s)[1],10):0,y=h?parseFloat(/IEMobile\/(\d+\.\d+)/.exec(s)[1],10):0,b=(c?e(s):0,p?parseFloat(/Android\ (\d\.\d)/.exec(s)[1],10):0),w=o(r.support,{browser:n,subtitles:!!l.addTextTrack,fullscreen:"function"==typeof document.webkitCancelFullScreen&&!/Mac OS X 10_5.+Version\/5\.0\.\d Safari/.test(s)||document.mozFullScreenEnabled||"function"==typeof document.exitFullscreen||"function"==typeof document.msExitFullscreen,inlineBlock:!(u&&n.version<8),touch:"ontouchstart"in window,dataload:!c&&!d&&!h,zeropreload:!u&&!p,volume:!(c||p||d||m||f),cachedVideoTag:!(c||d||f||h),firstframe:!(d||c||p||m||f||h||v),inlineVideo:!d&&(!h||g>=8.1&&y>=11)&&(!p||b>=3),hlsDuration:!p&&(!n.safari||c||d||f),seekable:!c&&!f});try{var x=navigator.plugins["Shockwave Flash"],E=u?new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version"):x.description;u||x[0].enabledPlugin?(E=E.split(/\D+/),E.length&&!E[0]&&(E=E.slice(1)),w.flashVideo=E[0]>9||9==E[0]&&E[3]>=115):w.flashVideo=!1}catch(k){}try{w.video=!!l.canPlayType,w.video&&l.canPlayType("video/mp4")}catch(T){w.video=!1}w.animation=function(){for(var e=["","Webkit","Moz","O","ms","Khtml"],t=document.createElement("p"),n=0;n=10?e:"0"+e}function o(e){e=e||0;var t=Math.floor(e/3600),n=Math.floor(e/60);return e-=60*n,t>=1?(n-=60*t,t+":"+r(n)+":"+r(e)):r(n)+":"+r(e)}var i=e("../flowplayer"),a=e("../common"),l=e("class-list"),s=e("bean"),u=e("./slider");i(function(e,t){function n(e){return a.find(".fp-"+e,t)[0]}function r(e){a.css(w,"padding-top",100*e+"%"),p.inlineBlock||a.height(a.find("object",t)[0],a.height(t))}function c(e){e?(v.add("is-mouseover"),v.remove("is-mouseout")):(v.add("is-mouseout"),v.remove("is-mouseover"))}var f,d=e.conf,p=i.support,v=l(t);a.find(".fp-ratio,.fp-ui",t).forEach(a.removeNode),v.add("flowplayer"),t.appendChild(a.createElement("div",{className:"fp-ratio"}));var m=a.createElement("div",{className:"fp-ui"},'
00:00 00:00
'.replace(/class="/g,'class="fp-'));t.appendChild(m);var h=(n("progress"),n("buffer")),g=n("elapsed"),y=n("remaining"),b=n("waiting"),w=n("ratio"),x=n("speed"),E=l(x),k=n("duration"),T=n("controls"),S=n("timeline-tooltip"),C=a.css(w,"padding-top"),N=n("timeline"),O=u(N,e.rtl),j=(n("volume"),n("fullscreen")),P=n("volumeslider"),A=u(P,e.rtl),_=v.contains("fixed-controls")||v.contains("no-toggle");O.disableAnimation(v.contains("is-touch")),e.sliders=e.sliders||{},e.sliders.timeline=O,e.sliders.volume=A,p.animation||a.html(b,"loading …
"),d.ratio&&r(d.ratio);try{d.fullscreen||a.removeNode(j)}catch(D){a.removeNode(j)}e.on("ready",function(e,n,i){var l=n.video.duration;O.disable(n.disabled||!l),d.adaptiveRatio&&!isNaN(i.height/i.width)&&r(i.height/i.width,!0),a.html([k,y],o(l)),a.toggleClass(t,"is-long",l>=3600),A.slide(n.volumeLevel),"flash"===n.engine.engineName?O.disableAnimation(!0,!0):O.disableAnimation(!1),a.find(".fp-title",m).forEach(a.removeNode),i.title&&a.prepend(m,a.createElement("div",{className:"fp-title"},i.title))}).on("unload",function(){C||a.css(w,"paddingTop",""),O.slide(0)}).on("buffer",function(){var t=e.video,n=t.buffer/t.duration;!t.seekable&&p.seekable&&O.max(n),1>n?a.css(h,"width",100*n+"%"):a.css(h,"width","100%")}).on("speed",function(e,t,n){a.text(x,n+"x"),E.add("fp-hilite"),setTimeout(function(){E.remove("fp-hilite")},1e3)}).on("buffered",function(){a.css(h,"width","100%"),O.max(1)}).on("progress",function(){var t=e.video.time,n=e.video.duration;O.dragging||O.slide(t/n,e.seeking?0:250),a.html(g,o(t)),a.html(y,"-"+o(n-t))}).on("finish resume seek",function(e){a.toggleClass(t,"is-finished","finish"==e.type)}).on("stop",function(){a.html(g,o(0)),O.slide(0,100)}).on("finish",function(){a.html(g,o(e.video.duration)),O.slide(1,100),v.remove("is-seeking")}).on("beforeseek",function(){}).on("volume",function(){A.slide(e.volumeLevel)}).on("disable",function(){var n=e.disabled;O.disable(n),A.disable(n),a.toggleClass(t,"is-disabled",e.disabled)}).on("mute",function(e,n,r){a.toggleClass(t,"is-muted",r)}).on("error",function(e,n,r){if(a.removeClass(t,"is-loading"),a.addClass(t,"is-error"),r){r.message=d.errors[r.code],n.error=!0;var o=a.find(".fp-message",t)[0],i=r.video||n.video;a.find("h2",o)[0].innerHTML=(n.engine&&n.engine.engineName||"html5")+": "+r.message,a.find("p",o)[0].innerHTML=r.url||i.url||i.src||d.errorUrls[r.code],n.off("mouseenter click"),v.remove("is-mouseover")}}),s.on(t,"mouseenter mouseleave",function(n){if(!_){var r,o="mouseover"==n.type;if(c(o),o){var i=function(){c(!0),r=new Date};e.on("pause.x volume.x",i),s.on(t,"mousemove.x",i),f=setInterval(function(){new Date-r>d.mouseoutTimeout&&(c(!1),r=new Date)},100)}else s.off(t,"mousemove.x"),e.off("pause.x volume.x"),clearInterval(f)}}),s.on(t,"mouseleave",function(){(O.dragging||A.dragging)&&(v.add("is-mouseover"),v.remove("is-mouseout"))}),s.on(t,"click.player",function(t){if(!e.disabled){var n=l(t.target);return n.contains("fp-ui")||n.contains("fp-engine")||t.flash?(t.preventDefault&&t.preventDefault(),e.toggle()):void 0}}),s.on(t,"mousemove",".fp-timeline",function(t){var n=t.pageX||t.clientX,r=n-a.offset(N).left,i=r/a.width(N),l=i*e.video.duration;0>i||(a.html(S,o(l)),a.css(S,"left",n-a.offset(T).left-a.width(S)/2+"px"))}),s.on(t,"contextmenu",function(e){var n=a.offset(a.find(".fp-player",t)[0]),r=window,o=e.clientX-n.left,i=e.clientY-(n.top+r.scrollY),l=a.find(".fp-context-menu",t)[0];l&&(e.preventDefault(),a.css(l,{left:o+"px",top:i+"px",display:"block"}),s.on(t,"click",".fp-context-menu",function(e){e.stopPropagation()}),s.on(document,"click.outsidemenu",function(e){a.css(l,"display","none"),s.off(document,"click.outsidemenu")}))}),e.on("flashdisabled",function(){v.add("is-flash-disabled"),e.one("ready",function(){v.remove("is-flash-disabled"),a.find(".fp-flash-disabled",t).forEach(a.removeNode)}),t.appendChild(a.createElement("div",{className:"fp-flash-disabled"},"Adobe Flash is disabled for this page, click player area to enable"))}),d.poster&&a.css(t,"background-image","url("+d.poster+")");var I=a.css(t,"background-color"),M="none"!=a.css(t,"background-image")||I&&"rgba(0, 0, 0, 0)"!=I&&"transparent"!=I;!M||d.splash||d.autoplay||e.on("ready stop",function(){v.add("is-poster"),e.one("progress",function(){v.remove("is-poster")})}),"string"==typeof d.splash&&a.css(t,"background-image","url('"+d.splash+"')"),!M&&e.forcedSplash&&a.css(t,"background-color","#555"),s.on(t,"click",".fp-toggle, .fp-play",function(){e.disabled||e.toggle()}),s.on(t,"click",".fp-mute",function(){e.mute()}),s.on(t,"click",".fp-fullscreen",function(){e.fullscreen()}),s.on(t,"click",".fp-unload",function(){e.unload()}),s.on(N,"slide",function(t){e.seeking=!0,e.seek(t*e.video.duration)}),s.on(P,"slide",function(t){e.volume(t)});var L=n("time");s.on(t,"click",".fp-time",function(){l(L).toggle("is-inverted")}),c(_),e.on("shutdown",function(){s.off(N),s.off(P)})}),t.exports.format=o},{"../common":1,"../flowplayer":18,"./slider":14,bean:20,"class-list":22}],18:[function(e,t,n){"use strict";function r(e,t,n){t&&t.embed&&(t.embed=o({},y.defaults.embed,t.embed));var r,d,v=e,m=a(v),h=o({},y.defaults,y.conf,t),g={},x=new w;m.add("is-loading");try{g=p?window.localStorage:g}catch(E){}var k=v.currentStyle&&"rtl"===v.currentStyle.direction||window.getComputedStyle&&null!==window.getComputedStyle(v,null)&&"rtl"===window.getComputedStyle(v,null).getPropertyValue("direction");k&&m.add("is-rtl");var T={conf:h,currentSpeed:1,volumeLevel:h.muted?0:"undefined"==typeof h.volume?1*g.volume:h.volume,video:{},disabled:!1,finished:!1,loading:!1,muted:"true"==g.muted||h.muted,paused:!1,playing:!1,ready:!1,splash:!1,rtl:k,load:function(e,t){if(!T.error&&!T.loading){T.video={},T.finished=!1,e=e||h.clip,e=o({},x.resolve(e,h.clip.sources)),(T.playing||T.engine)&&(e.autoplay=!0);var n=S(e);if(!n)return T.trigger("error",[T,{code:y.support.flashVideo?5:10}]);if(!n.engineName)throw new Error("engineName property of factory should be exposed");if(T.engine&&n.engineName===T.engine.engineName||(T.ready=!1,T.engine&&(T.engine.unload(),T.conf.autoplay=!0),d=T.engine=n(T,v),T.one("ready",function(){d.volume(T.volumeLevel)})),o(e,d.pick(e.sources.filter(function(e){return e.engine?e.engine===d.engineName:!0}))),e.src){e.src=s.createElement("a",{href:e.src}).href;var r=T.trigger("load",[T,e,d],!0);r.defaultPrevented?T.loading=!1:(d.load(e),i(e)&&(t=e),t&&T.one("ready",t))}return T}},pause:function(e){return!T.ready||T.seeking||T.loading||(d.pause(),T.one("pause",e)),T},resume:function(){return T.ready&&T.paused&&(d.resume(),T.finished&&(T.trigger("resume",[T]),T.finished=!1)),T},toggle:function(){return T.ready?T.paused?T.resume():T.pause():T.load()},seek:function(e,t){if(T.ready&&!T.live){if("boolean"==typeof e){var n=.1*T.video.duration;e=T.video.time+(e?n:-n)}e=r=Math.min(Math.max(e,0),T.video.duration).toFixed(1);var o=T.trigger("beforeseek",[T,e],!0);o.defaultPrevented?(T.seeking=!1,s.toggleClass(v,"is-seeking",T.seeking)):(d.seek(e),i(t)&&T.one("seek",t))}return T},seekTo:function(e,t){var n=void 0===e?r:.1*T.video.duration*e;return T.seek(n,t)},mute:function(e,t){return void 0===e&&(e=!T.muted),t||(g.muted=T.muted=e,g.volume=isNaN(g.volume)?h.volume:g.volume),T.volume(e?0:g.volume,!0),T.trigger("mute",[T,e]),T},volume:function(e,t){return T.ready&&(e=Math.min(Math.max(e,0),1),t||(g.volume=e),d.volume(e)),T},speed:function(e,t){return T.ready&&("boolean"==typeof e&&(e=h.speeds[h.speeds.indexOf(T.currentSpeed)+(e?1:-1)]||T.currentSpeed),d.speed(e),t&&v.one("speed",t)),T},stop:function(){return T.ready&&(T.pause(),T.seek(0,function(){T.trigger("stop")})),T},unload:function(){return m.contains("is-embedding")||(h.splash?(T.trigger("unload",[T]),d&&d.unload()):T.stop()),T},shutdown:function(){T.unload(),T.trigger("shutdown",[T]),l.off(v),delete c[v.getAttribute("data-flowplayer-instance-id")]},disable:function(e){return void 0===e&&(e=!T.disabled),e!=T.disabled&&(T.disabled=e,T.trigger("disable",e)),T}};T.conf=o(T.conf,h),u(T);var S=function(e){var t,n=y.engines;if(h.engine){var r=n.filter(function(e){return e.engineName===h.engine})[0];if(r&&e.sources.some(function(e){return e.engine&&e.engine!==r.engineName?!1:r.canPlay(e.type,T.conf)}))return r}return h.enginePreference&&(n=y.engines.filter(function(e){return h.enginePreference.indexOf(e.engineName)>-1}).sort(function(e,t){return h.enginePreference.indexOf(e.engineName)-h.enginePreference.indexOf(t.engineName)})),e.sources.some(function(e){var r=n.filter(function(t){return e.engine&&e.engine!==t.engineName?!1:t.canPlay(e.type,T.conf)}).shift();return r&&(t=r),!!r}),t};return v.getAttribute("data-flowplayer-instance-id")||(v.setAttribute("data-flowplayer-instance-id",b++),T.on("boot",function(){(h.splash||m.contains("is-splash")||!y.support.firstframe)&&(T.forcedSplash=!h.splash&&!m.contains("is-splash"),T.splash=h.autoplay=!0,h.splash||(h.splash=!0),m.add("is-splash")),h.splash&&s.find("video",v).forEach(s.removeNode),(h.live||m.contains("is-live"))&&(T.live=h.live=!0,m.add("is-live")),f.forEach(function(e){e(T,v)}),c.push(T),h.splash?T.unload():T.load(),h.disabled&&T.disable(),T.one("ready",n)}).on("load",function(e,t,n){h.splash&&s.find(".flowplayer.is-ready,.flowplayer.is-loading").forEach(function(e){var t=e.getAttribute("data-flowplayer-instance-id");if(t!==v.getAttribute("data-flowplayer-instance-id")){var n=c[Number(t)];n&&n.conf.splash&&n.unload()}}),m.add("is-loading"),t.loading=!0,"undefined"!=typeof n.live&&(s.toggleClass(v,"is-live",n.live),t.live=n.live)}).on("ready",function(e,t,n){n.time=0,t.video=n,m.remove("is-loading"),t.loading=!1,t.muted?t.mute(!0,!0):t.volume(t.volumeLevel);var r=t.conf.hlsFix&&/mpegurl/i.exec(n.type);s.toggleClass(v,"hls-fix",!!r)}).on("unload",function(e){m.remove("is-loading"),T.loading=!1}).on("ready unload",function(e){var t="ready"==e.type;s.toggleClass(v,"is-splash",!t),s.toggleClass(v,"is-ready",t),T.ready=t,T.splash=!t}).on("progress",function(e,t,n){t.video.time=n}).on("speed",function(e,t,n){t.currentSpeed=n}).on("volume",function(e,t,n){t.volumeLevel=Math.round(100*n)/100,t.muted?n&&t.mute(!1):g.volume=n}).on("beforeseek seek",function(e){T.seeking="beforeseek"==e.type,s.toggleClass(v,"is-seeking",T.seeking)}).on("ready pause resume unload finish stop",function(e,t,n){T.paused=/pause|finish|unload|stop/.test(e.type),T.paused=T.paused||"ready"===e.type&&!h.autoplay&&!T.playing,T.playing=!T.paused,s.toggleClass(v,"is-paused",T.paused),s.toggleClass(v,"is-playing",T.playing),T.load.ed||T.pause()}).on("finish",function(e){T.finished=!0}).on("error",function(){})),T.trigger("boot",[T,v]),T}var o=e("extend-object"),i=e("is-function"),a=e("class-list"),l=e("bean"),s=e("./common"),u=e("./ext/events"),c=[],f=[],d=(window.navigator.userAgent,window.onbeforeunload);window.onbeforeunload=function(e){return c.forEach(function(e){e.conf.splash?e.unload():e.bind("error",function(){s.find(".flowplayer.is-error .fp-message").forEach(s.removeNode)})}),d?d(e):void 0};var p=!1;try{"object"==typeof window.localStorage&&(window.localStorage.flowplayerTestStorage="test",p=!0)}catch(v){}var m=/Safari/.exec(navigator.userAgent)&&!/Chrome/.exec(navigator.userAgent),h=/(\d+\.\d+) Safari/.exec(navigator.userAgent),g=h?Number(h[1]):100,y=t.exports=function(e,t,n){if(i(e))return f.push(e);if("number"==typeof e||"undefined"==typeof e)return c[e||0];if(e.nodeType){if(null!==e.getAttribute("data-flowplayer-instance-id"))return c[e.getAttribute("data-flowplayer-instance-id")];if(!t)return;return r(e,t,n)}if(e.jquery)return y(e[0],t,n);if("string"==typeof e){var o=s.find(e)[0];return o&&y(o,t,n)}};o(y,{version:"6.0.3",engines:[],conf:{},set:function(e,t){"string"==typeof e?y.conf[e]=t:o(y.conf,e)},support:{},defaults:{debug:p?!!localStorage.flowplayerDebug:!1,disabled:!1,fullscreen:window==window.top,keyboard:!0,ratio:9/16,adaptiveRatio:!1,rtmp:0,proxy:"best",splash:!1,live:!1,swf:"//releases.flowplayer.org/6.0.3/flowplayer.swf",swfHls:"//releases.flowplayer.org/6.0.3/flowplayerhls.swf",speeds:[.25,.5,1,1.5,2],tooltip:!0,mouseoutTimeout:5e3,volume:p?"true"==localStorage.muted?0:isNaN(localStorage.volume)?1:localStorage.volume||1:1,errors:["","Video loading aborted","Network error","Video not properly encoded","Video file not found","Unsupported video","Skin not found","SWF file not found","Subtitles not found","Invalid RTMP URL","Unsupported video format. Try installing Adobe Flash."],errorUrls:["","","","","","","","","","","http://get.adobe.com/flashplayer/"],playlist:[],hlsFix:m&&8>g},bean:l,common:s,extend:o});var b=0,w=e("./ext/resolve");if("undefined"!=typeof window.jQuery){var x=window.jQuery;x(function(){"function"==typeof x.fn.flowplayer&&x('.flowplayer:has(video,script[type="application/json"])').flowplayer()});var E=function(e){if(!e.length)return{};var t=e.data()||{},n={};return x.each(["autoplay","loop","preload","poster"],function(r,o){var i=e.attr(o);void 0!==i&&-1!==["autoplay","poster"].indexOf(o)?n[o]=i?i:!0:void 0!==i&&(t[o]=i?i:!0)}),t.subtitles=e.find("track").map(function(){var e=x(this);return{src:e.attr("src"),kind:e.attr("kind"),label:e.attr("label"),srclang:e.attr("srclang"),"default":e.prop("default")}}).get(),t.sources=(new w).sourcesFromVideoTag(e,x),o(n,{clip:t})};x.fn.flowplayer=function(e,t){return this.each(function(){"string"==typeof e&&(e={swf:e}),i(e)&&(t=e,e={});var n=x(this),o=n.find('script[type="application/json"]'),a=o.length?JSON.parse(o.text()):E(n.find("video")),l=x.extend({},e||{},a,n.data()),s=r(this,l,t);u.EVENTS.forEach(function(e){s.on(e+".jquery",function(e){n.trigger.call(n,e.type,e.detail&&e.detail.args)})}),n.data("flowplayer",s)})}}},{"./common":1,"./ext/events":8,"./ext/resolve":13,bean:20,"class-list":22,"extend-object":26,"is-function":27}],19:[function(e,t,n){e("es5-shim");var r=t.exports=e("./flowplayer");e("./ext/support"),e("./engine/embed"),e("./engine/html5"),e("./engine/flash"),e("./ext/ui"),e("./ext/keyboard"),e("./ext/playlist"),e("./ext/cuepoint"),e("./ext/subtitle"),e("./ext/analytics"),e("./ext/embed"),e("./ext/fullscreen"),e("./ext/mobile"),r(function(e,t){function n(e){var t=document.createElement("a");return t.href=e,l.hostname(t.hostname)}var o=function(e,t){var n=e.className.split(" ");-1===n.indexOf(t)&&(e.className+=" "+t)},i=function(e){return"none"!==window.getComputedStyle(e).display},a=e.conf,l=r.common,s=l.createElement,u=a.swf.indexOf("flowplayer.org")&&a.e&&t.getAttribute("data-origin"),c=u?n(u):l.hostname(),f=(document,a.key);"file:"==location.protocol&&(c="localhost"),e.load.ed=1,a.hostname=c,a.origin=u||location.href,u&&o(t,"is-embedded"),"string"==typeof f&&(f=f.split(/,\s*/));var d=function(e,n){var r=s("a",{href:n,className:"fp-brand"});r.innerHTML=e,l.find(".fp-controls",t)[0].appendChild(r)};if(f&&"function"==typeof key_check&&key_check(f,c)){if(a.logo){var p=s("a",{href:u,className:"fp-logo"});a.embed&&a.embed.popup&&(p.target="_blank");var v=s("img",{src:a.logo});p.appendChild(v),t.appendChild(p)}a.brand&&u||a.brand&&a.brand.showOnOrigin?d(a.brand.text||a.brand,u||location.href):l.addClass(t,"no-brand")}else{d("flowplayer","http://flowplayer.org");var p=s("a",{href:"http://flowplayer.org"});t.appendChild(p);var m=s("div",{className:"fp-context-menu"},''),h=window.location.href.indexOf("localhost"),g=l.find(".fp-player",t)[0];7!==h&&(g||t).appendChild(m),e.on("pause resume finish unload ready",function(e,n){l.removeClass(t,"no-brand");var r=-1;if(n.video.src)for(var o=[["org","flowplayer","drive"],["org","flowplayer","my"]],a=0;ao;o++)if(d[o].reg.test(u)){p[u]=s=d[o].fix;break}for(l=s(e,this,u),o=l.length;o--;)!((a=l[o])in this)&&a in e&&(this[a]=e[a])}}};return v.prototype.preventDefault=function(){this.originalEvent.preventDefault?this.originalEvent.preventDefault():this.originalEvent.returnValue=!1},v.prototype.stopPropagation=function(){this.originalEvent.stopPropagation?this.originalEvent.stopPropagation():this.originalEvent.cancelBubble=!0},v.prototype.stop=function(){this.preventDefault(),this.stopPropagation(),this.stopped=!0},v.prototype.stopImmediatePropagation=function(){this.originalEvent.stopImmediatePropagation&&this.originalEvent.stopImmediatePropagation(),this.isImmediatePropagationStopped=function(){return!0}},v.prototype.isImmediatePropagationStopped=function(){return this.originalEvent.isImmediatePropagationStopped&&this.originalEvent.isImmediatePropagationStopped()},v.prototype.clone=function(e){var t=new v(this,this.element,this.isNative);return t.currentTarget=e,t},v}(),k=function(e,t){return f||t||e!==u&&e!==r?e:c},T=function(){var e=function(e,t,n,r){var o=function(n,o){return t.apply(e,r?v.call(o,n?0:1).concat(r):o)},i=function(n,r){return t.__beanDel?t.__beanDel.ft(n.target,e):r},a=n?function(e){var t=i(e,this);return n.apply(t,arguments)?(e&&(e.currentTarget=t),o(e,arguments)):void 0}:function(e){return t.__beanDel&&(e=e.clone(i(e))),o(e,arguments)};return a.__beanDel=t.__beanDel,a},t=function(t,n,r,o,i,a,l){var s,u=x[n];"unload"==n&&(r=j(P,t,n,r,o)),u&&(u.condition&&(r=e(t,r,u.condition,a)),n=u.base||n),this.isNative=s=w[n]&&!!t[d],this.customType=!f&&!s&&n,this.element=t,this.type=n,this.original=o,this.namespaces=i,this.eventType=f||s?n:"propertychange",this.target=k(t,s),this[d]=!!this.target[d],this.root=l,this.handler=e(t,r,null,a)};return t.prototype.inNamespaces=function(e){var t,n,r=0;if(!e)return!0;if(!this.namespaces)return!1;for(t=e.length;t--;)for(n=this.namespaces.length;n--;)e[t]==this.namespaces[n]&&r++;return e.length===r},t.prototype.matches=function(e,t,n){return!(this.element!==e||t&&this.original!==t||n&&this.handler!==n)},t}(),S=function(){var e={},t=function(n,r,o,i,a,l){var s=a?"r":"$";if(r&&"*"!=r){var u,c=0,f=e[s+r],d="*"==n;if(!f)return;for(u=f.length;u>c;c++)if((d||f[c].matches(n,o,i))&&!l(f[c],f,c,r))return}else for(var p in e)p.charAt(0)==s&&t(n,p.substr(1),o,i,a,l)},n=function(t,n,r,o){var i,a=e[(o?"r":"$")+n];if(a)for(i=a.length;i--;)if(!a[i].root&&a[i].matches(t,r,null))return!0;return!1},r=function(e,n,r,o){var i=[];return t(e,n,r,null,o,function(e){return i.push(e)}),i},o=function(t){var n=!t.root&&!this.has(t.element,t.type,null,!1),r=(t.root?"r":"$")+t.type;return(e[r]||(e[r]=[])).push(t),n},i=function(n){t(n.element,n.type,null,n.handler,n.root,function(t,n,r){return n.splice(r,1),t.removed=!0,0===n.length&&delete e[(t.root?"r":"$")+t.type],!1})},a=function(){var t,n=[];for(t in e)"$"==t.charAt(0)&&(n=n.concat(e[t]));return n};return{has:n,get:r,put:o,del:i,entries:a}}(),C=function(e){n=arguments.length?e:u.querySelectorAll?function(e,t){return t.querySelectorAll(e)}:function(){throw new Error("Bean: No selector engine installed")}},N=function(e,t){if(f||!t||!e||e.propertyName=="_on"+t){var n=S.get(this,t||e.type,null,!1),r=n.length,o=0;for(e=new E(e,this,!0),t&&(e.type=t);r>o&&!e.isImmediatePropagationStopped();o++)n[o].removed||n[o].handler.call(this,e)}},O=f?function(e,t,n){e[n?l:s](t,N,!1)}:function(e,t,n,r){var o;n?(S.put(o=new T(e,r||t,function(t){N.call(e,t,r)},N,null,null,!0)),r&&null==e["_on"+r]&&(e["_on"+r]=0),o.target.attachEvent("on"+o.eventType,o.handler)):(o=S.get(e,r||t,N,!0)[0],o&&(o.target.detachEvent("on"+o.eventType,o.handler),S.del(o)))},j=function(e,t,n,r,o){return function(){r.apply(this,arguments),e(t,n,o)}},P=function(e,t,n,r){var o,i,l=t&&t.replace(a,""),s=S.get(e,l,null,!1),u={};for(o=0,i=s.length;i>o;o++)n&&s[o].original!==n||!s[o].inNamespaces(r)||(S.del(s[o]),!u[s[o].eventType]&&s[o][d]&&(u[s[o].eventType]={t:s[o].eventType,c:s[o].type}));for(o in u)S.has(e,u[o].t,null,!1)||O(e,u[o].t,!1,u[o].c)},A=function(e,t){var r=function(t,r){for(var o,i=h(e)?n(e,r):e;t&&t!==r;t=t.parentNode)for(o=i.length;o--;)if(i[o]===t)return t},o=function(e){var n=r(e.target,this);n&&t.apply(n,arguments)};return o.__beanDel={ft:r,selector:e},o},_=f?function(e,t,n){var o=u.createEvent(e?"HTMLEvents":"UIEvents");o[e?"initEvent":"initUIEvent"](t,!0,!0,r,1),n.dispatchEvent(o)}:function(e,t,n){n=k(n,e),e?n.fireEvent("on"+t,u.createEventObject()):n["_on"+t]++},D=function(e,t,n){var r,o,l,s,u=h(t);if(u&&t.indexOf(" ")>0){for(t=m(t),s=t.length;s--;)D(e,t[s],n);return e}if(o=u&&t.replace(a,""),o&&x[o]&&(o=x[o].base),!t||u)(l=u&&t.replace(i,""))&&(l=m(l,".")),P(e,o,n,l);else if(g(t))P(e,null,t);else for(r in t)t.hasOwnProperty(r)&&D(e,r,t[r]);return e},I=function(e,t,r,o){var l,s,u,c,f,h,y;{if(void 0!==r||"object"!=typeof t){for(g(r)?(f=v.call(arguments,3),o=l=r):(l=o,f=v.call(arguments,4),o=A(r,l,n)),u=m(t),this===p&&(o=j(D,e,t,o,l)),c=u.length;c--;)y=S.put(h=new T(e,u[c].replace(a,""),o,l,m(u[c].replace(i,""),"."),f,!1)),h[d]&&y&&O(e,h.eventType,!0,h.customType);return e}for(s in t)t.hasOwnProperty(s)&&I.call(this,e,s,t[s])}},M=function(e,t,n,r){return I.apply(null,h(n)?[e,n,t,r].concat(arguments.length>3?v.call(arguments,5):[]):v.call(arguments))},L=function(){return I.apply(p,arguments)},F=function(e,t,n){var r,o,l,s,u,c=m(t);for(r=c.length;r--;)if(t=c[r].replace(a,""),(s=c[r].replace(i,""))&&(s=m(s,".")),s||n||!e[d])for(u=S.get(e,t,null,!1),n=[!1].concat(n),o=0,l=u.length;l>o;o++)u[o].inNamespaces(s)&&u[o].handler.apply(e,n);else _(w[t],t,e);return e},$=function(e,t,n){for(var r,o,i=S.get(t,n,null,!1),a=i.length,l=0;a>l;l++)i[l].original&&(r=[e,i[l].type],(o=i[l].handler.__beanDel)&&r.push(o.selector),r.push(i[l].original),I.apply(null,r));return e},R={on:I,add:M,one:L,off:D,remove:D,clone:$,fire:F,Event:E,setSelectorEngine:C,noConflict:function(){return t[e]=o,this}};if(r.attachEvent){var V=function(){var e,t=S.entries();for(e in t)t[e].type&&"unload"!==t[e].type&&D(t[e].element,t[e].type);r.detachEvent("onunload",V),r.CollectGarbage&&r.CollectGarbage()};r.attachEvent("onunload",V)}return C(),R})},{}],21:[function(t,n,r){(function(t){!function(o){function i(e){throw RangeError(I[e])}function a(e,t){for(var n=e.length;n--;)e[n]=t(e[n]);return e}function l(e,t){return a(e.split(D),t).join(".")}function s(e){for(var t,n,r=[],o=0,i=e.length;i>o;)t=e.charCodeAt(o++),t>=55296&&56319>=t&&i>o?(n=e.charCodeAt(o++),56320==(64512&n)?r.push(((1023&t)<<10)+(1023&n)+65536):(r.push(t),o--)):r.push(t);return r}function u(e){return a(e,function(e){var t="";return e>65535&&(e-=65536,t+=F(e>>>10&1023|55296),e=56320|1023&e),t+=F(e)}).join("")}function c(e){return 10>e-48?e-22:26>e-65?e-65:26>e-97?e-97:k}function f(e,t){return e+22+75*(26>e)-((0!=t)<<5)}function d(e,t,n){var r=0;for(e=n?L(e/N):e>>1,e+=L(e/t);e>M*S>>1;r+=k)e=L(e/M);return L(r+(M+1)*e/(e+C))}function p(e){var t,n,r,o,a,l,s,f,p,v,m=[],h=e.length,g=0,y=j,b=O;for(n=e.lastIndexOf(P),0>n&&(n=0),r=0;n>r;++r)e.charCodeAt(r)>=128&&i("not-basic"),m.push(e.charCodeAt(r));for(o=n>0?n+1:0;h>o;){for(a=g,l=1,s=k;o>=h&&i("invalid-input"),f=c(e.charCodeAt(o++)),(f>=k||f>L((E-g)/l))&&i("overflow"),g+=f*l,p=b>=s?T:s>=b+S?S:s-b,!(p>f);s+=k)v=k-p,l>L(E/v)&&i("overflow"),l*=v;t=m.length+1,b=d(g-a,t,0==a),L(g/t)>E-y&&i("overflow"),y+=L(g/t),g%=t,m.splice(g++,0,y)}return u(m)}function v(e){var t,n,r,o,a,l,u,c,p,v,m,h,g,y,b,w=[];for(e=s(e),h=e.length,t=j,n=0,a=O,l=0;h>l;++l)m=e[l],128>m&&w.push(F(m));for(r=o=w.length,o&&w.push(P);h>r;){for(u=E,l=0;h>l;++l)m=e[l],m>=t&&u>m&&(u=m);for(g=r+1,u-t>L((E-n)/g)&&i("overflow"),n+=(u-t)*g,t=u,l=0;h>l;++l)if(m=e[l],t>m&&++n>E&&i("overflow"),m==t){for(c=n,p=k;v=a>=p?T:p>=a+S?S:p-a,!(v>c);p+=k)b=c-v,y=k-v,w.push(F(f(v+b%y,0))),c=L(b/y);w.push(F(f(c,0))),a=d(n,g,r==o),n=0,++r}++n,++t}return w.join("")}function m(e){return l(e,function(e){return A.test(e)?p(e.slice(4).toLowerCase()):e})}function h(e){return l(e,function(e){return _.test(e)?"xn--"+v(e):e})}var g="object"==typeof r&&r,y="object"==typeof n&&n&&n.exports==g&&n,b="object"==typeof t&&t;(b.global===b||b.window===b)&&(o=b);var w,x,E=2147483647,k=36,T=1,S=26,C=38,N=700,O=72,j=128,P="-",A=/^xn--/,_=/[^ -~]/,D=/\x2E|\u3002|\uFF0E|\uFF61/g,I={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},M=k-T,L=Math.floor,F=String.fromCharCode;if(w={version:"1.2.4",ucs2:{decode:s,encode:u},decode:p,encode:v,toASCII:h,toUnicode:m},"function"==typeof e&&"object"==typeof e.amd&&e.amd)e("punycode",function(){return w});else if(g&&!g.nodeType)if(y)y.exports=w;else for(x in w)w.hasOwnProperty(x)&&(g[x]=w[x]);else o.punycode=w}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],22:[function(e,t,n){function r(e){function t(e){var t=c();a(t,e)>-1||(t.push(e),f(t))}function n(e){var t=c(),n=a(t,e);-1!==n&&(t.splice(n,1),f(t))}function r(e){return a(c(),e)>-1}function l(e){return r(e)?(n(e),!1):(t(e),!0)}function s(){return e.className}function u(e){var t=c();return t[e]||null}function c(){var t=e.className;return o(t.split(" "),i)}function f(t){var n=t.length;e.className=t.join(" "),p.length=n;for(var r=0;r0||-1)*Math.floor(Math.abs(t))),t},ToPrimitive:function(t){var n,r,o;if(D(t))return t;if(r=t.valueOf,e(r)&&(n=r.call(t),D(n)))return n;if(o=t.toString,e(o)&&(n=o.call(t),D(n)))return n;throw new TypeError},ToObject:function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return r(e)},ToUint32:function(e){return e>>>0}},M=function(){};_(i,{bind:function(t){var n=this;if(!e(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var o,i=c.call(arguments,1),a=function(){if(this instanceof o){var e=n.apply(this,v.call(i,c.call(arguments)));return r(e)===e?e:this}return n.apply(t,v.call(i,c.call(arguments)))},l=h(0,n.length-i.length),s=[],u=0;l>u;u++)d.call(s,"$"+u);return o=Function("binder","return function ("+s.join(",")+"){ return binder.apply(this, arguments); }")(a),n.prototype&&(M.prototype=n.prototype,o.prototype=new M,M.prototype=null),o}});var L=m.bind(o.hasOwnProperty),F=m.bind(o.toString),$=m.bind(l.slice),R=m.bind(l.split),V=t.isArray||function(e){return"[object Array]"===F(e)},H=1!==[].unshift(0);_(n,{unshift:function(){return p.apply(this,arguments),this.length}},H),_(t,{isArray:V});var U=r("a"),q="a"!==U[0]||!(0 in U),z=function(e){var t=!0,n=!0;return e&&(e.call("foo",function(e,n,r){"object"!=typeof r&&(t=!1)}),e.call([1],function(){"use strict";n="string"==typeof this},"x")),!!e&&t&&n};_(n,{forEach:function(t){var n,r=I.ToObject(this),o=q&&O(this)?R(this,""):r,i=-1,a=o.length>>>0;if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.forEach callback must be a function");for(;++i>>0,l=t(a);if(arguments.length>1&&(r=arguments[1]),!e(n))throw new TypeError("Array.prototype.map callback must be a function");for(var s=0;a>s;s++)s in i&&("undefined"!=typeof r?l[s]=n.call(r,i[s],s,o):l[s]=n(i[s],s,o));return l}},!z(n.map)),_(n,{filter:function(t){var n,r,o=I.ToObject(this),i=q&&O(this)?R(this,""):o,a=i.length>>>0,l=[];if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.filter callback must be a function");for(var s=0;a>s;s++)s in i&&(n=i[s],("undefined"==typeof r?t(n,s,o):t.call(r,n,s,o))&&d.call(l,n));return l}},!z(n.filter)),_(n,{every:function(t){var n,r=I.ToObject(this),o=q&&O(this)?R(this,""):r,i=o.length>>>0;if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.every callback must be a function");for(var a=0;i>a;a++)if(a in o&&!("undefined"==typeof n?t(o[a],a,r):t.call(n,o[a],a,r)))return!1;return!0}},!z(n.every)),_(n,{some:function(t){var n,r=I.ToObject(this),o=q&&O(this)?R(this,""):r,i=o.length>>>0;if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.some callback must be a function");for(var a=0;i>a;a++)if(a in o&&("undefined"==typeof n?t(o[a],a,r):t.call(n,o[a],a,r)))return!0;return!1}},!z(n.some));var X=!1;n.reduce&&(X="object"==typeof n.reduce.call("es5",function(e,t,n,r){return r})),_(n,{reduce:function(t){var n=I.ToObject(this),r=q&&O(this)?R(this,""):n,o=r.length>>>0;if(!e(t))throw new TypeError("Array.prototype.reduce callback must be a function");if(0===o&&1===arguments.length)throw new TypeError("reduce of empty array with no initial value");var i,a=0;if(arguments.length>=2)i=arguments[1];else for(;;){if(a in r){i=r[a++];break}if(++a>=o)throw new TypeError("reduce of empty array with no initial value")}for(;o>a;a++)a in r&&(i=t(i,r[a],a,n));return i}},!X);var B=!1;n.reduceRight&&(B="object"==typeof n.reduceRight.call("es5",function(e,t,n,r){return r})),_(n,{reduceRight:function(t){var n=I.ToObject(this),r=q&&O(this)?R(this,""):n,o=r.length>>>0;if(!e(t))throw new TypeError("Array.prototype.reduceRight callback must be a function");if(0===o&&1===arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var i,a=o-1;if(arguments.length>=2)i=arguments[1];else for(;;){if(a in r){i=r[a--];break}if(--a<0)throw new TypeError("reduceRight of empty array with no initial value")}if(0>a)return i;do a in r&&(i=t(i,r[a],a,n));while(a--);return i}},!B);var Y=n.indexOf&&-1!==[0,1].indexOf(1,2);_(n,{indexOf:function(e){var t=q&&O(this)?R(this,""):I.ToObject(this),n=t.length>>>0;if(0===n)return-1;var r=0;for(arguments.length>1&&(r=I.ToInteger(arguments[1])),r=r>=0?r:h(0,n+r);n>r;r++)if(r in t&&t[r]===e)return r;return-1}},Y);var W=n.lastIndexOf&&-1!==[0,1].lastIndexOf(0,-3);_(n,{lastIndexOf:function(e){var t=q&&O(this)?R(this,""):I.ToObject(this),n=t.length>>>0;if(0===n)return-1;var r=n-1;for(arguments.length>1&&(r=g(r,I.ToInteger(arguments[1]))),r=r>=0?r:n-Math.abs(r);r>=0;r--)if(r in t&&e===t[r])return r;return-1}},W);var K=function(){var e=[1,2],t=e.splice();return 2===e.length&&V(t)&&0===t.length}();_(n,{splice:function(e,t){return 0===arguments.length?[]:f.apply(this,arguments)}},!K);var Z=function(){var e={};return n.splice.call(e,0,0,1),1===e.length}();_(n,{splice:function(e,t){if(0===arguments.length)return[];var n=arguments;return this.length=h(I.ToInteger(this.length),0),arguments.length>0&&"number"!=typeof t&&(n=c.call(arguments),n.length<2?d.call(n,this.length-e):n[1]=I.ToInteger(t)),f.apply(this,n)}},!Z);var G=function(){var e=new t(1e5);return e[8]="x",e.splice(1,1),7===e.indexOf("x")}(),J=function(){var e=256,t=[];return t[e]="a",t.splice(e+1,0,"b"),"a"===t[e]}();_(n,{splice:function(e,t){for(var n,r=I.ToObject(this),o=[],i=I.ToUint32(r.length),l=I.ToInteger(e),s=0>l?h(i+l,0):g(l,i),u=g(h(I.ToInteger(t),0),i-s),f=0;u>f;)n=a(s+f),L(r,n)&&(o[f]=r[n]),f+=1;var d,p=c.call(arguments,2),v=p.length;if(u>v){for(f=s;i-u>f;)n=a(f+u),d=a(f+v),L(r,n)?r[d]=r[n]:delete r[d],f+=1;for(f=i;f>i-u+v;)delete r[f-1],f-=1}else if(v>u)for(f=i-u;f>s;)n=a(f+u-1),d=a(f+v-1),L(r,n)?r[d]=r[n]:delete r[d],f-=1;f=s;for(var m=0;m=0&&e(t.callee)),r};_(r,{keys:function(t){var n=e(t),r=se(t),o=null!==t&&"object"==typeof t,i=o&&O(t);if(!o&&!n&&!r)throw new TypeError("Object.keys called on a non-object");var l=[],s=ee&&n;if(i&&te||r)for(var u=0;up;p++){var v=ae[p];f&&"constructor"===v||!L(t,v)||d.call(l,v)}return l}});var ue=r.keys&&function(){return 2===r.keys(arguments).length}(1,2),ce=r.keys;_(r,{keys:function(e){return ce(se(e)?c.call(e):e)}},!ue);var fe=-621987552e5,de="-000001",pe=Date.prototype.toISOString&&-1===new Date(fe).toISOString().indexOf(de),ve=Date.prototype.toISOString&&"1969-12-31T23:59:59.999Z"!==new Date(-1).toISOString();_(Date.prototype,{toISOString:function(){var e,t,n,r,o;if(!isFinite(this))throw new RangeError("Date.prototype.toISOString called on non-finite value.");for(r=this.getUTCFullYear(),o=this.getUTCMonth(),r+=Math.floor(o/12),o=(o%12+12)%12,e=[o+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()],r=(0>r?"-":r>9999?"+":"")+$("00000"+Math.abs(r),r>=0&&9999>=r?-4:-6),t=e.length;t--;)n=e[t],10>n&&(e[t]="0"+n);return r+"-"+c.call(e,0,2).join("-")+"T"+c.call(e,2).join(":")+"."+$("000"+this.getUTCMilliseconds(),-3)+"Z"}},pe||ve);var me=function(){try{return Date.prototype.toJSON&&null===new Date(NaN).toJSON()&&-1!==new Date(fe).toJSON().indexOf(de)&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(e){return!1}}();me||(Date.prototype.toJSON=function(t){var n=r(this),o=I.ToPrimitive(n);if("number"==typeof o&&!isFinite(o))return null;var i=n.toISOString;if(!e(i))throw new TypeError("toISOString property is not callable");return i.call(n)});var he=1e15===Date.parse("+033658-09-27T01:46:40.000Z"),ge=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"))||!isNaN(Date.parse("2012-12-31T23:59:60.000Z")),ye=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));(!Date.parse||ye||ge||!he)&&(Date=function(e){var t=function(n,r,o,i,l,s,u){var c,f=arguments.length;return c=this instanceof e?1===f&&a(n)===n?new e(t.parse(n)):f>=7?new e(n,r,o,i,l,s,u):f>=6?new e(n,r,o,i,l,s):f>=5?new e(n,r,o,i,l):f>=4?new e(n,r,o,i):f>=3?new e(n,r,o):f>=2?new e(n,r):f>=1?new e(n):new e:e.apply(this,arguments),_(c,{constructor:t},!0),c},n=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:(\\.\\d{1,}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),r=[0,31,59,90,120,151,181,212,243,273,304,334,365],o=function(e,t){var n=t>1?1:0;return r[t]+Math.floor((e-1969+n)/4)-Math.floor((e-1901+n)/100)+Math.floor((e-1601+n)/400)+365*(e-1970)},i=function(t){return s(new e(1970,0,1,0,0,0,t))};for(var l in e)L(e,l)&&(t[l]=e[l]);_(t,{now:e.now,UTC:e.UTC},!0),t.prototype=e.prototype,_(t.prototype,{constructor:t},!0);var u=function(t){var r=n.exec(t);if(r){var a,l=s(r[1]),u=s(r[2]||1)-1,c=s(r[3]||1)-1,f=s(r[4]||0),d=s(r[5]||0),p=s(r[6]||0),v=Math.floor(1e3*s(r[7]||0)),m=Boolean(r[4]&&!r[8]),h="-"===r[9]?1:-1,g=s(r[10]||0),y=s(r[11]||0);return(d>0||p>0||v>0?24:25)>f&&60>d&&60>p&&1e3>v&&u>-1&&12>u&&24>g&&60>y&&c>-1&&c=-864e13&&864e13>=a)?a:NaN}return e.parse.apply(this,arguments)};return _(t,{parse:u}),t}(Date)),Date.now||(Date.now=function(){return(new Date).getTime()});var be=u.toFixed&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==0xde0b6b3a7640080.toFixed(0)),we={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function(e,t){for(var n=-1,r=t;++n=0;)n+=we.data[t],we.data[t]=Math.floor(n/e),n=n%e*we.base},numToString:function(){for(var e=we.size,t="";--e>=0;)if(""!==t||0===e||0!==we.data[e]){var n=a(we.data[e]);""===t?t=n:t+=$("0000000",0,7-n.length)+n}return t},pow:function Ae(e,t,n){return 0===t?n:t%2===1?Ae(e,t-1,n*e):Ae(e*e,t/2,n)},log:function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}};_(u,{toFixed:function(e){var t,n,r,o,i,l,u,c;if(t=s(e),t=t!==t?0:Math.floor(t),0>t||t>20)throw new RangeError("Number.toFixed called with invalid number of decimals");if(n=s(this),n!==n)return"NaN";if(-1e21>=n||n>=1e21)return a(n);if(r="",0>n&&(r="-",n=-n),o="0",n>1e-21)if(i=we.log(n*we.pow(2,69,1))-69,l=0>i?n*we.pow(2,-i,1):n/we.pow(2,i,1),l*=4503599627370496,i=52-i,i>0){for(we.multiply(0,l),u=t;u>=7;)we.multiply(1e7,0),u-=7;for(we.multiply(we.pow(10,u,1),0),u=i-1;u>=23;)we.divide(1<<23),u-=23;we.divide(1<0?(c=o.length,o=t>=c?r+$("0.0000000000000000000",0,t-c+2)+o:r+$(o,0,c-t)+"."+$(o,c-t)):o=r+o,o}},be),2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?!function(){var e="undefined"==typeof/()??/.exec("")[1];l.split=function(t,n){var r=this;if("undefined"==typeof t&&0===n)return[];if(!T(t))return R(this,t,n);var o,i,a,l,s=[],u=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),f=0,p=new RegExp(t.source,u+"g");r+="",e||(o=new RegExp("^"+p.source+"$(?!\\s)",u));var v="undefined"==typeof n?-1>>>0:I.ToUint32(n);for(i=p.exec(r);i&&(a=i.index+i[0].length,!(a>f&&(d.call(s,$(r,f,i.index)),!e&&i.length>1&&i[0].replace(o,function(){for(var e=1;e1&&i.index=v)));)p.lastIndex===i.index&&p.lastIndex++,i=p.exec(r);return f===r.length?(l||!p.test(""))&&d.call(s,""):d.call(s,$(r,f)),s.length>v?$(s,0,v):s}}():"0".split(void 0,0).length&&(l.split=function(e,t){return"undefined"==typeof e&&0===t?[]:R(this,e,t)});var xe=l.replace,Ee=function(){var e=[];return"x".replace(/x(.)?/g,function(t,n){d.call(e,n)}),1===e.length&&"undefined"==typeof e[0]}();Ee||(l.replace=function(t,n){var r=e(n),o=T(t)&&/\)[*?]/.test(t.source);if(r&&o){var i=function(e){var r=arguments.length,o=t.lastIndex;t.lastIndex=0;var i=t.exec(e)||[];return t.lastIndex=o,d.call(i,arguments[r-2],arguments[r-1]),n.apply(this,i)};return xe.call(this,t,i)}return xe.call(this,t,n)});var ke=l.substr,Te="".substr&&"b"!=="0b".substr(-1);_(l,{substr:function(e,t){var n=e;return 0>e&&(n=h(this.length+e,0)),ke.call(this,n,t)}},Te);var Se=" \n\f\r \u2028\u2029\ufeff",Ce="",Ne="["+Se+"]",Oe=new RegExp("^"+Ne+Ne+"*"),je=new RegExp(Ne+Ne+"*$"),Pe=l.trim&&(Se.trim()||!Ce.trim());_(l,{trim:function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");return a(this).replace(Oe,"").replace(je,"")}},Pe),(8!==parseInt(Se+"08")||22!==parseInt(Se+"0x16"))&&(parseInt=function(e){var t=/^0[xX]/;return function(n,r){var o=a(n).trim(),i=s(r)||(t.test(o)?16:10);return e(o,i)}}(parseInt))})},{}],26:[function(e,t,n){var r=[],o=r.forEach,i=r.slice;t.exports=function(e){return o.call(i.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e}},{}],27:[function(e,t,n){function r(e){var t=o.call(e);return"[object Function]"===t||"function"==typeof e&&"[object RegExp]"!==t||"undefined"!=typeof window&&(e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt)}t.exports=r;var o=Object.prototype.toString},{}],28:[function(e,t,n){"use strict";t.exports=function(e){return"object"==typeof e&&null!==e}},{}],29:[function(t,n,r){!function(t,r){"undefined"!=typeof n&&n.exports?n.exports=r():"function"==typeof e&&e.amd?e(r):this[t]=r()}("$script",function(){function e(e,t){for(var n=0,r=e.length;r>n;++n)if(!t(e[n]))return s;return 1}function t(t,n){e(t,function(e){return!n(e)})}function n(i,a,l){function s(e){return e.call?e():d[e]}function c(){if(!--y){d[g]=1,h&&h();for(var n in v)e(n.split("|"),s)&&!t(v[n],s)&&(v[n]=[])}}i=i[u]?i:[i];var f=a&&a.call,h=f?a:l,g=f?i.join(""):a,y=i.length;return setTimeout(function(){t(i,function e(t,n){return null===t?c():(t=n||-1!==t.indexOf(".js")||/^https?:\/\//.test(t)||!o?t:o+t+".js",m[t]?(g&&(p[g]=1),2==m[t]?c():setTimeout(function(){e(t,!0)},0)):(m[t]=1,g&&(p[g]=1),void r(t,c)))})},0),n}function r(e,t){var n,r=a.createElement("script");r.onload=r.onerror=r[f]=function(){r[c]&&!/^c|loade/.test(r[c])||n||(r.onload=r[f]=null,n=1,m[e]=2,t())},r.async=1,r.src=i?e+(-1===e.indexOf("?")?"?":"&")+i:e,l.insertBefore(r,l.lastChild)}var o,i,a=document,l=a.getElementsByTagName("head")[0],s=!1,u="push",c="readyState",f="onreadystatechange",d={},p={},v={},m={};return n.get=r,n.order=function(e,t,r){!function o(i){i=e.shift(),e.length?n(i,o):n(i,t,r)}()},n.path=function(e){o=e},n.urlArgs=function(e){i=e},n.ready=function(r,o,i){r=r[u]?r:[r];var a=[];return!t(r,function(e){d[e]||a[u](e)})&&e(r,function(e){return d[e]})?o():!function(e){v[e]=v[e]||[],v[e][u](o),i&&i(a)}(r.join("|")),n},n.done=function(e){n([null],e)},n})},{}]},{},[19])(19)});
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/flowplayer.swf
Binary file src/pyams_media/skin/resources/flowplayer/flowplayer.swf has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/flowplayerhls.swf
Binary file src/pyams_media/skin/resources/flowplayer/flowplayerhls.swf has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/index.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/index.html Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/all-skins.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/skin/all-skins.css Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,998 @@
+@font-face {
+ font-family: 'fpicons';
+ src:url('fonts/fpicons.eot?yg5dv7');
+ src:url('fonts/fpicons.eot?#iefixyg5dv7') format('embedded-opentype'),
+ url('fonts/fpicons.woff?yg5dv7') format('woff'),
+ url('fonts/fpicons.ttf?yg5dv7') format('truetype'),
+ url('fonts/fpicons.svg?yg5dv7#fpicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="fp-i-"], [class*=" fp-i-"] {
+ font-family: 'fpicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.minimalist{position:relative;width:100%;counter-increment:flowplayer;background-size:contain;background-repeat:no-repeat;background-position:center center;display:inline-block;}
+.minimalist *{font-weight:inherit;font-family:inherit;font-style:inherit;text-decoration:inherit;font-size:100%;padding:0;border:0;margin:0;list-style-type:none}
+.minimalist a:focus{outline:0}
+.minimalist video{width:100%}
+.minimalist.is-ipad video{-webkit-transform:translateX(-2048px);}
+.is-ready.minimalist.is-ipad video{-webkit-transform:translateX(0)}
+.minimalist .fp-player{position:absolute;top:0;left:0;width:100%;height:100%}
+.minimalist .fp-engine,.minimalist .fp-ui,.minimalist .fp-message{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;z-index:1}
+.minimalist .fp-ui{z-index:11}
+.minimalist .fp-message{display:none;text-align:center;padding-top:5%;cursor:default;}
+.minimalist .fp-message h2{font-size:120%;margin-bottom:1em}
+.minimalist .fp-message p{color:#666;font-size:95%}
+.minimalist .fp-title{line-height:30px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif;font-size:11px;cursor:default;color:#fff;width:auto;max-width:50%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;float:left;padding:0 20px;}
+.is-rtl.minimalist .fp-title{float:right}
+.aside-time.minimalist .fp-title{display:none !important}
+.minimalist .fp-controls{position:absolute;bottom:0;width:100%;}
+.no-background.minimalist .fp-controls{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important}
+.is-fullscreen.minimalist .fp-controls{bottom:3px}
+.is-mouseover.minimalist .fp-controls{bottom:0}
+.minimalist .fp-controls,.minimalist .fp-title,.minimalist .fp-fullscreen,.minimalist .fp-unload,.minimalist .fp-close,.minimalist .fp-embed,.minimalist.aside-time .fp-time{background-color:#000;background-color:rgba(0,0,0,0.65);}
+.no-background.minimalist .fp-controls,.no-background.minimalist .fp-title,.no-background.minimalist .fp-fullscreen,.no-background.minimalist .fp-unload,.no-background.minimalist .fp-close,.no-background.minimalist .fp-embed,.no-background.minimalist.aside-time .fp-time{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.no-background.minimalist .fp-play,.no-background.minimalist .fp-brand{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.minimalist.fixed-controls .fp-controls{background-color:#000}
+.minimalist .fp-timeline{background-color:#a5a5a5}
+.minimalist .fp-buffer{background-color:#eee}
+.minimalist .fp-progress{background-color:#00a7c8}
+.minimalist .fp-volumeslider{background-color:#a5a5a5}
+.minimalist .fp-volumelevel{background-color:#00a7c8}
+.minimalist .fp-waiting{display:none;margin:19% auto;text-align:center;}
+.minimalist .fp-waiting *{-webkit-box-shadow:0 0 5px #333;-moz-box-shadow:0 0 5px #333;box-shadow:0 0 5px #333}
+.minimalist .fp-waiting em{width:1em;height:1em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;background-color:rgba(255,255,255,0.8);display:inline-block;-webkit-animation:pulse .6s infinite;-moz-animation:pulse .6s infinite;animation:pulse .6s infinite;margin:.3em;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);}
+.minimalist .fp-waiting em:nth-child(1){-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s}
+.minimalist .fp-waiting em:nth-child(2){-webkit-animation-delay:.45s;-moz-animation-delay:.45s;animation-delay:.45s}
+.minimalist .fp-waiting em:nth-child(3){-webkit-animation-delay:.6s;-moz-animation-delay:.6s;animation-delay:.6s}
+.minimalist .fp-waiting p{color:#ccc;font-weight:bold}
+.minimalist .fp-speed{font-size:30px;background-color:#333;background-color:rgba(51,51,51,0.8);color:#eee;margin:0 auto;text-align:center;width:120px;padding:.1em 0 0;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .5s;-moz-transition:opacity .5s;transition:opacity .5s;}
+.minimalist .fp-speed.fp-hilite{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.minimalist .fp-help{position:absolute;top:0;left:-9999em;z-index:100;background-color:#333;background-color:rgba(51,51,51,0.9);width:100%;height:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s;text-align:center;}
+.is-help.minimalist .fp-help{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.minimalist .fp-help .fp-help-section{margin:3%;direction:ltr}
+.minimalist .fp-help .fp-help-basics{margin-top:6%}
+.minimalist .fp-help p{color:#eee;margin:.5em 0;font-size:14px;line-height:1.5;display:inline-block;margin:1% 2%}
+.minimalist .fp-help em{background:#eee;-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;margin-right:.4em;padding:.3em .6em;color:#333}
+.minimalist .fp-help small{font-size:90%;color:#aaa}
+.minimalist .fp-help .fp-close{display:block}
+@media (max-width: 600px){.minimalist .fp-help p{font-size:9px}
+}.minimalist .fp-dropdown{position:absolute;top:5px;width:100px;background-color:#000 !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;margin:0 !important;list-style-type:none !important;}
+.minimalist .fp-dropdown:before{content:'';display:block;position:absolute;top:-5px;left:calc(50% - 5px);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid rgba(51,51,51,0.9)}
+.minimalist .fp-dropdown li{padding:10px !important;margin:0 !important;color:#fff !important;font-size:11px !important;list-style-type:none !important;}
+.minimalist .fp-dropdown li.active{background-color:#00a7c8 !important;cursor:default !important}
+.minimalist .fp-dropdown.fp-dropup{bottom:20px;top:auto;}
+.minimalist .fp-dropdown.fp-dropup:before{top:auto;bottom:-5px;border-bottom:none;border-top:5px solid rgba(51,51,51,0.9)}
+.minimalist .fp-tooltip{background-color:#000;color:#fff;display:none;position:absolute;padding:5px;}
+.minimalist .fp-tooltip:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;left:calc(50% - 5px);border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000}
+.minimalist .fp-timeline-tooltip{bottom:35px}
+.minimalist .fp-timeline:hover+.fp-timeline-tooltip{display:block}
+.minimalist .fp-subtitle{position:absolute;bottom:40px;left:-99999em;z-index:10;text-align:center;width:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .3s;-moz-transition:opacity .3s;transition:opacity .3s;}
+.minimalist .fp-subtitle p{display:inline;background-color:#333;background-color:rgba(51,51,51,0.9);color:#eee;padding:.1em .4em;font-size:16px;line-height:1.6;}
+.minimalist .fp-subtitle p:after{content:'';clear:both}
+.minimalist .fp-subtitle p b{font-weight:bold}
+.minimalist .fp-subtitle p i{font-style:italic}
+.minimalist .fp-subtitle p u{text-decoration:underline}
+.minimalist .fp-subtitle.fp-active{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.minimalist .fp-fullscreen,.minimalist .fp-unload,.minimalist .fp-mute,.minimalist .fp-embed,.minimalist .fp-close,.minimalist .fp-play,.minimalist .fp-menu{font-family:'fpicons' !important;color:#fff !important;font-size:15px !important;text-align:center !important;line-height:30px !important;text-decoration:none !important;}
+.is-rtl.minimalist .fp-fullscreen,.is-rtl.minimalist .fp-unload,.is-rtl.minimalist .fp-mute,.is-rtl.minimalist .fp-embed,.is-rtl.minimalist .fp-close,.is-rtl.minimalist .fp-play,.is-rtl.minimalist .fp-menu{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);transform:scale(-1,1)}
+.is-rtl.minimalist .fp-menu{-webkit-transform:none;-moz-transform:none;transform:none}
+.minimalist .fp-fullscreen:before{content:"\e602"}
+.minimalist .fp-unload:before,.minimalist .fp-close:before{content:"\e600"}
+.minimalist .fp-mute:before{content:"\e606"}
+.minimalist .fp-embed:before{content:"\e603"}
+.minimalist .fp-play:before{content:"\e608"}
+.minimalist .fp-menu:before{content:"\e604"}
+.minimalist .fp-flash-disabled{background:#333;width:390px;margin:0 auto;position:absolute;bottom:0;color:#fff}
+.is-splash.minimalist .fp-ui,.is-paused.minimalist .fp-ui{background:url(img/play_white.png) center no-repeat;background-size:11%;}
+.is-rtl.is-splash.minimalist .fp-ui,.is-rtl.is-paused.minimalist .fp-ui{background:url(img/play_white_rtl.png) center no-repeat;background-size:11%}
+@media (-webkit-min-device-pixel-ratio: 2){.is-splash.minimalist .fp-ui,.is-paused.minimalist .fp-ui{background:url(img/play_white@x2.png) center no-repeat;background-size:11%}
+.is-rtl.is-splash.minimalist .fp-ui,.is-rtl.is-paused.minimalist .fp-ui{background:url(img/play_white_rtl@x2.png) center no-repeat;background-size:11%}
+}.is-fullscreen.minimalist .fp-ui{background-size:auto}
+.is-seeking.minimalist .fp-ui,.is-loading.minimalist .fp-ui{background-image:none}
+.minimalist .fp-brand{color:#fff !important;position:absolute;right:115px;font-weight:normal !important;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;text-decoration:none !important;line-height:15px !important;font-size:11px !important;height:15px;width:55px;bottom:9px;box-sizing:border-box;text-align:center;padding:1px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
+.has-menu.minimalist .fp-brand{right:152px}
+.is-rtl.minimalist .fp-brand{right:auto;left:125px}
+.has-menu.is-rtl.minimalist .fp-brand{left:152px}
+.no-brand.minimalist .fp-brand{display:none}
+.no-volume.no-mute.minimalist .fp-brand{right:10px;}
+.has-menu.no-volume.no-mute.minimalist .fp-brand{right:47px}
+.no-volume.minimalist .fp-brand{right:50px}
+.no-mute.minimalist .fp-brand{right:95px}
+.minimalist .fp-logo{position:absolute;top:auto;left:15px;bottom:40px;cursor:pointer;display:none;z-index:100;}
+.minimalist .fp-logo img{width:100%}
+.is-embedded.minimalist .fp-logo{display:block}
+.fixed-controls.minimalist .fp-logo{bottom:15px}
+.minimalist .fp-fullscreen,.minimalist .fp-unload,.minimalist .fp-close{position:absolute;top:10px;left:auto;right:10px;display:block;width:30px;height:23px;text-align:center;cursor:pointer;height:30px;width:30px;}
+.is-rtl.minimalist .fp-fullscreen,.is-rtl.minimalist .fp-unload,.is-rtl.minimalist .fp-close{right:auto;left:10px}
+.minimalist .fp-unload,.minimalist .fp-close{display:none}
+.minimalist .fp-play{display:none;height:30px !important;position:absolute;bottom:0;left:0;text-align:center;}
+.is-rtl.minimalist .fp-play{left:auto;right:0}
+.is-playing.minimalist .fp-play:before{content:"\e607"}
+.minimalist .fp-menu{display:none;position:absolute;bottom:0;z-index:11;right:10px;}
+.is-rtl.minimalist .fp-menu{right:auto;left:10px}
+.has-menu.minimalist .fp-menu{display:block}
+.minimalist .fp-menu .fp-dropdown{z-index:12;display:none;left:-42.5px;line-height:auto;width:149px;-webkit-transform:none;-moz-transform:none;transform:none;}
+.is-rtl.minimalist .fp-menu .fp-dropdown{left:-10px}
+.minimalist .fp-menu.dropdown-open .fp-dropdown{display:block}
+.minimalist.is-ready.is-closeable .fp-unload{display:block}
+.minimalist.is-ready.is-closeable .fp-embed{right:90px}
+.minimalist.is-ready.is-closeable .fp-fullscreen{right:50px}
+.minimalist.is-fullscreen .fp-fullscreen{display:block !important;}
+.minimalist.is-fullscreen .fp-fullscreen:before{content:"\e601"}
+.minimalist .fp-timeline{height:3px;position:relative;overflow:hidden;top:10px;height:10px;margin:0 225px 0 55px;}
+.no-brand.minimalist .fp-timeline{margin-right:160px;}
+.has-menu.no-brand.minimalist .fp-timeline{margin-right:187px}
+.no-volume.no-brand.minimalist .fp-timeline{margin-right:95px}
+.no-mute.no-brand.minimalist .fp-timeline{margin-right:130px}
+.no-mute.no-volume.no-brand.minimalist .fp-timeline{margin-right:55px}
+.has-menu.minimalist .fp-timeline{margin-right:252px}
+.no-volume.minimalist .fp-timeline{margin-right:160px}
+.no-mute.minimalist .fp-timeline{margin-right:195px}
+.no-mute.no-volume.minimalist .fp-timeline{margin-right:120px;}
+.has-menu.no-mute.no-volume.minimalist .fp-timeline{margin-right:157px}
+.is-rtl.minimalist .fp-timeline{margin:0 55px 0 225px;}
+.no-brand.is-rtl.minimalist .fp-timeline{margin-left:160px;}
+.has-menu.no-brand.is-rtl.minimalist .fp-timeline{margin-left:197px}
+.has-menu.is-rtl.minimalist .fp-timeline{margin-left:262px}
+.no-volume.is-rtl.minimalist .fp-timeline{margin-left:95px}
+.no-mute.is-rtl.minimalist .fp-timeline{margin-left:130px}
+.no-mute.no-volume.is-rtl.minimalist .fp-timeline{margin-left:55px}
+.is-long.minimalist .fp-timeline{margin:0 255px 0 85px;}
+.no-volume.is-long.minimalist .fp-timeline{margin-right:180px}
+.no-mute.is-long.minimalist .fp-timeline{margin-right:140px}
+.has-menu.is-long.minimalist .fp-timeline{margin-right:292px}
+.no-brand.is-long.minimalist .fp-timeline{margin-right:190px;}
+.no-volume.no-brand.is-long.minimalist .fp-timeline{margin-right:125px}
+.no-mute.no-brand.is-long.minimalist .fp-timeline{margin-right:85px}
+.has-menu.no-brand.is-long.minimalist .fp-timeline{margin-right:227px}
+.is-rtl.is-long.minimalist .fp-timeline{margin:85px 0 190px 0;}
+.no-volume.is-rtl.is-long.minimalist .fp-timeline{margin-left:125px}
+.no-mute.is-rtl.is-long.minimalist .fp-timeline{margin-left:85px}
+.aside-time.minimalist .fp-timeline,.no-time.minimalist .fp-timeline{margin:0 190px 0 10px;}
+.has-menu.aside-time.minimalist .fp-timeline,.has-menu.no-time.minimalist .fp-timeline{margin-right:227px}
+.aside-time.no-brand.minimalist .fp-timeline{margin-right:115px}
+.aside-time.no-volume.minimalist .fp-timeline,.no-time.no-volume.minimalist .fp-timeline{margin-right:115px}
+.aside-time.no-mute.minimalist .fp-timeline,.no-time.no-mute.minimalist .fp-timeline{margin-right:75px}
+.is-rtl.aside-time.minimalist .fp-timeline,.is-rtl.no-time.minimalist .fp-timeline{margin:0 10px 0 115px}
+.is-rtl.aside-time.no-volume.minimalist .fp-timeline,.is-rtl.no-time.no-volume.minimalist .fp-timeline{margin-left:50px}
+.is-rtl.aside-time.no-mute.minimalist .fp-timeline,.is-rtl.no-time.no-mute.minimalist .fp-timeline{margin-left:10px}
+.minimalist .fp-buffer,.minimalist .fp-progress{position:absolute;top:0;left:auto;height:100%;cursor:col-resize}
+.minimalist .fp-buffer{-webkit-transition:width .25s linear;-moz-transition:width .25s linear;transition:width .25s linear}
+.minimalist .fp-timeline.no-animation .fp-buffer{-webkit-transition:none;-moz-transition:none;transition:none}
+.minimalist .fp-progress.animated{transition-timing-function:linear;transition-property:width,height}
+.minimalist.is-touch .fp-timeline{overflow:visible}
+.minimalist.is-touch .fp-progress{-webkit-transition:width .2s linear;-moz-transition:width .2s linear;transition:width .2s linear;box-sizing:border-box}
+.minimalist.is-touch .fp-timeline.is-dragging .fp-progress{-webkit-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;-moz-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear}
+.minimalist.is-touch.is-mouseover .fp-progress:after,.minimalist.is-touch.is-mouseover .fp-progress:before{content:'';box-sizing:border-box;display:block;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;position:absolute;right:-5px}
+.minimalist.is-touch.is-rtl.is-mouseover .fp-progress:after,.minimalist.is-touch.is-rtl.is-mouseover .fp-progress:before{right:auto;left:-5px}
+.minimalist.is-touch.is-rtl.is-mouseover .fp-progress:after{left:-10px;-webkit-box-shadow:-1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:-1px 0 4px rgba(0,0,0,0.5);box-shadow:-1px 0 4px rgba(0,0,0,0.5)}
+.minimalist.is-touch.is-mouseover .fp-progress:before{width:10px;height:10px}
+.minimalist.is-touch.is-mouseover .fp-progress:after{height:18px;width:18px;top:-4px;right:-10px;border:5px solid rgba(255,255,255,0.65);-webkit-box-shadow:1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:1px 0 4px rgba(0,0,0,0.5);box-shadow:1px 0 4px rgba(0,0,0,0.5)}
+.minimalist.is-touch.is-mouseover .fp-timeline.is-dragging .fp-progress:after{border:10px solid #fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px;-webkit-transition:inherit;-moz-transition:inherit;transition:inherit;top:-5px;right:-10px}
+.minimalist.is-touch.is-rtl.is-mouseover .fp-timeline.is-dragging .fp-progress:after{left:-15px;right:auto;border:10px solid #fff}
+.minimalist .fp-volume{position:absolute;top:12px;right:10px;}
+.has-menu.minimalist .fp-volume{right:37px}
+.is-rtl.minimalist .fp-volume{right:auto;left:10px}
+.is-rtl.has-menu.minimalist .fp-volume{left:37px}
+.minimalist .fp-mute{position:relative;width:30px;height:30px;float:left;top:-12px;cursor:pointer;}
+.is-rtl.minimalist .fp-mute{float:right}
+.no-mute.minimalist .fp-mute{display:none}
+.minimalist .fp-volumeslider{width:75px;height:6px;cursor:col-resize;float:left;}
+.is-rtl.minimalist .fp-volumeslider{float:right}
+.no-volume.minimalist .fp-volumeslider{display:none}
+.minimalist .fp-volumelevel{height:100%}
+.minimalist .fp-time{text-shadow:0 0 1px #000;font-size:11px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;color:#fff;width:100%;}
+.minimalist .fp-time.is-inverted .fp-duration{display:none}
+.minimalist .fp-time.is-inverted .fp-remaining{display:inline}
+.minimalist .fp-time em{width:35px;height:10px;line-height:10px;text-align:center;position:absolute;bottom:9px}
+.no-time.minimalist .fp-time{display:none}
+.is-long.minimalist .fp-time em{width:65px}
+.minimalist .fp-elapsed{left:10px;}
+.is-rtl.minimalist .fp-elapsed{left:auto;right:10px}
+.minimalist .fp-remaining,.minimalist .fp-duration{right:180px;color:#eee;}
+.no-brand.minimalist .fp-remaining,.no-brand.minimalist .fp-duration{right:125px;}
+.has-menu.no-brand.minimalist .fp-remaining,.has-menu.no-brand.minimalist .fp-duration{right:152px}
+.no-volume.no-brand.minimalist .fp-remaining,.no-volume.no-brand.minimalist .fp-duration{right:50px}
+.no-mute.no-brand.minimalist .fp-remaining,.no-mute.no-brand.minimalist .fp-duration{right:95px}
+.no-mute.no-volume.no-brand.minimalist .fp-remaining,.no-mute.no-volume.no-brand.minimalist .fp-duration{right:10px}
+.has-menu.minimalist .fp-remaining,.has-menu.minimalist .fp-duration{right:217px}
+.no-volume.minimalist .fp-remaining,.no-volume.minimalist .fp-duration{right:115px}
+.no-mute.minimalist .fp-remaining,.no-mute.minimalist .fp-duration{right:160px}
+.no-mute.no-volume.minimalist .fp-remaining,.no-mute.no-volume.minimalist .fp-duration{right:75px;}
+.has-menu.no-mute.no-volume.minimalist .fp-remaining,.has-menu.no-mute.no-volume.minimalist .fp-duration{right:112px}
+.is-rtl.minimalist .fp-remaining,.is-rtl.minimalist .fp-duration{right:auto;left:180px;}
+.no-brand.is-rtl.minimalist .fp-remaining,.no-brand.is-rtl.minimalist .fp-duration{left:115px;}
+.has-menu.no-brand.is-rtl.minimalist .fp-remaining,.has-menu.no-brand.is-rtl.minimalist .fp-duration{left:142px}
+.has-menu.is-rtl.minimalist .fp-remaining,.has-menu.is-rtl.minimalist .fp-duration{left:207px}
+.no-volume.is-rtl.minimalist .fp-remaining,.no-volume.is-rtl.minimalist .fp-duration{left:50px}
+.no-mute.is-rtl.minimalist .fp-remaining,.no-mute.is-rtl.minimalist .fp-duration{left:95px}
+.no-mute.no-volume.is-rtl.minimalist .fp-remaining,.no-mute.no-volume.is-rtl.minimalist .fp-duration{left:10px}
+.minimalist .fp-remaining{display:none}
+.minimalist.aside-time .fp-time{position:absolute;top:10px;left:10px;bottom:auto !important;width:auto;background-color:#000;background-color:rgba(0,0,0,0.65);height:30px;padding:0 5px;-webkit-border-radius:control_border_radius;-moz-border-radius:control_border_radius;border-radius:control_border_radius;line-height:30px;text-align:center;font-size:15px;}
+.no-background.minimalist.aside-time .fp-time{background-color:transparent !important}
+.minimalist.aside-time .fp-time strong,.minimalist.aside-time .fp-time em{position:static}
+.minimalist.aside-time .fp-time .fp-elapsed::after{content:' / '}
+.minimalist.is-splash,.minimalist.is-poster{cursor:pointer;}
+.minimalist.is-splash .fp-controls,.minimalist.is-poster .fp-controls,.minimalist.is-splash .fp-fullscreen,.minimalist.is-poster .fp-fullscreen,.minimalist.is-splash .fp-unload,.minimalist.is-poster .fp-unload,.minimalist.is-splash .fp-time,.minimalist.is-poster .fp-time,.minimalist.is-splash .fp-embed,.minimalist.is-poster .fp-embed,.minimalist.is-splash .fp-title,.minimalist.is-poster .fp-title,.minimalist.is-splash .fp-brand,.minimalist.is-poster .fp-brand{display:none !important}
+.minimalist.is-poster .fp-engine{top:-9999em}
+.minimalist.is-loading .fp-waiting{display:block}
+.minimalist.is-loading .fp-controls,.minimalist.is-loading .fp-time{display:none}
+.minimalist.is-loading .fp-ui{background-position:-9999em}
+.minimalist.is-loading video.fp-engine{position:absolute;top:-9999em}
+.minimalist.is-seeking .fp-waiting{display:block}
+.minimalist.is-playing{background-image:none !important;background-color:#333;}
+.minimalist.is-playing.hls-fix.is-finished .fp-engine{position:absolute;top:-9999em}
+.minimalist.is-fullscreen{top:0 !important;left:0 !important;border:0 !important;margin:0 !important;width:100% !important;height:100% !important;max-width:100% !important;z-index:99999 !important;-webkit-box-shadow:0 !important;-moz-box-shadow:0 !important;box-shadow:0 !important;background-image:none !important;background-color:#333;}
+.is-rtl.minimalist.is-fullscreen{left:auto !important;right:0 !important}
+.minimalist.is-fullscreen .fp-player{background-color:#333}
+.minimalist.is-error{border:1px solid #909090;background:#fdfdfd !important;}
+.minimalist.is-error h2{font-weight:bold;font-size:large;margin-top:10%}
+.minimalist.is-error .fp-message{display:block}
+.minimalist.is-error object,.minimalist.is-error video,.minimalist.is-error .fp-controls,.minimalist.is-error .fp-time,.minimalist.is-error .fp-subtitle{display:none}
+.minimalist.is-ready.is-muted .fp-mute{opacity:.7;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70)}
+.minimalist.is-ready.is-muted .fp-mute:before{content:"\e605"}
+.minimalist.is-mouseout .fp-controls,.minimalist.is-mouseout .fp-title{height:0;-webkit-transition:height .15s .3s;-moz-transition:height .15s .3s;transition:height .15s .3s}
+.is-fullscreen.minimalist.is-mouseout .fp-controls{height:3px;bottom:0}
+.minimalist.is-mouseout .fp-title{overflow:hidden}
+.minimalist.is-mouseout .fp-timeline{margin:0 !important}
+.minimalist.is-mouseout .fp-timeline{-webkit-transition:height .15s .3s,top .15s .3s,margin .15s .3s;-moz-transition:height .15s .3s,top .15s .3s,margin .15s .3s;transition:height .15s .3s,top .15s .3s,margin .15s .3s;height:4px;top:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
+.minimalist.is-mouseout .fp-fullscreen,.minimalist.is-mouseout .fp-unload,.minimalist.is-mouseout .fp-elapsed,.minimalist.is-mouseout .fp-remaining,.minimalist.is-mouseout .fp-duration,.minimalist.is-mouseout .fp-embed,.minimalist.is-mouseout .fp-volume,.minimalist.is-mouseout .fp-play,.minimalist.is-mouseout .fp-menu,.minimalist.is-mouseout .fp-brand,.minimalist.is-mouseout .fp-timeline-tooltip,.minimalist.is-mouseout.aside-time .fp-time{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .15s .3s;-moz-transition:opacity .15s .3s;transition:opacity .15s .3s}
+.minimalist.is-mouseover .fp-controls,.minimalist.fixed-controls .fp-controls{height:30px}
+.minimalist.is-mouseover .fp-title,.minimalist.fixed-controls .fp-title{height:30px}
+.minimalist.is-mouseover .fp-fullscreen,.minimalist.fixed-controls .fp-fullscreen,.minimalist.is-mouseover .fp-unload,.minimalist.fixed-controls .fp-unload,.minimalist.is-mouseover .fp-elapsed,.minimalist.fixed-controls .fp-elapsed,.minimalist.is-mouseover .fp-remaining,.minimalist.fixed-controls .fp-remaining,.minimalist.is-mouseover .fp-duration,.minimalist.fixed-controls .fp-duration,.minimalist.is-mouseover .fp-embed,.minimalist.fixed-controls .fp-embed,.minimalist.is-mouseover .fp-logo,.minimalist.fixed-controls .fp-logo,.minimalist.is-mouseover .fp-volume,.minimalist.fixed-controls .fp-volume,.minimalist.is-mouseover .fp-play,.minimalist.fixed-controls .fp-play,.minimalist.is-mouseover .fp-menu,.minimalist.fixed-controls .fp-menu{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.minimalist.fixed-controls .fp-volume{display:block}
+.minimalist.fixed-controls .fp-controls{bottom:-30px;}
+.is-fullscreen.minimalist.fixed-controls .fp-controls{bottom:0}
+.minimalist.fixed-controls .fp-time em{bottom:-20px;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);}
+.is-fullscreen.minimalist.fixed-controls .fp-time em{bottom:10px}
+.minimalist.is-disabled .fp-progress{background-color:#999}
+.minimalist.is-flash-disabled{background-color:#333;}
+.minimalist.is-flash-disabled object.fp-engine{z-index:100}
+.minimalist.is-flash-disabled .fp-flash-disabled{display:block;z-index:101}
+.minimalist .fp-embed{position:absolute;top:10px;left:auto;right:50px;display:block;width:30px;height:30px;text-align:center;}
+.is-rtl.minimalist .fp-embed{right:auto;left:50px}
+.minimalist .fp-embed-code{position:absolute;display:none;top:10px;right:67px;background-color:#333;padding:3px 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 3px #ccc;-moz-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc;font-size:12px;}
+.is-closeable.minimalist .fp-embed-code{right:99px}
+.minimalist .fp-embed-code:before{content:'';width:0;height:0;position:absolute;top:2px;right:-10px;border:5px solid transparent;border-left-color:#333}
+.is-rtl.minimalist .fp-embed-code{right:auto;left:67px;}
+.is-rtl.minimalist .fp-embed-code:before{right:auto;left:-10px;border-left-color:transparent;border-right-color:#333}
+.minimalist .fp-embed-code textarea{width:400px;height:16px;font-family:monaco,"courier new",verdana;color:#777;white-space:nowrap;resize:none;overflow:hidden;border:0;outline:0;background-color:transparent;color:#ccc}
+.minimalist .fp-embed-code label{display:block;color:#999}
+.minimalist.is-embedding .fp-embed,.minimalist.is-embedding .fp-embed-code{display:block;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.minimalist.no-time .fp-embed{left:10px !important;}
+.is-rtl.minimalist.no-time .fp-embed{left:auto;right:10px !important}
+.minimalist.is-live .fp-timeline,.minimalist.is-live .fp-duration,.minimalist.is-live .fp-remaining{display:none}
+.minimalist .fp-context-menu{position:absolute;display:none;z-index:1001;background-color:#fff;padding:10px;border:1px solid #aaa;-webkit-box-shadow:0 0 4px #888;-moz-box-shadow:0 0 4px #888;box-shadow:0 0 4px #888;width:170px;}
+.minimalist .fp-context-menu li{text-align:center !important;padding:10px;color:#444 !important;font-size:11px !important;margin:0 -10px 0 -10px;}
+.minimalist .fp-context-menu li a{color:#00a7c8 !important;font-size:12.100000000000001px !important}
+.minimalist .fp-context-menu li:hover:not(.copyright){background-color:#eee}
+.minimalist .fp-context-menu li.copyright{margin:0;padding-left:110px;background-image:url("img/flowplayer.png");background-repeat:no-repeat;background-size:100px 20px;background-position:5px 5px;border-bottom:1px solid #bbb;}
+@media (-webkit-min-device-pixel-ratio: 2){.minimalist .fp-context-menu li.copyright{background-image:url("img/flowplayer@2x.png")}
+}@-moz-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-webkit-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-o-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-ms-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}.minimalist.is-touch.is-mouseover .fp-progress:before{background-color:#00a7c8}
+.minimalist .fp-menu .fp-dropdown{right:-10px;left:auto;bottom:30px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
+.minimalist .fp-menu .fp-dropdown:before{display:none}
+.minimalist .fp-play{width:30px}
+.minimalist.aside-time .fp-time{top:0;left:0}
+.no-brand.minimalist .fp-remaining,.no-brand.minimalist .fp-duration{right:115px}
+.minimalist .fp-fullscreen,.minimalist .fp-unload,.minimalist .fp-close,.minimalist .fp-embed{right:0;top:0;}
+.is-rtl.minimalist .fp-fullscreen,.is-rtl.minimalist .fp-unload,.is-rtl.minimalist .fp-close,.is-rtl.minimalist .fp-embed{right:auto;left:0}
+.minimalist .fp-embed{right:32px;}
+.is-rtl.minimalist .fp-embed{right:auto;left:32px}
+.minimalist.is-closeable.is-ready .fp-fullscreen{right:32px}
+.minimalist.is-closeable.is-ready .fp-embed{right:64px}
+.minimalist.play-button .fp-play{display:block}
+.minimalist.play-button .fp-elapsed{left:27px;}
+.is-rtl.minimalist.play-button .fp-elapsed{right:27px}
+.minimalist.play-button .fp-timeline{margin-left:72px;}
+.is-rtl.minimalist.play-button .fp-timeline{margin-right:72px}
+.is-long.minimalist.play-button .fp-timeline{margin-left:102px;}
+.is-rtl.is-long.minimalist.play-button .fp-timeline{margin-right:102px}
+.no-time.minimalist.play-button .fp-timeline,.aside-time.minimalist.play-button .fp-timeline{margin-left:27px;}
+.is-rtl.no-time.minimalist.play-button .fp-timeline,.is-rtl.aside-time.minimalist.play-button .fp-timeline{margin-right:27px}
+@font-face {
+ font-family: 'fpicons';
+ src:url('fonts/fpicons.eot?yg5dv7');
+ src:url('fonts/fpicons.eot?#iefixyg5dv7') format('embedded-opentype'),
+ url('fonts/fpicons.woff?yg5dv7') format('woff'),
+ url('fonts/fpicons.ttf?yg5dv7') format('truetype'),
+ url('fonts/fpicons.svg?yg5dv7#fpicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="fp-i-"], [class*=" fp-i-"] {
+ font-family: 'fpicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.functional{position:relative;width:100%;counter-increment:flowplayer;background-size:contain;background-repeat:no-repeat;background-position:center center;display:inline-block;}
+.functional *{font-weight:inherit;font-family:inherit;font-style:inherit;text-decoration:inherit;font-size:100%;padding:0;border:0;margin:0;list-style-type:none}
+.functional a:focus{outline:0}
+.functional video{width:100%}
+.functional.is-ipad video{-webkit-transform:translateX(-2048px);}
+.is-ready.functional.is-ipad video{-webkit-transform:translateX(0)}
+.functional .fp-player{position:absolute;top:0;left:0;width:100%;height:100%}
+.functional .fp-engine,.functional .fp-ui,.functional .fp-message{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;z-index:1}
+.functional .fp-ui{z-index:11}
+.functional .fp-message{display:none;text-align:center;padding-top:5%;cursor:default;}
+.functional .fp-message h2{font-size:120%;margin-bottom:1em}
+.functional .fp-message p{color:#666;font-size:95%}
+.functional .fp-title{line-height:30px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif;font-size:11px;cursor:default;color:#fff;width:auto;max-width:50%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;float:left;padding:0 20px;}
+.is-rtl.functional .fp-title{float:right}
+.aside-time.functional .fp-title{display:none !important}
+.functional .fp-controls{position:absolute;bottom:0;width:100%;}
+.no-background.functional .fp-controls{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important}
+.is-fullscreen.functional .fp-controls{bottom:3px}
+.is-mouseover.functional .fp-controls{bottom:0}
+.functional .fp-controls,.functional .fp-title,.functional .fp-fullscreen,.functional .fp-unload,.functional .fp-close,.functional .fp-embed,.functional.aside-time .fp-time{background-color:#000;background-color:rgba(0,0,0,0.65);}
+.no-background.functional .fp-controls,.no-background.functional .fp-title,.no-background.functional .fp-fullscreen,.no-background.functional .fp-unload,.no-background.functional .fp-close,.no-background.functional .fp-embed,.no-background.functional.aside-time .fp-time{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.no-background.functional .fp-play,.no-background.functional .fp-brand{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.functional.fixed-controls .fp-controls{background-color:#000}
+.functional .fp-timeline{background-color:#a5a5a5}
+.functional .fp-buffer{background-color:#eee}
+.functional .fp-progress{background-color:#00a7c8}
+.functional .fp-volumeslider{background-color:#a5a5a5}
+.functional .fp-volumelevel{background-color:#00a7c8}
+.functional .fp-waiting{display:none;margin:19% auto;text-align:center;}
+.functional .fp-waiting *{-webkit-box-shadow:0 0 5px #333;-moz-box-shadow:0 0 5px #333;box-shadow:0 0 5px #333}
+.functional .fp-waiting em{width:1em;height:1em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;background-color:rgba(255,255,255,0.8);display:inline-block;-webkit-animation:pulse .6s infinite;-moz-animation:pulse .6s infinite;animation:pulse .6s infinite;margin:.3em;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);}
+.functional .fp-waiting em:nth-child(1){-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s}
+.functional .fp-waiting em:nth-child(2){-webkit-animation-delay:.45s;-moz-animation-delay:.45s;animation-delay:.45s}
+.functional .fp-waiting em:nth-child(3){-webkit-animation-delay:.6s;-moz-animation-delay:.6s;animation-delay:.6s}
+.functional .fp-waiting p{color:#ccc;font-weight:bold}
+.functional .fp-speed{font-size:30px;background-color:#333;background-color:rgba(51,51,51,0.8);color:#eee;margin:0 auto;text-align:center;width:120px;padding:.1em 0 0;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .5s;-moz-transition:opacity .5s;transition:opacity .5s;}
+.functional .fp-speed.fp-hilite{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.functional .fp-help{position:absolute;top:0;left:-9999em;z-index:100;background-color:#333;background-color:rgba(51,51,51,0.9);width:100%;height:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s;text-align:center;}
+.is-help.functional .fp-help{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.functional .fp-help .fp-help-section{margin:3%;direction:ltr}
+.functional .fp-help .fp-help-basics{margin-top:6%}
+.functional .fp-help p{color:#eee;margin:.5em 0;font-size:14px;line-height:1.5;display:inline-block;margin:1% 2%}
+.functional .fp-help em{background:#eee;-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;margin-right:.4em;padding:.3em .6em;color:#333}
+.functional .fp-help small{font-size:90%;color:#aaa}
+.functional .fp-help .fp-close{display:block}
+@media (max-width: 600px){.functional .fp-help p{font-size:9px}
+}.functional .fp-dropdown{position:absolute;top:5px;width:100px;background-color:#000 !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;margin:0 !important;list-style-type:none !important;}
+.functional .fp-dropdown:before{content:'';display:block;position:absolute;top:-5px;left:calc(50% - 5px);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid rgba(51,51,51,0.9)}
+.functional .fp-dropdown li{padding:10px !important;margin:0 !important;color:#fff !important;font-size:11px !important;list-style-type:none !important;}
+.functional .fp-dropdown li.active{background-color:#00a7c8 !important;cursor:default !important}
+.functional .fp-dropdown.fp-dropup{bottom:20px;top:auto;}
+.functional .fp-dropdown.fp-dropup:before{top:auto;bottom:-5px;border-bottom:none;border-top:5px solid rgba(51,51,51,0.9)}
+.functional .fp-tooltip{background-color:#000;color:#fff;display:none;position:absolute;padding:5px;}
+.functional .fp-tooltip:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;left:calc(50% - 5px);border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000}
+.functional .fp-timeline-tooltip{bottom:35px}
+.functional .fp-timeline:hover+.fp-timeline-tooltip{display:block}
+.functional .fp-subtitle{position:absolute;bottom:40px;left:-99999em;z-index:10;text-align:center;width:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .3s;-moz-transition:opacity .3s;transition:opacity .3s;}
+.functional .fp-subtitle p{display:inline;background-color:#333;background-color:rgba(51,51,51,0.9);color:#eee;padding:.1em .4em;font-size:16px;line-height:1.6;}
+.functional .fp-subtitle p:after{content:'';clear:both}
+.functional .fp-subtitle p b{font-weight:bold}
+.functional .fp-subtitle p i{font-style:italic}
+.functional .fp-subtitle p u{text-decoration:underline}
+.functional .fp-subtitle.fp-active{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.functional .fp-fullscreen,.functional .fp-unload,.functional .fp-mute,.functional .fp-embed,.functional .fp-close,.functional .fp-play,.functional .fp-menu{font-family:'fpicons' !important;color:#fff !important;font-size:15px !important;text-align:center !important;line-height:30px !important;text-decoration:none !important;}
+.is-rtl.functional .fp-fullscreen,.is-rtl.functional .fp-unload,.is-rtl.functional .fp-mute,.is-rtl.functional .fp-embed,.is-rtl.functional .fp-close,.is-rtl.functional .fp-play,.is-rtl.functional .fp-menu{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);transform:scale(-1,1)}
+.is-rtl.functional .fp-menu{-webkit-transform:none;-moz-transform:none;transform:none}
+.functional .fp-fullscreen:before{content:"\e602"}
+.functional .fp-unload:before,.functional .fp-close:before{content:"\e600"}
+.functional .fp-mute:before{content:"\e606"}
+.functional .fp-embed:before{content:"\e603"}
+.functional .fp-play:before{content:"\e608"}
+.functional .fp-menu:before{content:"\e604"}
+.functional .fp-flash-disabled{background:#333;width:390px;margin:0 auto;position:absolute;bottom:0;color:#fff}
+.is-splash.functional .fp-ui,.is-paused.functional .fp-ui{background:url(img/play_white.png) center no-repeat;background-size:11%;}
+.is-rtl.is-splash.functional .fp-ui,.is-rtl.is-paused.functional .fp-ui{background:url(img/play_white_rtl.png) center no-repeat;background-size:11%}
+@media (-webkit-min-device-pixel-ratio: 2){.is-splash.functional .fp-ui,.is-paused.functional .fp-ui{background:url(img/play_white@x2.png) center no-repeat;background-size:11%}
+.is-rtl.is-splash.functional .fp-ui,.is-rtl.is-paused.functional .fp-ui{background:url(img/play_white_rtl@x2.png) center no-repeat;background-size:11%}
+}.is-fullscreen.functional .fp-ui{background-size:auto}
+.is-seeking.functional .fp-ui,.is-loading.functional .fp-ui{background-image:none}
+.functional .fp-brand{color:#fff !important;position:absolute;right:115px;font-weight:normal !important;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;text-decoration:none !important;line-height:15px !important;font-size:11px !important;height:15px;width:55px;bottom:9px;box-sizing:border-box;text-align:center;padding:1px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
+.has-menu.functional .fp-brand{right:152px}
+.is-rtl.functional .fp-brand{right:auto;left:125px}
+.has-menu.is-rtl.functional .fp-brand{left:152px}
+.no-brand.functional .fp-brand{display:none}
+.no-volume.no-mute.functional .fp-brand{right:10px;}
+.has-menu.no-volume.no-mute.functional .fp-brand{right:47px}
+.no-volume.functional .fp-brand{right:50px}
+.no-mute.functional .fp-brand{right:95px}
+.functional .fp-logo{position:absolute;top:auto;left:15px;bottom:40px;cursor:pointer;display:none;z-index:100;}
+.functional .fp-logo img{width:100%}
+.is-embedded.functional .fp-logo{display:block}
+.fixed-controls.functional .fp-logo{bottom:15px}
+.functional .fp-fullscreen,.functional .fp-unload,.functional .fp-close{position:absolute;top:10px;left:auto;right:10px;display:block;width:30px;height:23px;text-align:center;cursor:pointer;height:30px;width:30px;}
+.is-rtl.functional .fp-fullscreen,.is-rtl.functional .fp-unload,.is-rtl.functional .fp-close{right:auto;left:10px}
+.functional .fp-unload,.functional .fp-close{display:none}
+.functional .fp-play{display:none;height:30px !important;position:absolute;bottom:0;left:0;text-align:center;}
+.is-rtl.functional .fp-play{left:auto;right:0}
+.is-playing.functional .fp-play:before{content:"\e607"}
+.functional .fp-menu{display:none;position:absolute;bottom:0;z-index:11;right:10px;}
+.is-rtl.functional .fp-menu{right:auto;left:10px}
+.has-menu.functional .fp-menu{display:block}
+.functional .fp-menu .fp-dropdown{z-index:12;display:none;left:-42.5px;line-height:auto;width:149px;-webkit-transform:none;-moz-transform:none;transform:none;}
+.is-rtl.functional .fp-menu .fp-dropdown{left:-10px}
+.functional .fp-menu.dropdown-open .fp-dropdown{display:block}
+.functional.is-ready.is-closeable .fp-unload{display:block}
+.functional.is-ready.is-closeable .fp-embed{right:90px}
+.functional.is-ready.is-closeable .fp-fullscreen{right:50px}
+.functional.is-fullscreen .fp-fullscreen{display:block !important;}
+.functional.is-fullscreen .fp-fullscreen:before{content:"\e601"}
+.functional .fp-timeline{height:3px;position:relative;overflow:hidden;top:10px;height:10px;margin:0 225px 0 55px;}
+.no-brand.functional .fp-timeline{margin-right:160px;}
+.has-menu.no-brand.functional .fp-timeline{margin-right:187px}
+.no-volume.no-brand.functional .fp-timeline{margin-right:95px}
+.no-mute.no-brand.functional .fp-timeline{margin-right:130px}
+.no-mute.no-volume.no-brand.functional .fp-timeline{margin-right:55px}
+.has-menu.functional .fp-timeline{margin-right:252px}
+.no-volume.functional .fp-timeline{margin-right:160px}
+.no-mute.functional .fp-timeline{margin-right:195px}
+.no-mute.no-volume.functional .fp-timeline{margin-right:120px;}
+.has-menu.no-mute.no-volume.functional .fp-timeline{margin-right:157px}
+.is-rtl.functional .fp-timeline{margin:0 55px 0 225px;}
+.no-brand.is-rtl.functional .fp-timeline{margin-left:160px;}
+.has-menu.no-brand.is-rtl.functional .fp-timeline{margin-left:197px}
+.has-menu.is-rtl.functional .fp-timeline{margin-left:262px}
+.no-volume.is-rtl.functional .fp-timeline{margin-left:95px}
+.no-mute.is-rtl.functional .fp-timeline{margin-left:130px}
+.no-mute.no-volume.is-rtl.functional .fp-timeline{margin-left:55px}
+.is-long.functional .fp-timeline{margin:0 255px 0 85px;}
+.no-volume.is-long.functional .fp-timeline{margin-right:180px}
+.no-mute.is-long.functional .fp-timeline{margin-right:140px}
+.has-menu.is-long.functional .fp-timeline{margin-right:292px}
+.no-brand.is-long.functional .fp-timeline{margin-right:190px;}
+.no-volume.no-brand.is-long.functional .fp-timeline{margin-right:125px}
+.no-mute.no-brand.is-long.functional .fp-timeline{margin-right:85px}
+.has-menu.no-brand.is-long.functional .fp-timeline{margin-right:227px}
+.is-rtl.is-long.functional .fp-timeline{margin:85px 0 190px 0;}
+.no-volume.is-rtl.is-long.functional .fp-timeline{margin-left:125px}
+.no-mute.is-rtl.is-long.functional .fp-timeline{margin-left:85px}
+.aside-time.functional .fp-timeline,.no-time.functional .fp-timeline{margin:0 190px 0 10px;}
+.has-menu.aside-time.functional .fp-timeline,.has-menu.no-time.functional .fp-timeline{margin-right:227px}
+.aside-time.no-brand.functional .fp-timeline{margin-right:115px}
+.aside-time.no-volume.functional .fp-timeline,.no-time.no-volume.functional .fp-timeline{margin-right:115px}
+.aside-time.no-mute.functional .fp-timeline,.no-time.no-mute.functional .fp-timeline{margin-right:75px}
+.is-rtl.aside-time.functional .fp-timeline,.is-rtl.no-time.functional .fp-timeline{margin:0 10px 0 115px}
+.is-rtl.aside-time.no-volume.functional .fp-timeline,.is-rtl.no-time.no-volume.functional .fp-timeline{margin-left:50px}
+.is-rtl.aside-time.no-mute.functional .fp-timeline,.is-rtl.no-time.no-mute.functional .fp-timeline{margin-left:10px}
+.functional .fp-buffer,.functional .fp-progress{position:absolute;top:0;left:auto;height:100%;cursor:col-resize}
+.functional .fp-buffer{-webkit-transition:width .25s linear;-moz-transition:width .25s linear;transition:width .25s linear}
+.functional .fp-timeline.no-animation .fp-buffer{-webkit-transition:none;-moz-transition:none;transition:none}
+.functional .fp-progress.animated{transition-timing-function:linear;transition-property:width,height}
+.functional.is-touch .fp-timeline{overflow:visible}
+.functional.is-touch .fp-progress{-webkit-transition:width .2s linear;-moz-transition:width .2s linear;transition:width .2s linear;box-sizing:border-box}
+.functional.is-touch .fp-timeline.is-dragging .fp-progress{-webkit-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;-moz-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear}
+.functional.is-touch.is-mouseover .fp-progress:after,.functional.is-touch.is-mouseover .fp-progress:before{content:'';box-sizing:border-box;display:block;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;position:absolute;right:-5px}
+.functional.is-touch.is-rtl.is-mouseover .fp-progress:after,.functional.is-touch.is-rtl.is-mouseover .fp-progress:before{right:auto;left:-5px}
+.functional.is-touch.is-rtl.is-mouseover .fp-progress:after{left:-10px;-webkit-box-shadow:-1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:-1px 0 4px rgba(0,0,0,0.5);box-shadow:-1px 0 4px rgba(0,0,0,0.5)}
+.functional.is-touch.is-mouseover .fp-progress:before{width:10px;height:10px}
+.functional.is-touch.is-mouseover .fp-progress:after{height:18px;width:18px;top:-4px;right:-10px;border:5px solid rgba(255,255,255,0.65);-webkit-box-shadow:1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:1px 0 4px rgba(0,0,0,0.5);box-shadow:1px 0 4px rgba(0,0,0,0.5)}
+.functional.is-touch.is-mouseover .fp-timeline.is-dragging .fp-progress:after{border:10px solid #fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px;-webkit-transition:inherit;-moz-transition:inherit;transition:inherit;top:-5px;right:-10px}
+.functional.is-touch.is-rtl.is-mouseover .fp-timeline.is-dragging .fp-progress:after{left:-15px;right:auto;border:10px solid #fff}
+.functional .fp-volume{position:absolute;top:12px;right:10px;}
+.has-menu.functional .fp-volume{right:37px}
+.is-rtl.functional .fp-volume{right:auto;left:10px}
+.is-rtl.has-menu.functional .fp-volume{left:37px}
+.functional .fp-mute{position:relative;width:30px;height:30px;float:left;top:-12px;cursor:pointer;}
+.is-rtl.functional .fp-mute{float:right}
+.no-mute.functional .fp-mute{display:none}
+.functional .fp-volumeslider{width:75px;height:6px;cursor:col-resize;float:left;}
+.is-rtl.functional .fp-volumeslider{float:right}
+.no-volume.functional .fp-volumeslider{display:none}
+.functional .fp-volumelevel{height:100%}
+.functional .fp-time{text-shadow:0 0 1px #000;font-size:11px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;color:#fff;width:100%;}
+.functional .fp-time.is-inverted .fp-duration{display:none}
+.functional .fp-time.is-inverted .fp-remaining{display:inline}
+.functional .fp-time em{width:35px;height:10px;line-height:10px;text-align:center;position:absolute;bottom:9px}
+.no-time.functional .fp-time{display:none}
+.is-long.functional .fp-time em{width:65px}
+.functional .fp-elapsed{left:10px;}
+.is-rtl.functional .fp-elapsed{left:auto;right:10px}
+.functional .fp-remaining,.functional .fp-duration{right:180px;color:#eee;}
+.no-brand.functional .fp-remaining,.no-brand.functional .fp-duration{right:125px;}
+.has-menu.no-brand.functional .fp-remaining,.has-menu.no-brand.functional .fp-duration{right:152px}
+.no-volume.no-brand.functional .fp-remaining,.no-volume.no-brand.functional .fp-duration{right:50px}
+.no-mute.no-brand.functional .fp-remaining,.no-mute.no-brand.functional .fp-duration{right:95px}
+.no-mute.no-volume.no-brand.functional .fp-remaining,.no-mute.no-volume.no-brand.functional .fp-duration{right:10px}
+.has-menu.functional .fp-remaining,.has-menu.functional .fp-duration{right:217px}
+.no-volume.functional .fp-remaining,.no-volume.functional .fp-duration{right:115px}
+.no-mute.functional .fp-remaining,.no-mute.functional .fp-duration{right:160px}
+.no-mute.no-volume.functional .fp-remaining,.no-mute.no-volume.functional .fp-duration{right:75px;}
+.has-menu.no-mute.no-volume.functional .fp-remaining,.has-menu.no-mute.no-volume.functional .fp-duration{right:112px}
+.is-rtl.functional .fp-remaining,.is-rtl.functional .fp-duration{right:auto;left:180px;}
+.no-brand.is-rtl.functional .fp-remaining,.no-brand.is-rtl.functional .fp-duration{left:115px;}
+.has-menu.no-brand.is-rtl.functional .fp-remaining,.has-menu.no-brand.is-rtl.functional .fp-duration{left:142px}
+.has-menu.is-rtl.functional .fp-remaining,.has-menu.is-rtl.functional .fp-duration{left:207px}
+.no-volume.is-rtl.functional .fp-remaining,.no-volume.is-rtl.functional .fp-duration{left:50px}
+.no-mute.is-rtl.functional .fp-remaining,.no-mute.is-rtl.functional .fp-duration{left:95px}
+.no-mute.no-volume.is-rtl.functional .fp-remaining,.no-mute.no-volume.is-rtl.functional .fp-duration{left:10px}
+.functional .fp-remaining{display:none}
+.functional.aside-time .fp-time{position:absolute;top:10px;left:10px;bottom:auto !important;width:auto;background-color:#000;background-color:rgba(0,0,0,0.65);height:30px;padding:0 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;line-height:30px;text-align:center;font-size:15px;}
+.no-background.functional.aside-time .fp-time{background-color:transparent !important}
+.functional.aside-time .fp-time strong,.functional.aside-time .fp-time em{position:static}
+.functional.aside-time .fp-time .fp-elapsed::after{content:' / '}
+.functional.is-splash,.functional.is-poster{cursor:pointer;}
+.functional.is-splash .fp-controls,.functional.is-poster .fp-controls,.functional.is-splash .fp-fullscreen,.functional.is-poster .fp-fullscreen,.functional.is-splash .fp-unload,.functional.is-poster .fp-unload,.functional.is-splash .fp-time,.functional.is-poster .fp-time,.functional.is-splash .fp-embed,.functional.is-poster .fp-embed,.functional.is-splash .fp-title,.functional.is-poster .fp-title,.functional.is-splash .fp-brand,.functional.is-poster .fp-brand{display:none !important}
+.functional.is-poster .fp-engine{top:-9999em}
+.functional.is-loading .fp-waiting{display:block}
+.functional.is-loading .fp-controls,.functional.is-loading .fp-time{display:none}
+.functional.is-loading .fp-ui{background-position:-9999em}
+.functional.is-loading video.fp-engine{position:absolute;top:-9999em}
+.functional.is-seeking .fp-waiting{display:block}
+.functional.is-playing{background-image:none !important;background-color:#333;}
+.functional.is-playing.hls-fix.is-finished .fp-engine{position:absolute;top:-9999em}
+.functional.is-fullscreen{top:0 !important;left:0 !important;border:0 !important;margin:0 !important;width:100% !important;height:100% !important;max-width:100% !important;z-index:99999 !important;-webkit-box-shadow:0 !important;-moz-box-shadow:0 !important;box-shadow:0 !important;background-image:none !important;background-color:#333;}
+.is-rtl.functional.is-fullscreen{left:auto !important;right:0 !important}
+.functional.is-fullscreen .fp-player{background-color:#333}
+.functional.is-error{border:1px solid #909090;background:#fdfdfd !important;}
+.functional.is-error h2{font-weight:bold;font-size:large;margin-top:10%}
+.functional.is-error .fp-message{display:block}
+.functional.is-error object,.functional.is-error video,.functional.is-error .fp-controls,.functional.is-error .fp-time,.functional.is-error .fp-subtitle{display:none}
+.functional.is-ready.is-muted .fp-mute{opacity:.7;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70)}
+.functional.is-ready.is-muted .fp-mute:before{content:"\e605"}
+.functional.is-mouseout .fp-controls,.functional.is-mouseout .fp-title{height:0;-webkit-transition:height .15s .3s;-moz-transition:height .15s .3s;transition:height .15s .3s}
+.is-fullscreen.functional.is-mouseout .fp-controls{height:3px;bottom:0}
+.functional.is-mouseout .fp-title{overflow:hidden}
+.functional.is-mouseout .fp-timeline{margin:0 !important}
+.functional.is-mouseout .fp-timeline{-webkit-transition:height .15s .3s,top .15s .3s,margin .15s .3s;-moz-transition:height .15s .3s,top .15s .3s,margin .15s .3s;transition:height .15s .3s,top .15s .3s,margin .15s .3s;height:4px;top:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
+.functional.is-mouseout .fp-fullscreen,.functional.is-mouseout .fp-unload,.functional.is-mouseout .fp-elapsed,.functional.is-mouseout .fp-remaining,.functional.is-mouseout .fp-duration,.functional.is-mouseout .fp-embed,.functional.is-mouseout .fp-volume,.functional.is-mouseout .fp-play,.functional.is-mouseout .fp-menu,.functional.is-mouseout .fp-brand,.functional.is-mouseout .fp-timeline-tooltip,.functional.is-mouseout.aside-time .fp-time{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .15s .3s;-moz-transition:opacity .15s .3s;transition:opacity .15s .3s}
+.functional.is-mouseover .fp-controls,.functional.fixed-controls .fp-controls{height:30px}
+.functional.is-mouseover .fp-title,.functional.fixed-controls .fp-title{height:30px}
+.functional.is-mouseover .fp-fullscreen,.functional.fixed-controls .fp-fullscreen,.functional.is-mouseover .fp-unload,.functional.fixed-controls .fp-unload,.functional.is-mouseover .fp-elapsed,.functional.fixed-controls .fp-elapsed,.functional.is-mouseover .fp-remaining,.functional.fixed-controls .fp-remaining,.functional.is-mouseover .fp-duration,.functional.fixed-controls .fp-duration,.functional.is-mouseover .fp-embed,.functional.fixed-controls .fp-embed,.functional.is-mouseover .fp-logo,.functional.fixed-controls .fp-logo,.functional.is-mouseover .fp-volume,.functional.fixed-controls .fp-volume,.functional.is-mouseover .fp-play,.functional.fixed-controls .fp-play,.functional.is-mouseover .fp-menu,.functional.fixed-controls .fp-menu{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.functional.fixed-controls .fp-volume{display:block}
+.functional.fixed-controls .fp-controls{bottom:-30px;}
+.is-fullscreen.functional.fixed-controls .fp-controls{bottom:0}
+.functional.fixed-controls .fp-time em{bottom:-20px;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);}
+.is-fullscreen.functional.fixed-controls .fp-time em{bottom:10px}
+.functional.is-disabled .fp-progress{background-color:#999}
+.functional.is-flash-disabled{background-color:#333;}
+.functional.is-flash-disabled object.fp-engine{z-index:100}
+.functional.is-flash-disabled .fp-flash-disabled{display:block;z-index:101}
+.functional .fp-embed{position:absolute;top:10px;left:auto;right:50px;display:block;width:30px;height:30px;text-align:center;}
+.is-rtl.functional .fp-embed{right:auto;left:50px}
+.functional .fp-embed-code{position:absolute;display:none;top:10px;right:67px;background-color:#333;padding:3px 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 3px #ccc;-moz-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc;font-size:12px;}
+.is-closeable.functional .fp-embed-code{right:99px}
+.functional .fp-embed-code:before{content:'';width:0;height:0;position:absolute;top:2px;right:-10px;border:5px solid transparent;border-left-color:#333}
+.is-rtl.functional .fp-embed-code{right:auto;left:67px;}
+.is-rtl.functional .fp-embed-code:before{right:auto;left:-10px;border-left-color:transparent;border-right-color:#333}
+.functional .fp-embed-code textarea{width:400px;height:16px;font-family:monaco,"courier new",verdana;color:#777;white-space:nowrap;resize:none;overflow:hidden;border:0;outline:0;background-color:transparent;color:#ccc}
+.functional .fp-embed-code label{display:block;color:#999}
+.functional.is-embedding .fp-embed,.functional.is-embedding .fp-embed-code{display:block;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.functional.no-time .fp-embed{left:10px !important;}
+.is-rtl.functional.no-time .fp-embed{left:auto;right:10px !important}
+.functional.is-live .fp-timeline,.functional.is-live .fp-duration,.functional.is-live .fp-remaining{display:none}
+.functional .fp-context-menu{position:absolute;display:none;z-index:1001;background-color:#fff;padding:10px;border:1px solid #aaa;-webkit-box-shadow:0 0 4px #888;-moz-box-shadow:0 0 4px #888;box-shadow:0 0 4px #888;width:170px;}
+.functional .fp-context-menu li{text-align:center !important;padding:10px;color:#444 !important;font-size:11px !important;margin:0 -10px 0 -10px;}
+.functional .fp-context-menu li a{color:#00a7c8 !important;font-size:12.100000000000001px !important}
+.functional .fp-context-menu li:hover:not(.copyright){background-color:#eee}
+.functional .fp-context-menu li.copyright{margin:0;padding-left:110px;background-image:url("img/flowplayer.png");background-repeat:no-repeat;background-size:100px 20px;background-position:5px 5px;border-bottom:1px solid #bbb;}
+@media (-webkit-min-device-pixel-ratio: 2){.functional .fp-context-menu li.copyright{background-image:url("img/flowplayer@2x.png")}
+}@-moz-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-webkit-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-o-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-ms-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}.functional.is-touch.is-mouseover .fp-progress:before{background-color:#00a7c8}
+.functional .fp-title{position:absolute;top:10px;left:10px;}
+.is-rtl.functional .fp-title{left:auto;right:10px}
+.functional .fp-title,.functional .fp-unload,.functional .fp-fullscreen,.functional .fp-embed{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.functional .fp-embed-code{right:85px;}
+.is-closeable.functional .fp-embed-code{right:125px}
+.is-rtl.functional .fp-embed-code{right:auto;left:85px}
+.functional.is-mouseout .fp-menu{display:none}
+.functional.is-mouseout .fp-controls{-webkit-transition:none;-moz-transition:none;transition:none;-webkit-animation:functional-controls-hide 1s 1;-moz-animation:functional-controls-hide 1s 1;animation:functional-controls-hide 1s 1}
+.functional.is-mouseout .fp-timeline{-webkit-transition:none;-moz-transition:none;transition:none}
+.functional.is-mouseout .fp-volume,.functional.is-mouseout .fp-brand,.functional.is-mouseout .fp-play,.functional.is-mouseout .fp-time{-webkit-transition:none;-moz-transition:none;transition:none;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+.functional.fixed-controls .fp-elapsed,.functional.fixed-controls.is-mouseover .fp-elapsed{left:50px}
+.functional.fixed-controls .fp-controls,.functional.fixed-controls.is-mouseover .fp-controls{bottom:-30px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;left:0;right:0;}
+.is-fullscreen.functional.fixed-controls .fp-controls,.is-fullscreen.functional.fixed-controls.is-mouseover .fp-controls{bottom:0}
+.functional.fixed-controls .fp-controls .fp-play,.functional.fixed-controls.is-mouseover .fp-controls .fp-play{left:10px}
+.functional.fixed-controls .fp-controls .fp-timeline,.functional.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:95px;}
+.is-long.functional.fixed-controls .fp-controls .fp-timeline,.is-long.functional.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:125px}
+.functional.is-mouseover .fp-controls{bottom:10px;left:50px;right:10px;width:auto;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.functional.is-mouseover .fp-controls{left:10px;right:50px}
+.functional.is-mouseover .fp-controls .fp-play{left:-40px;display:block;background-color:#000;background-color:rgba(0,0,0,0.65);width:30px;height:30px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.functional.is-mouseover .fp-controls .fp-play{left:auto;right:-40px}
+.functional.is-mouseover .fp-controls .fp-timeline{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.functional.is-mouseover .fp-controls .fp-timeline .fp-progress,.functional.is-mouseover .fp-controls .fp-timeline .fp-buffer{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.functional.is-mouseover .fp-controls .fp-menu .fp-dropdown{bottom:35px;left:auto;right:-10px;}
+.is-rtl.functional.is-mouseover .fp-controls .fp-menu .fp-dropdown{right:auto;left:-10px}
+.functional.is-mouseover .fp-controls .fp-menu .fp-dropdown:before{display:none}
+.functional.is-mouseover .fp-controls li{border-color:#000;}
+.functional.is-mouseover .fp-controls li.active{border-color:#00a7c8}
+.functional.is-mouseover .fp-controls li:last-child:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;right:10px;border-bottom:none;border-top-width:5px;border-top-style:solid;border-top-color:inherit;border-left:5px solid transparent;border-right:5px solid transparent;}
+.is-rtl.functional.is-mouseover .fp-controls li:last-child:before{right:auto;left:10px}
+.functional .fp-elapsed,.functional.play-button .fp-elapsed{left:60px;}
+.is-rtl.functional .fp-elapsed,.is-rtl.functional.play-button .fp-elapsed{right:60px;left:auto}
+.functional .fp-time em{bottom:19px}
+@-moz-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-webkit-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-o-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-ms-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}
+@font-face {
+ font-family: 'fpicons';
+ src:url('fonts/fpicons.eot?yg5dv7');
+ src:url('fonts/fpicons.eot?#iefixyg5dv7') format('embedded-opentype'),
+ url('fonts/fpicons.woff?yg5dv7') format('woff'),
+ url('fonts/fpicons.ttf?yg5dv7') format('truetype'),
+ url('fonts/fpicons.svg?yg5dv7#fpicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="fp-i-"], [class*=" fp-i-"] {
+ font-family: 'fpicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.playful{position:relative;width:100%;counter-increment:flowplayer;background-size:contain;background-repeat:no-repeat;background-position:center center;display:inline-block;}
+.playful *{font-weight:inherit;font-family:inherit;font-style:inherit;text-decoration:inherit;font-size:100%;padding:0;border:0;margin:0;list-style-type:none}
+.playful a:focus{outline:0}
+.playful video{width:100%}
+.playful.is-ipad video{-webkit-transform:translateX(-2048px);}
+.is-ready.playful.is-ipad video{-webkit-transform:translateX(0)}
+.playful .fp-player{position:absolute;top:0;left:0;width:100%;height:100%}
+.playful .fp-engine,.playful .fp-ui,.playful .fp-message{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;z-index:1}
+.playful .fp-ui{z-index:11}
+.playful .fp-message{display:none;text-align:center;padding-top:5%;cursor:default;}
+.playful .fp-message h2{font-size:120%;margin-bottom:1em}
+.playful .fp-message p{color:#666;font-size:95%}
+.playful .fp-title{line-height:35px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif;font-size:11px;cursor:default;color:#fff;width:auto;max-width:50%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;float:left;padding:0 24px;}
+.is-rtl.playful .fp-title{float:right}
+.aside-time.playful .fp-title{display:none !important}
+.playful .fp-controls{position:absolute;bottom:0;width:100%;}
+.no-background.playful .fp-controls{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important}
+.is-fullscreen.playful .fp-controls{bottom:3px}
+.is-mouseover.playful .fp-controls{bottom:0}
+.playful .fp-controls,.playful .fp-title,.playful .fp-fullscreen,.playful .fp-unload,.playful .fp-close,.playful .fp-embed,.playful.aside-time .fp-time{background-color:#000;background-color:rgba(0,0,0,0.65);}
+.no-background.playful .fp-controls,.no-background.playful .fp-title,.no-background.playful .fp-fullscreen,.no-background.playful .fp-unload,.no-background.playful .fp-close,.no-background.playful .fp-embed,.no-background.playful.aside-time .fp-time{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.no-background.playful .fp-play,.no-background.playful .fp-brand{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.playful.fixed-controls .fp-controls{background-color:#000}
+.playful .fp-timeline{background-color:#a5a5a5}
+.playful .fp-buffer{background-color:#eee}
+.playful .fp-progress{background-color:#00a7c8}
+.playful .fp-volumeslider{background-color:#a5a5a5}
+.playful .fp-volumelevel{background-color:#00a7c8}
+.playful .fp-waiting{display:none;margin:19% auto;text-align:center;}
+.playful .fp-waiting *{-webkit-box-shadow:0 0 5px #333;-moz-box-shadow:0 0 5px #333;box-shadow:0 0 5px #333}
+.playful .fp-waiting em{width:1em;height:1em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;background-color:rgba(255,255,255,0.8);display:inline-block;-webkit-animation:pulse .6s infinite;-moz-animation:pulse .6s infinite;animation:pulse .6s infinite;margin:.3em;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);}
+.playful .fp-waiting em:nth-child(1){-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s}
+.playful .fp-waiting em:nth-child(2){-webkit-animation-delay:.45s;-moz-animation-delay:.45s;animation-delay:.45s}
+.playful .fp-waiting em:nth-child(3){-webkit-animation-delay:.6s;-moz-animation-delay:.6s;animation-delay:.6s}
+.playful .fp-waiting p{color:#ccc;font-weight:bold}
+.playful .fp-speed{font-size:30px;background-color:#333;background-color:rgba(51,51,51,0.8);color:#eee;margin:0 auto;text-align:center;width:120px;padding:.1em 0 0;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .5s;-moz-transition:opacity .5s;transition:opacity .5s;}
+.playful .fp-speed.fp-hilite{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.playful .fp-help{position:absolute;top:0;left:-9999em;z-index:100;background-color:#333;background-color:rgba(51,51,51,0.9);width:100%;height:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s;text-align:center;}
+.is-help.playful .fp-help{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.playful .fp-help .fp-help-section{margin:3%;direction:ltr}
+.playful .fp-help .fp-help-basics{margin-top:6%}
+.playful .fp-help p{color:#eee;margin:.5em 0;font-size:14px;line-height:1.5;display:inline-block;margin:1% 2%}
+.playful .fp-help em{background:#eee;-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;margin-right:.4em;padding:.3em .6em;color:#333}
+.playful .fp-help small{font-size:90%;color:#aaa}
+.playful .fp-help .fp-close{display:block}
+@media (max-width: 600px){.playful .fp-help p{font-size:9px}
+}.playful .fp-dropdown{position:absolute;top:5px;width:100px;background-color:#000 !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;margin:0 !important;list-style-type:none !important;}
+.playful .fp-dropdown:before{content:'';display:block;position:absolute;top:-5px;left:calc(50% - 5px);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid rgba(51,51,51,0.9)}
+.playful .fp-dropdown li{padding:12px !important;margin:0 !important;color:#fff !important;font-size:11px !important;list-style-type:none !important;}
+.playful .fp-dropdown li.active{background-color:#00a7c8 !important;cursor:default !important}
+.playful .fp-dropdown.fp-dropup{bottom:20px;top:auto;}
+.playful .fp-dropdown.fp-dropup:before{top:auto;bottom:-5px;border-bottom:none;border-top:5px solid rgba(51,51,51,0.9)}
+.playful .fp-tooltip{background-color:#000;color:#fff;display:none;position:absolute;padding:5px;}
+.playful .fp-tooltip:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;left:calc(50% - 5px);border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000}
+.playful .fp-timeline-tooltip{bottom:41px}
+.playful .fp-timeline:hover+.fp-timeline-tooltip{display:block}
+.playful .fp-subtitle{position:absolute;bottom:40px;left:-99999em;z-index:10;text-align:center;width:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .3s;-moz-transition:opacity .3s;transition:opacity .3s;}
+.playful .fp-subtitle p{display:inline;background-color:#333;background-color:rgba(51,51,51,0.9);color:#eee;padding:.1em .4em;font-size:16px;line-height:1.6;}
+.playful .fp-subtitle p:after{content:'';clear:both}
+.playful .fp-subtitle p b{font-weight:bold}
+.playful .fp-subtitle p i{font-style:italic}
+.playful .fp-subtitle p u{text-decoration:underline}
+.playful .fp-subtitle.fp-active{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.playful .fp-fullscreen,.playful .fp-unload,.playful .fp-mute,.playful .fp-embed,.playful .fp-close,.playful .fp-play,.playful .fp-menu{font-family:'fpicons' !important;color:#fff !important;font-size:15px !important;text-align:center !important;line-height:30px !important;text-decoration:none !important;}
+.is-rtl.playful .fp-fullscreen,.is-rtl.playful .fp-unload,.is-rtl.playful .fp-mute,.is-rtl.playful .fp-embed,.is-rtl.playful .fp-close,.is-rtl.playful .fp-play,.is-rtl.playful .fp-menu{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);transform:scale(-1,1)}
+.is-rtl.playful .fp-menu{-webkit-transform:none;-moz-transform:none;transform:none}
+.playful .fp-fullscreen:before{content:"\e602"}
+.playful .fp-unload:before,.playful .fp-close:before{content:"\e600"}
+.playful .fp-mute:before{content:"\e606"}
+.playful .fp-embed:before{content:"\e603"}
+.playful .fp-play:before{content:"\e608"}
+.playful .fp-menu:before{content:"\e604"}
+.playful .fp-flash-disabled{background:#333;width:390px;margin:0 auto;position:absolute;bottom:0;color:#fff}
+.is-splash.playful .fp-ui,.is-paused.playful .fp-ui{background:url(img/play_white.png) center no-repeat;background-size:11%;}
+.is-rtl.is-splash.playful .fp-ui,.is-rtl.is-paused.playful .fp-ui{background:url(img/play_white_rtl.png) center no-repeat;background-size:11%}
+@media (-webkit-min-device-pixel-ratio: 2){.is-splash.playful .fp-ui,.is-paused.playful .fp-ui{background:url(img/play_white@x2.png) center no-repeat;background-size:11%}
+.is-rtl.is-splash.playful .fp-ui,.is-rtl.is-paused.playful .fp-ui{background:url(img/play_white_rtl@x2.png) center no-repeat;background-size:11%}
+}.is-fullscreen.playful .fp-ui{background-size:auto}
+.is-seeking.playful .fp-ui,.is-loading.playful .fp-ui{background-image:none}
+.playful .fp-brand{color:#fff !important;position:absolute;right:124px;font-weight:normal !important;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;text-decoration:none !important;line-height:15px !important;font-size:11px !important;height:15px;width:55px;bottom:11px;box-sizing:border-box;text-align:center;padding:1px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
+.has-menu.playful .fp-brand{right:161px}
+.is-rtl.playful .fp-brand{right:auto;left:134px}
+.has-menu.is-rtl.playful .fp-brand{left:161px}
+.no-brand.playful .fp-brand{display:none}
+.no-volume.no-mute.playful .fp-brand{right:12px;}
+.has-menu.no-volume.no-mute.playful .fp-brand{right:51px}
+.no-volume.playful .fp-brand{right:62px}
+.no-mute.playful .fp-brand{right:99px}
+.playful .fp-logo{position:absolute;top:auto;left:15px;bottom:45px;cursor:pointer;display:none;z-index:100;}
+.playful .fp-logo img{width:100%}
+.is-embedded.playful .fp-logo{display:block}
+.fixed-controls.playful .fp-logo{bottom:15px}
+.playful .fp-fullscreen,.playful .fp-unload,.playful .fp-close{position:absolute;top:12px;left:auto;right:12px;display:block;width:30px;height:23px;text-align:center;cursor:pointer;height:35px;width:35px;}
+.is-rtl.playful .fp-fullscreen,.is-rtl.playful .fp-unload,.is-rtl.playful .fp-close{right:auto;left:12px}
+.playful .fp-unload,.playful .fp-close{display:none}
+.playful .fp-play{display:none;height:35px !important;position:absolute;bottom:0;left:0;text-align:center;}
+.is-rtl.playful .fp-play{left:auto;right:0}
+.is-playing.playful .fp-play:before{content:"\e607"}
+.playful .fp-menu{display:none;position:absolute;bottom:0;z-index:11;right:12px;}
+.is-rtl.playful .fp-menu{right:auto;left:12px}
+.has-menu.playful .fp-menu{display:block}
+.playful .fp-menu .fp-dropdown{z-index:12;display:none;left:-42.5px;line-height:auto;width:153px;-webkit-transform:none;-moz-transform:none;transform:none;}
+.is-rtl.playful .fp-menu .fp-dropdown{left:-12px}
+.playful .fp-menu.dropdown-open .fp-dropdown{display:block}
+.playful.is-ready.is-closeable .fp-unload{display:block}
+.playful.is-ready.is-closeable .fp-embed{right:106px}
+.playful.is-ready.is-closeable .fp-fullscreen{right:59px}
+.playful.is-fullscreen .fp-fullscreen{display:block !important;}
+.playful.is-fullscreen .fp-fullscreen:before{content:"\e601"}
+.playful .fp-timeline{height:3px;position:relative;overflow:hidden;top:12px;height:11px;margin:0 238px 0 59px;}
+.no-brand.playful .fp-timeline{margin-right:171px;}
+.has-menu.no-brand.playful .fp-timeline{margin-right:198px}
+.no-volume.no-brand.playful .fp-timeline{margin-right:109px}
+.no-mute.no-brand.playful .fp-timeline{margin-right:133px}
+.no-mute.no-volume.no-brand.playful .fp-timeline{margin-right:59px}
+.has-menu.playful .fp-timeline{margin-right:265px}
+.no-volume.playful .fp-timeline{margin-right:176px}
+.no-mute.playful .fp-timeline{margin-right:200px}
+.no-mute.no-volume.playful .fp-timeline{margin-right:126px;}
+.has-menu.no-mute.no-volume.playful .fp-timeline{margin-right:165px}
+.is-rtl.playful .fp-timeline{margin:0 59px 0 238px;}
+.no-brand.is-rtl.playful .fp-timeline{margin-left:171px;}
+.has-menu.no-brand.is-rtl.playful .fp-timeline{margin-left:210px}
+.has-menu.is-rtl.playful .fp-timeline{margin-left:277px}
+.no-volume.is-rtl.playful .fp-timeline{margin-left:109px}
+.no-mute.is-rtl.playful .fp-timeline{margin-left:133px}
+.no-mute.no-volume.is-rtl.playful .fp-timeline{margin-left:59px}
+.is-long.playful .fp-timeline{margin:0 268px 0 89px;}
+.no-volume.is-long.playful .fp-timeline{margin-right:194px}
+.no-mute.is-long.playful .fp-timeline{margin-right:144px}
+.has-menu.is-long.playful .fp-timeline{margin-right:307px}
+.no-brand.is-long.playful .fp-timeline{margin-right:201px;}
+.no-volume.no-brand.is-long.playful .fp-timeline{margin-right:139px}
+.no-mute.no-brand.is-long.playful .fp-timeline{margin-right:89px}
+.has-menu.no-brand.is-long.playful .fp-timeline{margin-right:240px}
+.is-rtl.is-long.playful .fp-timeline{margin:89px 0 201px 0;}
+.no-volume.is-rtl.is-long.playful .fp-timeline{margin-left:139px}
+.no-mute.is-rtl.is-long.playful .fp-timeline{margin-left:89px}
+.aside-time.playful .fp-timeline,.no-time.playful .fp-timeline{margin:0 203px 0 12px;}
+.has-menu.aside-time.playful .fp-timeline,.has-menu.no-time.playful .fp-timeline{margin-right:242px}
+.aside-time.no-brand.playful .fp-timeline{margin-right:124px}
+.aside-time.no-volume.playful .fp-timeline,.no-time.no-volume.playful .fp-timeline{margin-right:129px}
+.aside-time.no-mute.playful .fp-timeline,.no-time.no-mute.playful .fp-timeline{margin-right:79px}
+.is-rtl.aside-time.playful .fp-timeline,.is-rtl.no-time.playful .fp-timeline{margin:0 12px 0 124px}
+.is-rtl.aside-time.no-volume.playful .fp-timeline,.is-rtl.no-time.no-volume.playful .fp-timeline{margin-left:62px}
+.is-rtl.aside-time.no-mute.playful .fp-timeline,.is-rtl.no-time.no-mute.playful .fp-timeline{margin-left:12px}
+.playful .fp-buffer,.playful .fp-progress{position:absolute;top:0;left:auto;height:100%;cursor:col-resize}
+.playful .fp-buffer{-webkit-transition:width .25s linear;-moz-transition:width .25s linear;transition:width .25s linear}
+.playful .fp-timeline.no-animation .fp-buffer{-webkit-transition:none;-moz-transition:none;transition:none}
+.playful .fp-progress.animated{transition-timing-function:linear;transition-property:width,height}
+.playful.is-touch .fp-timeline{overflow:visible}
+.playful.is-touch .fp-progress{-webkit-transition:width .2s linear;-moz-transition:width .2s linear;transition:width .2s linear;box-sizing:border-box}
+.playful.is-touch .fp-timeline.is-dragging .fp-progress{-webkit-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;-moz-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear}
+.playful.is-touch.is-mouseover .fp-progress:after,.playful.is-touch.is-mouseover .fp-progress:before{content:'';box-sizing:border-box;display:block;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;position:absolute;right:-5px}
+.playful.is-touch.is-rtl.is-mouseover .fp-progress:after,.playful.is-touch.is-rtl.is-mouseover .fp-progress:before{right:auto;left:-5px}
+.playful.is-touch.is-rtl.is-mouseover .fp-progress:after{left:-10px;-webkit-box-shadow:-1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:-1px 0 4px rgba(0,0,0,0.5);box-shadow:-1px 0 4px rgba(0,0,0,0.5)}
+.playful.is-touch.is-mouseover .fp-progress:before{width:10px;height:10px}
+.playful.is-touch.is-mouseover .fp-progress:after{height:18px;width:18px;top:-4px;right:-10px;border:5px solid rgba(255,255,255,0.65);-webkit-box-shadow:1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:1px 0 4px rgba(0,0,0,0.5);box-shadow:1px 0 4px rgba(0,0,0,0.5)}
+.playful.is-touch.is-mouseover .fp-timeline.is-dragging .fp-progress:after{border:10px solid #fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px;-webkit-transition:inherit;-moz-transition:inherit;transition:inherit;top:-5px;right:-10px}
+.playful.is-touch.is-rtl.is-mouseover .fp-timeline.is-dragging .fp-progress:after{left:-15px;right:auto;border:10px solid #fff}
+.playful .fp-volume{position:absolute;top:12px;right:12px;}
+.has-menu.playful .fp-volume{right:39px}
+.is-rtl.playful .fp-volume{right:auto;left:12px}
+.is-rtl.has-menu.playful .fp-volume{left:39px}
+.playful .fp-mute{position:relative;width:38px;height:20px;float:left;top:-4.5px;cursor:pointer;}
+.is-rtl.playful .fp-mute{float:right}
+.no-mute.playful .fp-mute{display:none}
+.playful .fp-volumeslider{width:75px;height:11px;cursor:col-resize;float:left;}
+.is-rtl.playful .fp-volumeslider{float:right}
+.no-volume.playful .fp-volumeslider{display:none}
+.playful .fp-volumelevel{height:100%}
+.playful .fp-time{text-shadow:0 0 1px #000;font-size:11px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;color:#fff;width:100%;}
+.playful .fp-time.is-inverted .fp-duration{display:none}
+.playful .fp-time.is-inverted .fp-remaining{display:inline}
+.playful .fp-time em{width:35px;height:11px;line-height:11px;text-align:center;position:absolute;bottom:11px}
+.no-time.playful .fp-time{display:none}
+.is-long.playful .fp-time em{width:65px}
+.playful .fp-elapsed{left:12px;}
+.is-rtl.playful .fp-elapsed{left:auto;right:12px}
+.playful .fp-remaining,.playful .fp-duration{right:191px;color:#eee;}
+.no-brand.playful .fp-remaining,.no-brand.playful .fp-duration{right:136px;}
+.has-menu.no-brand.playful .fp-remaining,.has-menu.no-brand.playful .fp-duration{right:163px}
+.no-volume.no-brand.playful .fp-remaining,.no-volume.no-brand.playful .fp-duration{right:62px}
+.no-mute.no-brand.playful .fp-remaining,.no-mute.no-brand.playful .fp-duration{right:99px}
+.no-mute.no-volume.no-brand.playful .fp-remaining,.no-mute.no-volume.no-brand.playful .fp-duration{right:12px}
+.has-menu.playful .fp-remaining,.has-menu.playful .fp-duration{right:230px}
+.no-volume.playful .fp-remaining,.no-volume.playful .fp-duration{right:129px}
+.no-mute.playful .fp-remaining,.no-mute.playful .fp-duration{right:166px}
+.no-mute.no-volume.playful .fp-remaining,.no-mute.no-volume.playful .fp-duration{right:79px;}
+.has-menu.no-mute.no-volume.playful .fp-remaining,.has-menu.no-mute.no-volume.playful .fp-duration{right:118px}
+.is-rtl.playful .fp-remaining,.is-rtl.playful .fp-duration{right:auto;left:191px;}
+.no-brand.is-rtl.playful .fp-remaining,.no-brand.is-rtl.playful .fp-duration{left:124px;}
+.has-menu.no-brand.is-rtl.playful .fp-remaining,.has-menu.no-brand.is-rtl.playful .fp-duration{left:151px}
+.has-menu.is-rtl.playful .fp-remaining,.has-menu.is-rtl.playful .fp-duration{left:218px}
+.no-volume.is-rtl.playful .fp-remaining,.no-volume.is-rtl.playful .fp-duration{left:62px}
+.no-mute.is-rtl.playful .fp-remaining,.no-mute.is-rtl.playful .fp-duration{left:99px}
+.no-mute.no-volume.is-rtl.playful .fp-remaining,.no-mute.no-volume.is-rtl.playful .fp-duration{left:12px}
+.playful .fp-remaining{display:none}
+.playful.aside-time .fp-time{position:absolute;top:12px;left:12px;bottom:auto !important;width:auto;background-color:#000;background-color:rgba(0,0,0,0.65);height:35px;padding:0 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;line-height:35px;text-align:center;font-size:15px;}
+.no-background.playful.aside-time .fp-time{background-color:transparent !important}
+.playful.aside-time .fp-time strong,.playful.aside-time .fp-time em{position:static}
+.playful.aside-time .fp-time .fp-elapsed::after{content:' / '}
+.playful.is-splash,.playful.is-poster{cursor:pointer;}
+.playful.is-splash .fp-controls,.playful.is-poster .fp-controls,.playful.is-splash .fp-fullscreen,.playful.is-poster .fp-fullscreen,.playful.is-splash .fp-unload,.playful.is-poster .fp-unload,.playful.is-splash .fp-time,.playful.is-poster .fp-time,.playful.is-splash .fp-embed,.playful.is-poster .fp-embed,.playful.is-splash .fp-title,.playful.is-poster .fp-title,.playful.is-splash .fp-brand,.playful.is-poster .fp-brand{display:none !important}
+.playful.is-poster .fp-engine{top:-9999em}
+.playful.is-loading .fp-waiting{display:block}
+.playful.is-loading .fp-controls,.playful.is-loading .fp-time{display:none}
+.playful.is-loading .fp-ui{background-position:-9999em}
+.playful.is-loading video.fp-engine{position:absolute;top:-9999em}
+.playful.is-seeking .fp-waiting{display:block}
+.playful.is-playing{background-image:none !important;background-color:#333;}
+.playful.is-playing.hls-fix.is-finished .fp-engine{position:absolute;top:-9999em}
+.playful.is-fullscreen{top:0 !important;left:0 !important;border:0 !important;margin:0 !important;width:100% !important;height:100% !important;max-width:100% !important;z-index:99999 !important;-webkit-box-shadow:0 !important;-moz-box-shadow:0 !important;box-shadow:0 !important;background-image:none !important;background-color:#333;}
+.is-rtl.playful.is-fullscreen{left:auto !important;right:0 !important}
+.playful.is-fullscreen .fp-player{background-color:#333}
+.playful.is-error{border:1px solid #909090;background:#fdfdfd !important;}
+.playful.is-error h2{font-weight:bold;font-size:large;margin-top:10%}
+.playful.is-error .fp-message{display:block}
+.playful.is-error object,.playful.is-error video,.playful.is-error .fp-controls,.playful.is-error .fp-time,.playful.is-error .fp-subtitle{display:none}
+.playful.is-ready.is-muted .fp-mute{opacity:.7;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70)}
+.playful.is-ready.is-muted .fp-mute:before{content:"\e605"}
+.playful.is-mouseout .fp-controls,.playful.is-mouseout .fp-title{height:0;-webkit-transition:height .15s .3s;-moz-transition:height .15s .3s;transition:height .15s .3s}
+.is-fullscreen.playful.is-mouseout .fp-controls{height:3px;bottom:0}
+.playful.is-mouseout .fp-title{overflow:hidden}
+.playful.is-mouseout .fp-timeline{margin:0 !important}
+.playful.is-mouseout .fp-timeline{-webkit-transition:height .15s .3s,top .15s .3s,margin .15s .3s;-moz-transition:height .15s .3s,top .15s .3s,margin .15s .3s;transition:height .15s .3s,top .15s .3s,margin .15s .3s;height:4px;top:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
+.playful.is-mouseout .fp-fullscreen,.playful.is-mouseout .fp-unload,.playful.is-mouseout .fp-elapsed,.playful.is-mouseout .fp-remaining,.playful.is-mouseout .fp-duration,.playful.is-mouseout .fp-embed,.playful.is-mouseout .fp-volume,.playful.is-mouseout .fp-play,.playful.is-mouseout .fp-menu,.playful.is-mouseout .fp-brand,.playful.is-mouseout .fp-timeline-tooltip,.playful.is-mouseout.aside-time .fp-time{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .15s .3s;-moz-transition:opacity .15s .3s;transition:opacity .15s .3s}
+.playful.is-mouseover .fp-controls,.playful.fixed-controls .fp-controls{height:35px}
+.playful.is-mouseover .fp-title,.playful.fixed-controls .fp-title{height:35px}
+.playful.is-mouseover .fp-fullscreen,.playful.fixed-controls .fp-fullscreen,.playful.is-mouseover .fp-unload,.playful.fixed-controls .fp-unload,.playful.is-mouseover .fp-elapsed,.playful.fixed-controls .fp-elapsed,.playful.is-mouseover .fp-remaining,.playful.fixed-controls .fp-remaining,.playful.is-mouseover .fp-duration,.playful.fixed-controls .fp-duration,.playful.is-mouseover .fp-embed,.playful.fixed-controls .fp-embed,.playful.is-mouseover .fp-logo,.playful.fixed-controls .fp-logo,.playful.is-mouseover .fp-volume,.playful.fixed-controls .fp-volume,.playful.is-mouseover .fp-play,.playful.fixed-controls .fp-play,.playful.is-mouseover .fp-menu,.playful.fixed-controls .fp-menu{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.playful.fixed-controls .fp-volume{display:block}
+.playful.fixed-controls .fp-controls{bottom:-35px;}
+.is-fullscreen.playful.fixed-controls .fp-controls{bottom:0}
+.playful.fixed-controls .fp-time em{bottom:-23px;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);}
+.is-fullscreen.playful.fixed-controls .fp-time em{bottom:12px}
+.playful.is-disabled .fp-progress{background-color:#999}
+.playful.is-flash-disabled{background-color:#333;}
+.playful.is-flash-disabled object.fp-engine{z-index:100}
+.playful.is-flash-disabled .fp-flash-disabled{display:block;z-index:101}
+.playful .fp-embed{position:absolute;top:12px;left:auto;right:59px;display:block;width:35px;height:35px;text-align:center;}
+.is-rtl.playful .fp-embed{right:auto;left:59px}
+.playful .fp-embed-code{position:absolute;display:none;top:10px;right:77px;background-color:#333;padding:3px 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 3px #ccc;-moz-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc;font-size:12px;}
+.is-closeable.playful .fp-embed-code{right:114px}
+.playful .fp-embed-code:before{content:'';width:0;height:0;position:absolute;top:2px;right:-10px;border:5px solid transparent;border-left-color:#333}
+.is-rtl.playful .fp-embed-code{right:auto;left:77px;}
+.is-rtl.playful .fp-embed-code:before{right:auto;left:-10px;border-left-color:transparent;border-right-color:#333}
+.playful .fp-embed-code textarea{width:400px;height:16px;font-family:monaco,"courier new",verdana;color:#777;white-space:nowrap;resize:none;overflow:hidden;border:0;outline:0;background-color:transparent;color:#ccc}
+.playful .fp-embed-code label{display:block;color:#999}
+.playful.is-embedding .fp-embed,.playful.is-embedding .fp-embed-code{display:block;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.playful.no-time .fp-embed{left:12px !important;}
+.is-rtl.playful.no-time .fp-embed{left:auto;right:12px !important}
+.playful.is-live .fp-timeline,.playful.is-live .fp-duration,.playful.is-live .fp-remaining{display:none}
+.playful .fp-context-menu{position:absolute;display:none;z-index:1001;background-color:#fff;padding:10px;border:1px solid #aaa;-webkit-box-shadow:0 0 4px #888;-moz-box-shadow:0 0 4px #888;box-shadow:0 0 4px #888;width:170px;}
+.playful .fp-context-menu li{text-align:center !important;padding:10px;color:#444 !important;font-size:11px !important;margin:0 -10px 0 -10px;}
+.playful .fp-context-menu li a{color:#00a7c8 !important;font-size:12.100000000000001px !important}
+.playful .fp-context-menu li:hover:not(.copyright){background-color:#eee}
+.playful .fp-context-menu li.copyright{margin:0;padding-left:110px;background-image:url("img/flowplayer.png");background-repeat:no-repeat;background-size:100px 20px;background-position:5px 5px;border-bottom:1px solid #bbb;}
+@media (-webkit-min-device-pixel-ratio: 2){.playful .fp-context-menu li.copyright{background-image:url("img/flowplayer@2x.png")}
+}@-moz-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-webkit-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-o-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-ms-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}.playful.is-touch.is-mouseover .fp-progress:before{background-color:#00a7c8}
+.playful .fp-title{position:absolute;top:12px;left:12px;}
+.is-rtl.playful .fp-title{left:auto;right:12px}
+.playful .fp-title,.playful .fp-unload,.playful .fp-fullscreen,.playful .fp-embed{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.playful .fp-embed-code{right:99px;}
+.is-closeable.playful .fp-embed-code{right:146px}
+.is-rtl.playful .fp-embed-code{right:auto;left:99px}
+.playful.is-mouseout .fp-menu{display:none}
+.playful.is-mouseout .fp-controls{-webkit-transition:none;-moz-transition:none;transition:none;-webkit-animation:functional-controls-hide 1s 1;-moz-animation:functional-controls-hide 1s 1;animation:functional-controls-hide 1s 1}
+.playful.is-mouseout .fp-timeline{-webkit-transition:none;-moz-transition:none;transition:none}
+.playful.is-mouseout .fp-volume,.playful.is-mouseout .fp-brand,.playful.is-mouseout .fp-play,.playful.is-mouseout .fp-time{-webkit-transition:none;-moz-transition:none;transition:none;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+.playful.fixed-controls .fp-elapsed,.playful.fixed-controls.is-mouseover .fp-elapsed{left:59px}
+.playful.fixed-controls .fp-controls,.playful.fixed-controls.is-mouseover .fp-controls{bottom:-35px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;left:0;right:0;}
+.is-fullscreen.playful.fixed-controls .fp-controls,.is-fullscreen.playful.fixed-controls.is-mouseover .fp-controls{bottom:0}
+.playful.fixed-controls .fp-controls .fp-play,.playful.fixed-controls.is-mouseover .fp-controls .fp-play{left:12px}
+.playful.fixed-controls .fp-controls .fp-timeline,.playful.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:106px;}
+.is-long.playful.fixed-controls .fp-controls .fp-timeline,.is-long.playful.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:136px}
+.playful.is-mouseover .fp-controls{bottom:12px;left:59px;right:12px;width:auto;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.playful.is-mouseover .fp-controls{left:12px;right:59px}
+.playful.is-mouseover .fp-controls .fp-play{left:-47px;display:block;background-color:#000;background-color:rgba(0,0,0,0.65);width:35px;height:35px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.playful.is-mouseover .fp-controls .fp-play{left:auto;right:-47px}
+.playful.is-mouseover .fp-controls .fp-timeline{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.playful.is-mouseover .fp-controls .fp-timeline .fp-progress,.playful.is-mouseover .fp-controls .fp-timeline .fp-buffer{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.playful.is-mouseover .fp-controls .fp-menu .fp-dropdown{bottom:41px;left:auto;right:-12px;}
+.is-rtl.playful.is-mouseover .fp-controls .fp-menu .fp-dropdown{right:auto;left:-12px}
+.playful.is-mouseover .fp-controls .fp-menu .fp-dropdown:before{display:none}
+.playful.is-mouseover .fp-controls li{border-color:#000;}
+.playful.is-mouseover .fp-controls li.active{border-color:#00a7c8}
+.playful.is-mouseover .fp-controls li:last-child:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;right:12px;border-bottom:none;border-top-width:5px;border-top-style:solid;border-top-color:inherit;border-left:5px solid transparent;border-right:5px solid transparent;}
+.is-rtl.playful.is-mouseover .fp-controls li:last-child:before{right:auto;left:12px}
+.playful .fp-elapsed,.playful.play-button .fp-elapsed{left:71px;}
+.is-rtl.playful .fp-elapsed,.is-rtl.playful.play-button .fp-elapsed{right:71px;left:auto}
+.playful .fp-time em{bottom:23px}
+@-moz-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-webkit-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-o-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-ms-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}.playful .fp-controls,.playful .fp-title,.playful .fp-embed,.playful .fp-play,.playful .fp-fullscreen,.playful .fp-close,.playful.aside-time .fp-time,.playful .fp-unload{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(136,136,136,0.85)),to(rgba(0,0,0,0.85)));background-image:-webkit-linear-gradient(top,rgba(136,136,136,0.85),rgba(0,0,0,0.85));background-image:-moz-linear-gradient(top,rgba(136,136,136,0.85),rgba(0,0,0,0.85));background-image:-o-linear-gradient(top,rgba(136,136,136,0.85),rgba(0,0,0,0.85));background-image:linear-gradient(to bottom,rgba(136,136,136,0.85),rgba(0,0,0,0.85));color:#eee !important;}
+.playful .fp-controls:before,.playful .fp-title:before,.playful .fp-embed:before,.playful .fp-play:before,.playful .fp-fullscreen:before,.playful .fp-close:before,.playful.aside-time .fp-time:before,.playful .fp-unload:before{color:#eee}
+.playful .fp-dropdown{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
+.playful .fp-dropdown li:last-child{-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px}
+.playful .fp-fullscreen:before,.playful .fp-unload:before,.playful .fp-mute:before,.playful .fp-embed:before,.playful .fp-close:before,.playful .fp-play:before,.playful .fp-menu:before{vertical-align:-2px}
+.playful .fp-controls .fp-menu{bottom:3px;}
+.is-mouseover.playful .fp-controls .fp-menu .fp-dropdown{bottom:36px}
+.playful .fp-volumeslider{height:8px;margin-top:1px;margin-left:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
+.playful .fp-volumeslider .fp-volumelevel{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
+.playful .fp-mute{top:-9.5px;}
+.playful .fp-mute:before{content:"\e60c";vertical-align:0;}
+.is-muted.is-ready.playful .fp-mute:before{content:"\e60c";color:#ccc}
+.playful .fp-mute:after{content:'';background-color:#9ebb11;width:6px;height:6px;display:block;position:absolute;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;right:2px;top:11px;}
+.is-muted.playful .fp-mute:after{background-color:#f00}
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.eot
Binary file src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.eot has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.svg Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,23 @@
+
+
+
+Generated by IcoMoon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.ttf
Binary file src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.ttf has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.woff
Binary file src/pyams_media/skin/resources/flowplayer/skin/fonts/fpicons.woff has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/functional.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/skin/functional.css Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,336 @@
+@font-face {
+ font-family: 'fpicons';
+ src:url('fonts/fpicons.eot?yg5dv7');
+ src:url('fonts/fpicons.eot?#iefixyg5dv7') format('embedded-opentype'),
+ url('fonts/fpicons.woff?yg5dv7') format('woff'),
+ url('fonts/fpicons.ttf?yg5dv7') format('truetype'),
+ url('fonts/fpicons.svg?yg5dv7#fpicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="fp-i-"], [class*=" fp-i-"] {
+ font-family: 'fpicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.flowplayer{position:relative;width:100%;counter-increment:flowplayer;background-size:contain;background-repeat:no-repeat;background-position:center center;display:inline-block;}
+.flowplayer *{font-weight:inherit;font-family:inherit;font-style:inherit;text-decoration:inherit;font-size:100%;padding:0;border:0;margin:0;list-style-type:none}
+.flowplayer a:focus{outline:0}
+.flowplayer video{width:100%}
+.flowplayer.is-ipad video{-webkit-transform:translateX(-2048px);}
+.is-ready.flowplayer.is-ipad video{-webkit-transform:translateX(0)}
+.flowplayer .fp-player{position:absolute;top:0;left:0;width:100%;height:100%}
+.flowplayer .fp-engine,.flowplayer .fp-ui,.flowplayer .fp-message{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;z-index:1}
+.flowplayer .fp-ui{z-index:11}
+.flowplayer .fp-message{display:none;text-align:center;padding-top:5%;cursor:default;}
+.flowplayer .fp-message h2{font-size:120%;margin-bottom:1em}
+.flowplayer .fp-message p{color:#666;font-size:95%}
+.flowplayer .fp-title{line-height:30px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif;font-size:11px;cursor:default;color:#fff;width:auto;max-width:50%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;float:left;padding:0 20px;}
+.is-rtl.flowplayer .fp-title{float:right}
+.aside-time.flowplayer .fp-title{display:none !important}
+.flowplayer .fp-controls{position:absolute;bottom:0;width:100%;}
+.no-background.flowplayer .fp-controls{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important}
+.is-fullscreen.flowplayer .fp-controls{bottom:3px}
+.is-mouseover.flowplayer .fp-controls{bottom:0}
+.flowplayer .fp-controls,.flowplayer .fp-title,.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close,.flowplayer .fp-embed,.flowplayer.aside-time .fp-time{background-color:#000;background-color:rgba(0,0,0,0.65);}
+.no-background.flowplayer .fp-controls,.no-background.flowplayer .fp-title,.no-background.flowplayer .fp-fullscreen,.no-background.flowplayer .fp-unload,.no-background.flowplayer .fp-close,.no-background.flowplayer .fp-embed,.no-background.flowplayer.aside-time .fp-time{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.no-background.flowplayer .fp-play,.no-background.flowplayer .fp-brand{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.flowplayer.fixed-controls .fp-controls{background-color:#000}
+.flowplayer .fp-timeline{background-color:#a5a5a5}
+.flowplayer .fp-buffer{background-color:#eee}
+.flowplayer .fp-progress{background-color:#00a7c8}
+.flowplayer .fp-volumeslider{background-color:#a5a5a5}
+.flowplayer .fp-volumelevel{background-color:#00a7c8}
+.flowplayer .fp-waiting{display:none;margin:19% auto;text-align:center;}
+.flowplayer .fp-waiting *{-webkit-box-shadow:0 0 5px #333;-moz-box-shadow:0 0 5px #333;box-shadow:0 0 5px #333}
+.flowplayer .fp-waiting em{width:1em;height:1em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;background-color:rgba(255,255,255,0.8);display:inline-block;-webkit-animation:pulse .6s infinite;-moz-animation:pulse .6s infinite;animation:pulse .6s infinite;margin:.3em;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);}
+.flowplayer .fp-waiting em:nth-child(1){-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s}
+.flowplayer .fp-waiting em:nth-child(2){-webkit-animation-delay:.45s;-moz-animation-delay:.45s;animation-delay:.45s}
+.flowplayer .fp-waiting em:nth-child(3){-webkit-animation-delay:.6s;-moz-animation-delay:.6s;animation-delay:.6s}
+.flowplayer .fp-waiting p{color:#ccc;font-weight:bold}
+.flowplayer .fp-speed{font-size:30px;background-color:#333;background-color:rgba(51,51,51,0.8);color:#eee;margin:0 auto;text-align:center;width:120px;padding:.1em 0 0;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .5s;-moz-transition:opacity .5s;transition:opacity .5s;}
+.flowplayer .fp-speed.fp-hilite{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-help{position:absolute;top:0;left:-9999em;z-index:100;background-color:#333;background-color:rgba(51,51,51,0.9);width:100%;height:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s;text-align:center;}
+.is-help.flowplayer .fp-help{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-help .fp-help-section{margin:3%;direction:ltr}
+.flowplayer .fp-help .fp-help-basics{margin-top:6%}
+.flowplayer .fp-help p{color:#eee;margin:.5em 0;font-size:14px;line-height:1.5;display:inline-block;margin:1% 2%}
+.flowplayer .fp-help em{background:#eee;-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;margin-right:.4em;padding:.3em .6em;color:#333}
+.flowplayer .fp-help small{font-size:90%;color:#aaa}
+.flowplayer .fp-help .fp-close{display:block}
+@media (max-width: 600px){.flowplayer .fp-help p{font-size:9px}
+}.flowplayer .fp-dropdown{position:absolute;top:5px;width:100px;background-color:#000 !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;margin:0 !important;list-style-type:none !important;}
+.flowplayer .fp-dropdown:before{content:'';display:block;position:absolute;top:-5px;left:calc(50% - 5px);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid rgba(51,51,51,0.9)}
+.flowplayer .fp-dropdown li{padding:10px !important;margin:0 !important;color:#fff !important;font-size:11px !important;list-style-type:none !important;}
+.flowplayer .fp-dropdown li.active{background-color:#00a7c8 !important;cursor:default !important}
+.flowplayer .fp-dropdown.fp-dropup{bottom:20px;top:auto;}
+.flowplayer .fp-dropdown.fp-dropup:before{top:auto;bottom:-5px;border-bottom:none;border-top:5px solid rgba(51,51,51,0.9)}
+.flowplayer .fp-tooltip{background-color:#000;color:#fff;display:none;position:absolute;padding:5px;}
+.flowplayer .fp-tooltip:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;left:calc(50% - 5px);border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000}
+.flowplayer .fp-timeline-tooltip{bottom:35px}
+.flowplayer .fp-timeline:hover+.fp-timeline-tooltip{display:block}
+.flowplayer .fp-subtitle{position:absolute;bottom:40px;left:-99999em;z-index:10;text-align:center;width:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .3s;-moz-transition:opacity .3s;transition:opacity .3s;}
+.flowplayer .fp-subtitle p{display:inline;background-color:#333;background-color:rgba(51,51,51,0.9);color:#eee;padding:.1em .4em;font-size:16px;line-height:1.6;}
+.flowplayer .fp-subtitle p:after{content:'';clear:both}
+.flowplayer .fp-subtitle p b{font-weight:bold}
+.flowplayer .fp-subtitle p i{font-style:italic}
+.flowplayer .fp-subtitle p u{text-decoration:underline}
+.flowplayer .fp-subtitle.fp-active{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-mute,.flowplayer .fp-embed,.flowplayer .fp-close,.flowplayer .fp-play,.flowplayer .fp-menu{font-family:'fpicons' !important;color:#fff !important;font-size:15px !important;text-align:center !important;line-height:30px !important;text-decoration:none !important;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-mute,.is-rtl.flowplayer .fp-embed,.is-rtl.flowplayer .fp-close,.is-rtl.flowplayer .fp-play,.is-rtl.flowplayer .fp-menu{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);transform:scale(-1,1)}
+.is-rtl.flowplayer .fp-menu{-webkit-transform:none;-moz-transform:none;transform:none}
+.flowplayer .fp-fullscreen:before{content:"\e602"}
+.flowplayer .fp-unload:before,.flowplayer .fp-close:before{content:"\e600"}
+.flowplayer .fp-mute:before{content:"\e606"}
+.flowplayer .fp-embed:before{content:"\e603"}
+.flowplayer .fp-play:before{content:"\e608"}
+.flowplayer .fp-menu:before{content:"\e604"}
+.flowplayer .fp-flash-disabled{background:#333;width:390px;margin:0 auto;position:absolute;bottom:0;color:#fff}
+.is-splash.flowplayer .fp-ui,.is-paused.flowplayer .fp-ui{background:url(img/play_white.png) center no-repeat;background-size:11%;}
+.is-rtl.is-splash.flowplayer .fp-ui,.is-rtl.is-paused.flowplayer .fp-ui{background:url(img/play_white_rtl.png) center no-repeat;background-size:11%}
+@media (-webkit-min-device-pixel-ratio: 2){.is-splash.flowplayer .fp-ui,.is-paused.flowplayer .fp-ui{background:url(img/play_white@x2.png) center no-repeat;background-size:11%}
+.is-rtl.is-splash.flowplayer .fp-ui,.is-rtl.is-paused.flowplayer .fp-ui{background:url(img/play_white_rtl@x2.png) center no-repeat;background-size:11%}
+}.is-fullscreen.flowplayer .fp-ui{background-size:auto}
+.is-seeking.flowplayer .fp-ui,.is-loading.flowplayer .fp-ui{background-image:none}
+.flowplayer .fp-brand{color:#fff !important;position:absolute;right:115px;font-weight:normal !important;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;text-decoration:none !important;line-height:15px !important;font-size:11px !important;height:15px;width:55px;bottom:9px;box-sizing:border-box;text-align:center;padding:1px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
+.has-menu.flowplayer .fp-brand{right:152px}
+.is-rtl.flowplayer .fp-brand{right:auto;left:125px}
+.has-menu.is-rtl.flowplayer .fp-brand{left:152px}
+.no-brand.flowplayer .fp-brand{display:none}
+.no-volume.no-mute.flowplayer .fp-brand{right:10px;}
+.has-menu.no-volume.no-mute.flowplayer .fp-brand{right:47px}
+.no-volume.flowplayer .fp-brand{right:50px}
+.no-mute.flowplayer .fp-brand{right:95px}
+.flowplayer .fp-logo{position:absolute;top:auto;left:15px;bottom:40px;cursor:pointer;display:none;z-index:100;}
+.flowplayer .fp-logo img{width:100%}
+.is-embedded.flowplayer .fp-logo{display:block}
+.fixed-controls.flowplayer .fp-logo{bottom:15px}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close{position:absolute;top:10px;left:auto;right:10px;display:block;width:30px;height:23px;text-align:center;cursor:pointer;height:30px;width:30px;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-close{right:auto;left:10px}
+.flowplayer .fp-unload,.flowplayer .fp-close{display:none}
+.flowplayer .fp-play{display:none;height:30px !important;position:absolute;bottom:0;left:0;text-align:center;}
+.is-rtl.flowplayer .fp-play{left:auto;right:0}
+.is-playing.flowplayer .fp-play:before{content:"\e607"}
+.flowplayer .fp-menu{display:none;position:absolute;bottom:0;z-index:11;right:10px;}
+.is-rtl.flowplayer .fp-menu{right:auto;left:10px}
+.has-menu.flowplayer .fp-menu{display:block}
+.flowplayer .fp-menu .fp-dropdown{z-index:12;display:none;left:-42.5px;line-height:auto;width:149px;-webkit-transform:none;-moz-transform:none;transform:none;}
+.is-rtl.flowplayer .fp-menu .fp-dropdown{left:-10px}
+.flowplayer .fp-menu.dropdown-open .fp-dropdown{display:block}
+.flowplayer.is-ready.is-closeable .fp-unload{display:block}
+.flowplayer.is-ready.is-closeable .fp-embed{right:90px}
+.flowplayer.is-ready.is-closeable .fp-fullscreen{right:50px}
+.flowplayer.is-fullscreen .fp-fullscreen{display:block !important;}
+.flowplayer.is-fullscreen .fp-fullscreen:before{content:"\e601"}
+.flowplayer .fp-timeline{height:3px;position:relative;overflow:hidden;top:10px;height:10px;margin:0 225px 0 55px;}
+.no-brand.flowplayer .fp-timeline{margin-right:160px;}
+.has-menu.no-brand.flowplayer .fp-timeline{margin-right:187px}
+.no-volume.no-brand.flowplayer .fp-timeline{margin-right:95px}
+.no-mute.no-brand.flowplayer .fp-timeline{margin-right:130px}
+.no-mute.no-volume.no-brand.flowplayer .fp-timeline{margin-right:55px}
+.has-menu.flowplayer .fp-timeline{margin-right:252px}
+.no-volume.flowplayer .fp-timeline{margin-right:160px}
+.no-mute.flowplayer .fp-timeline{margin-right:195px}
+.no-mute.no-volume.flowplayer .fp-timeline{margin-right:120px;}
+.has-menu.no-mute.no-volume.flowplayer .fp-timeline{margin-right:157px}
+.is-rtl.flowplayer .fp-timeline{margin:0 55px 0 225px;}
+.no-brand.is-rtl.flowplayer .fp-timeline{margin-left:160px;}
+.has-menu.no-brand.is-rtl.flowplayer .fp-timeline{margin-left:197px}
+.has-menu.is-rtl.flowplayer .fp-timeline{margin-left:262px}
+.no-volume.is-rtl.flowplayer .fp-timeline{margin-left:95px}
+.no-mute.is-rtl.flowplayer .fp-timeline{margin-left:130px}
+.no-mute.no-volume.is-rtl.flowplayer .fp-timeline{margin-left:55px}
+.is-long.flowplayer .fp-timeline{margin:0 255px 0 85px;}
+.no-volume.is-long.flowplayer .fp-timeline{margin-right:180px}
+.no-mute.is-long.flowplayer .fp-timeline{margin-right:140px}
+.has-menu.is-long.flowplayer .fp-timeline{margin-right:292px}
+.no-brand.is-long.flowplayer .fp-timeline{margin-right:190px;}
+.no-volume.no-brand.is-long.flowplayer .fp-timeline{margin-right:125px}
+.no-mute.no-brand.is-long.flowplayer .fp-timeline{margin-right:85px}
+.has-menu.no-brand.is-long.flowplayer .fp-timeline{margin-right:227px}
+.is-rtl.is-long.flowplayer .fp-timeline{margin:85px 0 190px 0;}
+.no-volume.is-rtl.is-long.flowplayer .fp-timeline{margin-left:125px}
+.no-mute.is-rtl.is-long.flowplayer .fp-timeline{margin-left:85px}
+.aside-time.flowplayer .fp-timeline,.no-time.flowplayer .fp-timeline{margin:0 190px 0 10px;}
+.has-menu.aside-time.flowplayer .fp-timeline,.has-menu.no-time.flowplayer .fp-timeline{margin-right:227px}
+.aside-time.no-brand.flowplayer .fp-timeline{margin-right:115px}
+.aside-time.no-volume.flowplayer .fp-timeline,.no-time.no-volume.flowplayer .fp-timeline{margin-right:115px}
+.aside-time.no-mute.flowplayer .fp-timeline,.no-time.no-mute.flowplayer .fp-timeline{margin-right:75px}
+.is-rtl.aside-time.flowplayer .fp-timeline,.is-rtl.no-time.flowplayer .fp-timeline{margin:0 10px 0 115px}
+.is-rtl.aside-time.no-volume.flowplayer .fp-timeline,.is-rtl.no-time.no-volume.flowplayer .fp-timeline{margin-left:50px}
+.is-rtl.aside-time.no-mute.flowplayer .fp-timeline,.is-rtl.no-time.no-mute.flowplayer .fp-timeline{margin-left:10px}
+.flowplayer .fp-buffer,.flowplayer .fp-progress{position:absolute;top:0;left:auto;height:100%;cursor:col-resize}
+.flowplayer .fp-buffer{-webkit-transition:width .25s linear;-moz-transition:width .25s linear;transition:width .25s linear}
+.flowplayer .fp-timeline.no-animation .fp-buffer{-webkit-transition:none;-moz-transition:none;transition:none}
+.flowplayer .fp-progress.animated{transition-timing-function:linear;transition-property:width,height}
+.flowplayer.is-touch .fp-timeline{overflow:visible}
+.flowplayer.is-touch .fp-progress{-webkit-transition:width .2s linear;-moz-transition:width .2s linear;transition:width .2s linear;box-sizing:border-box}
+.flowplayer.is-touch .fp-timeline.is-dragging .fp-progress{-webkit-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;-moz-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear}
+.flowplayer.is-touch.is-mouseover .fp-progress:after,.flowplayer.is-touch.is-mouseover .fp-progress:before{content:'';box-sizing:border-box;display:block;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;position:absolute;right:-5px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:after,.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:before{right:auto;left:-5px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:after{left:-10px;-webkit-box-shadow:-1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:-1px 0 4px rgba(0,0,0,0.5);box-shadow:-1px 0 4px rgba(0,0,0,0.5)}
+.flowplayer.is-touch.is-mouseover .fp-progress:before{width:10px;height:10px}
+.flowplayer.is-touch.is-mouseover .fp-progress:after{height:18px;width:18px;top:-4px;right:-10px;border:5px solid rgba(255,255,255,0.65);-webkit-box-shadow:1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:1px 0 4px rgba(0,0,0,0.5);box-shadow:1px 0 4px rgba(0,0,0,0.5)}
+.flowplayer.is-touch.is-mouseover .fp-timeline.is-dragging .fp-progress:after{border:10px solid #fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px;-webkit-transition:inherit;-moz-transition:inherit;transition:inherit;top:-5px;right:-10px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-timeline.is-dragging .fp-progress:after{left:-15px;right:auto;border:10px solid #fff}
+.flowplayer .fp-volume{position:absolute;top:12px;right:10px;}
+.has-menu.flowplayer .fp-volume{right:37px}
+.is-rtl.flowplayer .fp-volume{right:auto;left:10px}
+.is-rtl.has-menu.flowplayer .fp-volume{left:37px}
+.flowplayer .fp-mute{position:relative;width:30px;height:30px;float:left;top:-12px;cursor:pointer;}
+.is-rtl.flowplayer .fp-mute{float:right}
+.no-mute.flowplayer .fp-mute{display:none}
+.flowplayer .fp-volumeslider{width:75px;height:6px;cursor:col-resize;float:left;}
+.is-rtl.flowplayer .fp-volumeslider{float:right}
+.no-volume.flowplayer .fp-volumeslider{display:none}
+.flowplayer .fp-volumelevel{height:100%}
+.flowplayer .fp-time{text-shadow:0 0 1px #000;font-size:11px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;color:#fff;width:100%;}
+.flowplayer .fp-time.is-inverted .fp-duration{display:none}
+.flowplayer .fp-time.is-inverted .fp-remaining{display:inline}
+.flowplayer .fp-time em{width:35px;height:10px;line-height:10px;text-align:center;position:absolute;bottom:9px}
+.no-time.flowplayer .fp-time{display:none}
+.is-long.flowplayer .fp-time em{width:65px}
+.flowplayer .fp-elapsed{left:10px;}
+.is-rtl.flowplayer .fp-elapsed{left:auto;right:10px}
+.flowplayer .fp-remaining,.flowplayer .fp-duration{right:180px;color:#eee;}
+.no-brand.flowplayer .fp-remaining,.no-brand.flowplayer .fp-duration{right:125px;}
+.has-menu.no-brand.flowplayer .fp-remaining,.has-menu.no-brand.flowplayer .fp-duration{right:152px}
+.no-volume.no-brand.flowplayer .fp-remaining,.no-volume.no-brand.flowplayer .fp-duration{right:50px}
+.no-mute.no-brand.flowplayer .fp-remaining,.no-mute.no-brand.flowplayer .fp-duration{right:95px}
+.no-mute.no-volume.no-brand.flowplayer .fp-remaining,.no-mute.no-volume.no-brand.flowplayer .fp-duration{right:10px}
+.has-menu.flowplayer .fp-remaining,.has-menu.flowplayer .fp-duration{right:217px}
+.no-volume.flowplayer .fp-remaining,.no-volume.flowplayer .fp-duration{right:115px}
+.no-mute.flowplayer .fp-remaining,.no-mute.flowplayer .fp-duration{right:160px}
+.no-mute.no-volume.flowplayer .fp-remaining,.no-mute.no-volume.flowplayer .fp-duration{right:75px;}
+.has-menu.no-mute.no-volume.flowplayer .fp-remaining,.has-menu.no-mute.no-volume.flowplayer .fp-duration{right:112px}
+.is-rtl.flowplayer .fp-remaining,.is-rtl.flowplayer .fp-duration{right:auto;left:180px;}
+.no-brand.is-rtl.flowplayer .fp-remaining,.no-brand.is-rtl.flowplayer .fp-duration{left:115px;}
+.has-menu.no-brand.is-rtl.flowplayer .fp-remaining,.has-menu.no-brand.is-rtl.flowplayer .fp-duration{left:142px}
+.has-menu.is-rtl.flowplayer .fp-remaining,.has-menu.is-rtl.flowplayer .fp-duration{left:207px}
+.no-volume.is-rtl.flowplayer .fp-remaining,.no-volume.is-rtl.flowplayer .fp-duration{left:50px}
+.no-mute.is-rtl.flowplayer .fp-remaining,.no-mute.is-rtl.flowplayer .fp-duration{left:95px}
+.no-mute.no-volume.is-rtl.flowplayer .fp-remaining,.no-mute.no-volume.is-rtl.flowplayer .fp-duration{left:10px}
+.flowplayer .fp-remaining{display:none}
+.flowplayer.aside-time .fp-time{position:absolute;top:10px;left:10px;bottom:auto !important;width:auto;background-color:#000;background-color:rgba(0,0,0,0.65);height:30px;padding:0 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;line-height:30px;text-align:center;font-size:15px;}
+.no-background.flowplayer.aside-time .fp-time{background-color:transparent !important}
+.flowplayer.aside-time .fp-time strong,.flowplayer.aside-time .fp-time em{position:static}
+.flowplayer.aside-time .fp-time .fp-elapsed::after{content:' / '}
+.flowplayer.is-splash,.flowplayer.is-poster{cursor:pointer;}
+.flowplayer.is-splash .fp-controls,.flowplayer.is-poster .fp-controls,.flowplayer.is-splash .fp-fullscreen,.flowplayer.is-poster .fp-fullscreen,.flowplayer.is-splash .fp-unload,.flowplayer.is-poster .fp-unload,.flowplayer.is-splash .fp-time,.flowplayer.is-poster .fp-time,.flowplayer.is-splash .fp-embed,.flowplayer.is-poster .fp-embed,.flowplayer.is-splash .fp-title,.flowplayer.is-poster .fp-title,.flowplayer.is-splash .fp-brand,.flowplayer.is-poster .fp-brand{display:none !important}
+.flowplayer.is-poster .fp-engine{top:-9999em}
+.flowplayer.is-loading .fp-waiting{display:block}
+.flowplayer.is-loading .fp-controls,.flowplayer.is-loading .fp-time{display:none}
+.flowplayer.is-loading .fp-ui{background-position:-9999em}
+.flowplayer.is-loading video.fp-engine{position:absolute;top:-9999em}
+.flowplayer.is-seeking .fp-waiting{display:block}
+.flowplayer.is-playing{background-image:none !important;background-color:#333;}
+.flowplayer.is-playing.hls-fix.is-finished .fp-engine{position:absolute;top:-9999em}
+.flowplayer.is-fullscreen{top:0 !important;left:0 !important;border:0 !important;margin:0 !important;width:100% !important;height:100% !important;max-width:100% !important;z-index:99999 !important;-webkit-box-shadow:0 !important;-moz-box-shadow:0 !important;box-shadow:0 !important;background-image:none !important;background-color:#333;}
+.is-rtl.flowplayer.is-fullscreen{left:auto !important;right:0 !important}
+.flowplayer.is-fullscreen .fp-player{background-color:#333}
+.flowplayer.is-error{border:1px solid #909090;background:#fdfdfd !important;}
+.flowplayer.is-error h2{font-weight:bold;font-size:large;margin-top:10%}
+.flowplayer.is-error .fp-message{display:block}
+.flowplayer.is-error object,.flowplayer.is-error video,.flowplayer.is-error .fp-controls,.flowplayer.is-error .fp-time,.flowplayer.is-error .fp-subtitle{display:none}
+.flowplayer.is-ready.is-muted .fp-mute{opacity:.7;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70)}
+.flowplayer.is-ready.is-muted .fp-mute:before{content:"\e605"}
+.flowplayer.is-mouseout .fp-controls,.flowplayer.is-mouseout .fp-title{height:0;-webkit-transition:height .15s .3s;-moz-transition:height .15s .3s;transition:height .15s .3s}
+.is-fullscreen.flowplayer.is-mouseout .fp-controls{height:3px;bottom:0}
+.flowplayer.is-mouseout .fp-title{overflow:hidden}
+.flowplayer.is-mouseout .fp-timeline{margin:0 !important}
+.flowplayer.is-mouseout .fp-timeline{-webkit-transition:height .15s .3s,top .15s .3s,margin .15s .3s;-moz-transition:height .15s .3s,top .15s .3s,margin .15s .3s;transition:height .15s .3s,top .15s .3s,margin .15s .3s;height:4px;top:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
+.flowplayer.is-mouseout .fp-fullscreen,.flowplayer.is-mouseout .fp-unload,.flowplayer.is-mouseout .fp-elapsed,.flowplayer.is-mouseout .fp-remaining,.flowplayer.is-mouseout .fp-duration,.flowplayer.is-mouseout .fp-embed,.flowplayer.is-mouseout .fp-volume,.flowplayer.is-mouseout .fp-play,.flowplayer.is-mouseout .fp-menu,.flowplayer.is-mouseout .fp-brand,.flowplayer.is-mouseout .fp-timeline-tooltip,.flowplayer.is-mouseout.aside-time .fp-time{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .15s .3s;-moz-transition:opacity .15s .3s;transition:opacity .15s .3s}
+.flowplayer.is-mouseover .fp-controls,.flowplayer.fixed-controls .fp-controls{height:30px}
+.flowplayer.is-mouseover .fp-title,.flowplayer.fixed-controls .fp-title{height:30px}
+.flowplayer.is-mouseover .fp-fullscreen,.flowplayer.fixed-controls .fp-fullscreen,.flowplayer.is-mouseover .fp-unload,.flowplayer.fixed-controls .fp-unload,.flowplayer.is-mouseover .fp-elapsed,.flowplayer.fixed-controls .fp-elapsed,.flowplayer.is-mouseover .fp-remaining,.flowplayer.fixed-controls .fp-remaining,.flowplayer.is-mouseover .fp-duration,.flowplayer.fixed-controls .fp-duration,.flowplayer.is-mouseover .fp-embed,.flowplayer.fixed-controls .fp-embed,.flowplayer.is-mouseover .fp-logo,.flowplayer.fixed-controls .fp-logo,.flowplayer.is-mouseover .fp-volume,.flowplayer.fixed-controls .fp-volume,.flowplayer.is-mouseover .fp-play,.flowplayer.fixed-controls .fp-play,.flowplayer.is-mouseover .fp-menu,.flowplayer.fixed-controls .fp-menu{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer.fixed-controls .fp-volume{display:block}
+.flowplayer.fixed-controls .fp-controls{bottom:-30px;}
+.is-fullscreen.flowplayer.fixed-controls .fp-controls{bottom:0}
+.flowplayer.fixed-controls .fp-time em{bottom:-20px;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);}
+.is-fullscreen.flowplayer.fixed-controls .fp-time em{bottom:10px}
+.flowplayer.is-disabled .fp-progress{background-color:#999}
+.flowplayer.is-flash-disabled{background-color:#333;}
+.flowplayer.is-flash-disabled object.fp-engine{z-index:100}
+.flowplayer.is-flash-disabled .fp-flash-disabled{display:block;z-index:101}
+.flowplayer .fp-embed{position:absolute;top:10px;left:auto;right:50px;display:block;width:30px;height:30px;text-align:center;}
+.is-rtl.flowplayer .fp-embed{right:auto;left:50px}
+.flowplayer .fp-embed-code{position:absolute;display:none;top:10px;right:67px;background-color:#333;padding:3px 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 3px #ccc;-moz-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc;font-size:12px;}
+.is-closeable.flowplayer .fp-embed-code{right:99px}
+.flowplayer .fp-embed-code:before{content:'';width:0;height:0;position:absolute;top:2px;right:-10px;border:5px solid transparent;border-left-color:#333}
+.is-rtl.flowplayer .fp-embed-code{right:auto;left:67px;}
+.is-rtl.flowplayer .fp-embed-code:before{right:auto;left:-10px;border-left-color:transparent;border-right-color:#333}
+.flowplayer .fp-embed-code textarea{width:400px;height:16px;font-family:monaco,"courier new",verdana;color:#777;white-space:nowrap;resize:none;overflow:hidden;border:0;outline:0;background-color:transparent;color:#ccc}
+.flowplayer .fp-embed-code label{display:block;color:#999}
+.flowplayer.is-embedding .fp-embed,.flowplayer.is-embedding .fp-embed-code{display:block;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer.no-time .fp-embed{left:10px !important;}
+.is-rtl.flowplayer.no-time .fp-embed{left:auto;right:10px !important}
+.flowplayer.is-live .fp-timeline,.flowplayer.is-live .fp-duration,.flowplayer.is-live .fp-remaining{display:none}
+.flowplayer .fp-context-menu{position:absolute;display:none;z-index:1001;background-color:#fff;padding:10px;border:1px solid #aaa;-webkit-box-shadow:0 0 4px #888;-moz-box-shadow:0 0 4px #888;box-shadow:0 0 4px #888;width:170px;}
+.flowplayer .fp-context-menu li{text-align:center !important;padding:10px;color:#444 !important;font-size:11px !important;margin:0 -10px 0 -10px;}
+.flowplayer .fp-context-menu li a{color:#00a7c8 !important;font-size:12.100000000000001px !important}
+.flowplayer .fp-context-menu li:hover:not(.copyright){background-color:#eee}
+.flowplayer .fp-context-menu li.copyright{margin:0;padding-left:110px;background-image:url("img/flowplayer.png");background-repeat:no-repeat;background-size:100px 20px;background-position:5px 5px;border-bottom:1px solid #bbb;}
+@media (-webkit-min-device-pixel-ratio: 2){.flowplayer .fp-context-menu li.copyright{background-image:url("img/flowplayer@2x.png")}
+}@-moz-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-webkit-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-o-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-ms-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}.flowplayer.is-touch.is-mouseover .fp-progress:before{background-color:#00a7c8}
+.flowplayer .fp-title{position:absolute;top:10px;left:10px;}
+.is-rtl.flowplayer .fp-title{left:auto;right:10px}
+.flowplayer .fp-title,.flowplayer .fp-unload,.flowplayer .fp-fullscreen,.flowplayer .fp-embed{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.flowplayer .fp-embed-code{right:85px;}
+.is-closeable.flowplayer .fp-embed-code{right:125px}
+.is-rtl.flowplayer .fp-embed-code{right:auto;left:85px}
+.flowplayer.is-mouseout .fp-menu{display:none}
+.flowplayer.is-mouseout .fp-controls{-webkit-transition:none;-moz-transition:none;transition:none;-webkit-animation:functional-controls-hide 1s 1;-moz-animation:functional-controls-hide 1s 1;animation:functional-controls-hide 1s 1}
+.flowplayer.is-mouseout .fp-timeline{-webkit-transition:none;-moz-transition:none;transition:none}
+.flowplayer.is-mouseout .fp-volume,.flowplayer.is-mouseout .fp-brand,.flowplayer.is-mouseout .fp-play,.flowplayer.is-mouseout .fp-time{-webkit-transition:none;-moz-transition:none;transition:none;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+.flowplayer.fixed-controls .fp-elapsed,.flowplayer.fixed-controls.is-mouseover .fp-elapsed{left:50px}
+.flowplayer.fixed-controls .fp-controls,.flowplayer.fixed-controls.is-mouseover .fp-controls{bottom:-30px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;left:0;right:0;}
+.is-fullscreen.flowplayer.fixed-controls .fp-controls,.is-fullscreen.flowplayer.fixed-controls.is-mouseover .fp-controls{bottom:0}
+.flowplayer.fixed-controls .fp-controls .fp-play,.flowplayer.fixed-controls.is-mouseover .fp-controls .fp-play{left:10px}
+.flowplayer.fixed-controls .fp-controls .fp-timeline,.flowplayer.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:95px;}
+.is-long.flowplayer.fixed-controls .fp-controls .fp-timeline,.is-long.flowplayer.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:125px}
+.flowplayer.is-mouseover .fp-controls{bottom:10px;left:50px;right:10px;width:auto;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.flowplayer.is-mouseover .fp-controls{left:10px;right:50px}
+.flowplayer.is-mouseover .fp-controls .fp-play{left:-40px;display:block;background-color:#000;background-color:rgba(0,0,0,0.65);width:30px;height:30px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.flowplayer.is-mouseover .fp-controls .fp-play{left:auto;right:-40px}
+.flowplayer.is-mouseover .fp-controls .fp-timeline{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.flowplayer.is-mouseover .fp-controls .fp-timeline .fp-progress,.flowplayer.is-mouseover .fp-controls .fp-timeline .fp-buffer{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.flowplayer.is-mouseover .fp-controls .fp-menu .fp-dropdown{bottom:35px;left:auto;right:-10px;}
+.is-rtl.flowplayer.is-mouseover .fp-controls .fp-menu .fp-dropdown{right:auto;left:-10px}
+.flowplayer.is-mouseover .fp-controls .fp-menu .fp-dropdown:before{display:none}
+.flowplayer.is-mouseover .fp-controls li{border-color:#000;}
+.flowplayer.is-mouseover .fp-controls li.active{border-color:#00a7c8}
+.flowplayer.is-mouseover .fp-controls li:last-child:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;right:10px;border-bottom:none;border-top-width:5px;border-top-style:solid;border-top-color:inherit;border-left:5px solid transparent;border-right:5px solid transparent;}
+.is-rtl.flowplayer.is-mouseover .fp-controls li:last-child:before{right:auto;left:10px}
+.flowplayer .fp-elapsed,.flowplayer.play-button .fp-elapsed{left:60px;}
+.is-rtl.flowplayer .fp-elapsed,.is-rtl.flowplayer.play-button .fp-elapsed{right:60px;left:auto}
+.flowplayer .fp-time em{bottom:19px}
+@-moz-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-webkit-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-o-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-ms-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/black.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/black.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/black@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/black@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/black_rtl.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/black_rtl.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/black_rtl@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/black_rtl@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/flowplayer.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/flowplayer.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/flowplayer@2x.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/flowplayer@2x.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_black.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_black.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_black@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_black@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_black_rtl.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_black_rtl.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_black_rtl@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_black_rtl@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_white.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_white.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_white@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_white@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_white_rtl.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_white_rtl.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/play_white_rtl@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/play_white_rtl@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_black.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_black.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_black@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_black@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_black_rtl.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_black_rtl.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_black_rtl@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_black_rtl@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_white.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_white.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_white@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_white@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_white_rtl.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_white_rtl.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/playful_white_rtl@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/playful_white_rtl@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/white.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/white.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/white@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/white@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/white_rtl.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/white_rtl.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/img/white_rtl@x2.png
Binary file src/pyams_media/skin/resources/flowplayer/skin/img/white_rtl@x2.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/minimalist.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/skin/minimalist.css Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,313 @@
+@font-face {
+ font-family: 'fpicons';
+ src:url('fonts/fpicons.eot?yg5dv7');
+ src:url('fonts/fpicons.eot?#iefixyg5dv7') format('embedded-opentype'),
+ url('fonts/fpicons.woff?yg5dv7') format('woff'),
+ url('fonts/fpicons.ttf?yg5dv7') format('truetype'),
+ url('fonts/fpicons.svg?yg5dv7#fpicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="fp-i-"], [class*=" fp-i-"] {
+ font-family: 'fpicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.flowplayer{position:relative;width:100%;counter-increment:flowplayer;background-size:contain;background-repeat:no-repeat;background-position:center center;display:inline-block;}
+.flowplayer *{font-weight:inherit;font-family:inherit;font-style:inherit;text-decoration:inherit;font-size:100%;padding:0;border:0;margin:0;list-style-type:none}
+.flowplayer a:focus{outline:0}
+.flowplayer video{width:100%}
+.flowplayer.is-ipad video{-webkit-transform:translateX(-2048px);}
+.is-ready.flowplayer.is-ipad video{-webkit-transform:translateX(0)}
+.flowplayer .fp-player{position:absolute;top:0;left:0;width:100%;height:100%}
+.flowplayer .fp-engine,.flowplayer .fp-ui,.flowplayer .fp-message{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;z-index:1}
+.flowplayer .fp-ui{z-index:11}
+.flowplayer .fp-message{display:none;text-align:center;padding-top:5%;cursor:default;}
+.flowplayer .fp-message h2{font-size:120%;margin-bottom:1em}
+.flowplayer .fp-message p{color:#666;font-size:95%}
+.flowplayer .fp-title{line-height:30px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif;font-size:11px;cursor:default;color:#fff;width:auto;max-width:50%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;float:left;padding:0 20px;}
+.is-rtl.flowplayer .fp-title{float:right}
+.aside-time.flowplayer .fp-title{display:none !important}
+.flowplayer .fp-controls{position:absolute;bottom:0;width:100%;}
+.no-background.flowplayer .fp-controls{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important}
+.is-fullscreen.flowplayer .fp-controls{bottom:3px}
+.is-mouseover.flowplayer .fp-controls{bottom:0}
+.flowplayer .fp-controls,.flowplayer .fp-title,.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close,.flowplayer .fp-embed,.flowplayer.aside-time .fp-time{background-color:#000;background-color:rgba(0,0,0,0.65);}
+.no-background.flowplayer .fp-controls,.no-background.flowplayer .fp-title,.no-background.flowplayer .fp-fullscreen,.no-background.flowplayer .fp-unload,.no-background.flowplayer .fp-close,.no-background.flowplayer .fp-embed,.no-background.flowplayer.aside-time .fp-time{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.no-background.flowplayer .fp-play,.no-background.flowplayer .fp-brand{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.flowplayer.fixed-controls .fp-controls{background-color:#000}
+.flowplayer .fp-timeline{background-color:#a5a5a5}
+.flowplayer .fp-buffer{background-color:#eee}
+.flowplayer .fp-progress{background-color:#00a7c8}
+.flowplayer .fp-volumeslider{background-color:#a5a5a5}
+.flowplayer .fp-volumelevel{background-color:#00a7c8}
+.flowplayer .fp-waiting{display:none;margin:19% auto;text-align:center;}
+.flowplayer .fp-waiting *{-webkit-box-shadow:0 0 5px #333;-moz-box-shadow:0 0 5px #333;box-shadow:0 0 5px #333}
+.flowplayer .fp-waiting em{width:1em;height:1em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;background-color:rgba(255,255,255,0.8);display:inline-block;-webkit-animation:pulse .6s infinite;-moz-animation:pulse .6s infinite;animation:pulse .6s infinite;margin:.3em;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);}
+.flowplayer .fp-waiting em:nth-child(1){-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s}
+.flowplayer .fp-waiting em:nth-child(2){-webkit-animation-delay:.45s;-moz-animation-delay:.45s;animation-delay:.45s}
+.flowplayer .fp-waiting em:nth-child(3){-webkit-animation-delay:.6s;-moz-animation-delay:.6s;animation-delay:.6s}
+.flowplayer .fp-waiting p{color:#ccc;font-weight:bold}
+.flowplayer .fp-speed{font-size:30px;background-color:#333;background-color:rgba(51,51,51,0.8);color:#eee;margin:0 auto;text-align:center;width:120px;padding:.1em 0 0;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .5s;-moz-transition:opacity .5s;transition:opacity .5s;}
+.flowplayer .fp-speed.fp-hilite{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-help{position:absolute;top:0;left:-9999em;z-index:100;background-color:#333;background-color:rgba(51,51,51,0.9);width:100%;height:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s;text-align:center;}
+.is-help.flowplayer .fp-help{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-help .fp-help-section{margin:3%;direction:ltr}
+.flowplayer .fp-help .fp-help-basics{margin-top:6%}
+.flowplayer .fp-help p{color:#eee;margin:.5em 0;font-size:14px;line-height:1.5;display:inline-block;margin:1% 2%}
+.flowplayer .fp-help em{background:#eee;-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;margin-right:.4em;padding:.3em .6em;color:#333}
+.flowplayer .fp-help small{font-size:90%;color:#aaa}
+.flowplayer .fp-help .fp-close{display:block}
+@media (max-width: 600px){.flowplayer .fp-help p{font-size:9px}
+}.flowplayer .fp-dropdown{position:absolute;top:5px;width:100px;background-color:#000 !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;margin:0 !important;list-style-type:none !important;}
+.flowplayer .fp-dropdown:before{content:'';display:block;position:absolute;top:-5px;left:calc(50% - 5px);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid rgba(51,51,51,0.9)}
+.flowplayer .fp-dropdown li{padding:10px !important;margin:0 !important;color:#fff !important;font-size:11px !important;list-style-type:none !important;}
+.flowplayer .fp-dropdown li.active{background-color:#00a7c8 !important;cursor:default !important}
+.flowplayer .fp-dropdown.fp-dropup{bottom:20px;top:auto;}
+.flowplayer .fp-dropdown.fp-dropup:before{top:auto;bottom:-5px;border-bottom:none;border-top:5px solid rgba(51,51,51,0.9)}
+.flowplayer .fp-tooltip{background-color:#000;color:#fff;display:none;position:absolute;padding:5px;}
+.flowplayer .fp-tooltip:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;left:calc(50% - 5px);border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000}
+.flowplayer .fp-timeline-tooltip{bottom:35px}
+.flowplayer .fp-timeline:hover+.fp-timeline-tooltip{display:block}
+.flowplayer .fp-subtitle{position:absolute;bottom:40px;left:-99999em;z-index:10;text-align:center;width:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .3s;-moz-transition:opacity .3s;transition:opacity .3s;}
+.flowplayer .fp-subtitle p{display:inline;background-color:#333;background-color:rgba(51,51,51,0.9);color:#eee;padding:.1em .4em;font-size:16px;line-height:1.6;}
+.flowplayer .fp-subtitle p:after{content:'';clear:both}
+.flowplayer .fp-subtitle p b{font-weight:bold}
+.flowplayer .fp-subtitle p i{font-style:italic}
+.flowplayer .fp-subtitle p u{text-decoration:underline}
+.flowplayer .fp-subtitle.fp-active{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-mute,.flowplayer .fp-embed,.flowplayer .fp-close,.flowplayer .fp-play,.flowplayer .fp-menu{font-family:'fpicons' !important;color:#fff !important;font-size:15px !important;text-align:center !important;line-height:30px !important;text-decoration:none !important;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-mute,.is-rtl.flowplayer .fp-embed,.is-rtl.flowplayer .fp-close,.is-rtl.flowplayer .fp-play,.is-rtl.flowplayer .fp-menu{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);transform:scale(-1,1)}
+.is-rtl.flowplayer .fp-menu{-webkit-transform:none;-moz-transform:none;transform:none}
+.flowplayer .fp-fullscreen:before{content:"\e602"}
+.flowplayer .fp-unload:before,.flowplayer .fp-close:before{content:"\e600"}
+.flowplayer .fp-mute:before{content:"\e606"}
+.flowplayer .fp-embed:before{content:"\e603"}
+.flowplayer .fp-play:before{content:"\e608"}
+.flowplayer .fp-menu:before{content:"\e604"}
+.flowplayer .fp-flash-disabled{background:#333;width:390px;margin:0 auto;position:absolute;bottom:0;color:#fff}
+.is-splash.flowplayer .fp-ui,.is-paused.flowplayer .fp-ui{background:url(img/play_white.png) center no-repeat;background-size:11%;}
+.is-rtl.is-splash.flowplayer .fp-ui,.is-rtl.is-paused.flowplayer .fp-ui{background:url(img/play_white_rtl.png) center no-repeat;background-size:11%}
+@media (-webkit-min-device-pixel-ratio: 2){.is-splash.flowplayer .fp-ui,.is-paused.flowplayer .fp-ui{background:url(img/play_white@x2.png) center no-repeat;background-size:11%}
+.is-rtl.is-splash.flowplayer .fp-ui,.is-rtl.is-paused.flowplayer .fp-ui{background:url(img/play_white_rtl@x2.png) center no-repeat;background-size:11%}
+}.is-fullscreen.flowplayer .fp-ui{background-size:auto}
+.is-seeking.flowplayer .fp-ui,.is-loading.flowplayer .fp-ui{background-image:none}
+.flowplayer .fp-brand{color:#fff !important;position:absolute;right:115px;font-weight:normal !important;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;text-decoration:none !important;line-height:15px !important;font-size:11px !important;height:15px;width:55px;bottom:9px;box-sizing:border-box;text-align:center;padding:1px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
+.has-menu.flowplayer .fp-brand{right:152px}
+.is-rtl.flowplayer .fp-brand{right:auto;left:125px}
+.has-menu.is-rtl.flowplayer .fp-brand{left:152px}
+.no-brand.flowplayer .fp-brand{display:none}
+.no-volume.no-mute.flowplayer .fp-brand{right:10px;}
+.has-menu.no-volume.no-mute.flowplayer .fp-brand{right:47px}
+.no-volume.flowplayer .fp-brand{right:50px}
+.no-mute.flowplayer .fp-brand{right:95px}
+.flowplayer .fp-logo{position:absolute;top:auto;left:15px;bottom:40px;cursor:pointer;display:none;z-index:100;}
+.flowplayer .fp-logo img{width:100%}
+.is-embedded.flowplayer .fp-logo{display:block}
+.fixed-controls.flowplayer .fp-logo{bottom:15px}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close{position:absolute;top:10px;left:auto;right:10px;display:block;width:30px;height:23px;text-align:center;cursor:pointer;height:30px;width:30px;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-close{right:auto;left:10px}
+.flowplayer .fp-unload,.flowplayer .fp-close{display:none}
+.flowplayer .fp-play{display:none;height:30px !important;position:absolute;bottom:0;left:0;text-align:center;}
+.is-rtl.flowplayer .fp-play{left:auto;right:0}
+.is-playing.flowplayer .fp-play:before{content:"\e607"}
+.flowplayer .fp-menu{display:none;position:absolute;bottom:0;z-index:11;right:10px;}
+.is-rtl.flowplayer .fp-menu{right:auto;left:10px}
+.has-menu.flowplayer .fp-menu{display:block}
+.flowplayer .fp-menu .fp-dropdown{z-index:12;display:none;left:-42.5px;line-height:auto;width:149px;-webkit-transform:none;-moz-transform:none;transform:none;}
+.is-rtl.flowplayer .fp-menu .fp-dropdown{left:-10px}
+.flowplayer .fp-menu.dropdown-open .fp-dropdown{display:block}
+.flowplayer.is-ready.is-closeable .fp-unload{display:block}
+.flowplayer.is-ready.is-closeable .fp-embed{right:90px}
+.flowplayer.is-ready.is-closeable .fp-fullscreen{right:50px}
+.flowplayer.is-fullscreen .fp-fullscreen{display:block !important;}
+.flowplayer.is-fullscreen .fp-fullscreen:before{content:"\e601"}
+.flowplayer .fp-timeline{height:3px;position:relative;overflow:hidden;top:10px;height:10px;margin:0 225px 0 55px;}
+.no-brand.flowplayer .fp-timeline{margin-right:160px;}
+.has-menu.no-brand.flowplayer .fp-timeline{margin-right:187px}
+.no-volume.no-brand.flowplayer .fp-timeline{margin-right:95px}
+.no-mute.no-brand.flowplayer .fp-timeline{margin-right:130px}
+.no-mute.no-volume.no-brand.flowplayer .fp-timeline{margin-right:55px}
+.has-menu.flowplayer .fp-timeline{margin-right:252px}
+.no-volume.flowplayer .fp-timeline{margin-right:160px}
+.no-mute.flowplayer .fp-timeline{margin-right:195px}
+.no-mute.no-volume.flowplayer .fp-timeline{margin-right:120px;}
+.has-menu.no-mute.no-volume.flowplayer .fp-timeline{margin-right:157px}
+.is-rtl.flowplayer .fp-timeline{margin:0 55px 0 225px;}
+.no-brand.is-rtl.flowplayer .fp-timeline{margin-left:160px;}
+.has-menu.no-brand.is-rtl.flowplayer .fp-timeline{margin-left:197px}
+.has-menu.is-rtl.flowplayer .fp-timeline{margin-left:262px}
+.no-volume.is-rtl.flowplayer .fp-timeline{margin-left:95px}
+.no-mute.is-rtl.flowplayer .fp-timeline{margin-left:130px}
+.no-mute.no-volume.is-rtl.flowplayer .fp-timeline{margin-left:55px}
+.is-long.flowplayer .fp-timeline{margin:0 255px 0 85px;}
+.no-volume.is-long.flowplayer .fp-timeline{margin-right:180px}
+.no-mute.is-long.flowplayer .fp-timeline{margin-right:140px}
+.has-menu.is-long.flowplayer .fp-timeline{margin-right:292px}
+.no-brand.is-long.flowplayer .fp-timeline{margin-right:190px;}
+.no-volume.no-brand.is-long.flowplayer .fp-timeline{margin-right:125px}
+.no-mute.no-brand.is-long.flowplayer .fp-timeline{margin-right:85px}
+.has-menu.no-brand.is-long.flowplayer .fp-timeline{margin-right:227px}
+.is-rtl.is-long.flowplayer .fp-timeline{margin:85px 0 190px 0;}
+.no-volume.is-rtl.is-long.flowplayer .fp-timeline{margin-left:125px}
+.no-mute.is-rtl.is-long.flowplayer .fp-timeline{margin-left:85px}
+.aside-time.flowplayer .fp-timeline,.no-time.flowplayer .fp-timeline{margin:0 190px 0 10px;}
+.has-menu.aside-time.flowplayer .fp-timeline,.has-menu.no-time.flowplayer .fp-timeline{margin-right:227px}
+.aside-time.no-brand.flowplayer .fp-timeline{margin-right:115px}
+.aside-time.no-volume.flowplayer .fp-timeline,.no-time.no-volume.flowplayer .fp-timeline{margin-right:115px}
+.aside-time.no-mute.flowplayer .fp-timeline,.no-time.no-mute.flowplayer .fp-timeline{margin-right:75px}
+.is-rtl.aside-time.flowplayer .fp-timeline,.is-rtl.no-time.flowplayer .fp-timeline{margin:0 10px 0 115px}
+.is-rtl.aside-time.no-volume.flowplayer .fp-timeline,.is-rtl.no-time.no-volume.flowplayer .fp-timeline{margin-left:50px}
+.is-rtl.aside-time.no-mute.flowplayer .fp-timeline,.is-rtl.no-time.no-mute.flowplayer .fp-timeline{margin-left:10px}
+.flowplayer .fp-buffer,.flowplayer .fp-progress{position:absolute;top:0;left:auto;height:100%;cursor:col-resize}
+.flowplayer .fp-buffer{-webkit-transition:width .25s linear;-moz-transition:width .25s linear;transition:width .25s linear}
+.flowplayer .fp-timeline.no-animation .fp-buffer{-webkit-transition:none;-moz-transition:none;transition:none}
+.flowplayer .fp-progress.animated{transition-timing-function:linear;transition-property:width,height}
+.flowplayer.is-touch .fp-timeline{overflow:visible}
+.flowplayer.is-touch .fp-progress{-webkit-transition:width .2s linear;-moz-transition:width .2s linear;transition:width .2s linear;box-sizing:border-box}
+.flowplayer.is-touch .fp-timeline.is-dragging .fp-progress{-webkit-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;-moz-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear}
+.flowplayer.is-touch.is-mouseover .fp-progress:after,.flowplayer.is-touch.is-mouseover .fp-progress:before{content:'';box-sizing:border-box;display:block;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;position:absolute;right:-5px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:after,.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:before{right:auto;left:-5px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:after{left:-10px;-webkit-box-shadow:-1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:-1px 0 4px rgba(0,0,0,0.5);box-shadow:-1px 0 4px rgba(0,0,0,0.5)}
+.flowplayer.is-touch.is-mouseover .fp-progress:before{width:10px;height:10px}
+.flowplayer.is-touch.is-mouseover .fp-progress:after{height:18px;width:18px;top:-4px;right:-10px;border:5px solid rgba(255,255,255,0.65);-webkit-box-shadow:1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:1px 0 4px rgba(0,0,0,0.5);box-shadow:1px 0 4px rgba(0,0,0,0.5)}
+.flowplayer.is-touch.is-mouseover .fp-timeline.is-dragging .fp-progress:after{border:10px solid #fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px;-webkit-transition:inherit;-moz-transition:inherit;transition:inherit;top:-5px;right:-10px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-timeline.is-dragging .fp-progress:after{left:-15px;right:auto;border:10px solid #fff}
+.flowplayer .fp-volume{position:absolute;top:12px;right:10px;}
+.has-menu.flowplayer .fp-volume{right:37px}
+.is-rtl.flowplayer .fp-volume{right:auto;left:10px}
+.is-rtl.has-menu.flowplayer .fp-volume{left:37px}
+.flowplayer .fp-mute{position:relative;width:30px;height:30px;float:left;top:-12px;cursor:pointer;}
+.is-rtl.flowplayer .fp-mute{float:right}
+.no-mute.flowplayer .fp-mute{display:none}
+.flowplayer .fp-volumeslider{width:75px;height:6px;cursor:col-resize;float:left;}
+.is-rtl.flowplayer .fp-volumeslider{float:right}
+.no-volume.flowplayer .fp-volumeslider{display:none}
+.flowplayer .fp-volumelevel{height:100%}
+.flowplayer .fp-time{text-shadow:0 0 1px #000;font-size:11px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;color:#fff;width:100%;}
+.flowplayer .fp-time.is-inverted .fp-duration{display:none}
+.flowplayer .fp-time.is-inverted .fp-remaining{display:inline}
+.flowplayer .fp-time em{width:35px;height:10px;line-height:10px;text-align:center;position:absolute;bottom:9px}
+.no-time.flowplayer .fp-time{display:none}
+.is-long.flowplayer .fp-time em{width:65px}
+.flowplayer .fp-elapsed{left:10px;}
+.is-rtl.flowplayer .fp-elapsed{left:auto;right:10px}
+.flowplayer .fp-remaining,.flowplayer .fp-duration{right:180px;color:#eee;}
+.no-brand.flowplayer .fp-remaining,.no-brand.flowplayer .fp-duration{right:125px;}
+.has-menu.no-brand.flowplayer .fp-remaining,.has-menu.no-brand.flowplayer .fp-duration{right:152px}
+.no-volume.no-brand.flowplayer .fp-remaining,.no-volume.no-brand.flowplayer .fp-duration{right:50px}
+.no-mute.no-brand.flowplayer .fp-remaining,.no-mute.no-brand.flowplayer .fp-duration{right:95px}
+.no-mute.no-volume.no-brand.flowplayer .fp-remaining,.no-mute.no-volume.no-brand.flowplayer .fp-duration{right:10px}
+.has-menu.flowplayer .fp-remaining,.has-menu.flowplayer .fp-duration{right:217px}
+.no-volume.flowplayer .fp-remaining,.no-volume.flowplayer .fp-duration{right:115px}
+.no-mute.flowplayer .fp-remaining,.no-mute.flowplayer .fp-duration{right:160px}
+.no-mute.no-volume.flowplayer .fp-remaining,.no-mute.no-volume.flowplayer .fp-duration{right:75px;}
+.has-menu.no-mute.no-volume.flowplayer .fp-remaining,.has-menu.no-mute.no-volume.flowplayer .fp-duration{right:112px}
+.is-rtl.flowplayer .fp-remaining,.is-rtl.flowplayer .fp-duration{right:auto;left:180px;}
+.no-brand.is-rtl.flowplayer .fp-remaining,.no-brand.is-rtl.flowplayer .fp-duration{left:115px;}
+.has-menu.no-brand.is-rtl.flowplayer .fp-remaining,.has-menu.no-brand.is-rtl.flowplayer .fp-duration{left:142px}
+.has-menu.is-rtl.flowplayer .fp-remaining,.has-menu.is-rtl.flowplayer .fp-duration{left:207px}
+.no-volume.is-rtl.flowplayer .fp-remaining,.no-volume.is-rtl.flowplayer .fp-duration{left:50px}
+.no-mute.is-rtl.flowplayer .fp-remaining,.no-mute.is-rtl.flowplayer .fp-duration{left:95px}
+.no-mute.no-volume.is-rtl.flowplayer .fp-remaining,.no-mute.no-volume.is-rtl.flowplayer .fp-duration{left:10px}
+.flowplayer .fp-remaining{display:none}
+.flowplayer.aside-time .fp-time{position:absolute;top:10px;left:10px;bottom:auto !important;width:auto;background-color:#000;background-color:rgba(0,0,0,0.65);height:30px;padding:0 5px;-webkit-border-radius:control_border_radius;-moz-border-radius:control_border_radius;border-radius:control_border_radius;line-height:30px;text-align:center;font-size:15px;}
+.no-background.flowplayer.aside-time .fp-time{background-color:transparent !important}
+.flowplayer.aside-time .fp-time strong,.flowplayer.aside-time .fp-time em{position:static}
+.flowplayer.aside-time .fp-time .fp-elapsed::after{content:' / '}
+.flowplayer.is-splash,.flowplayer.is-poster{cursor:pointer;}
+.flowplayer.is-splash .fp-controls,.flowplayer.is-poster .fp-controls,.flowplayer.is-splash .fp-fullscreen,.flowplayer.is-poster .fp-fullscreen,.flowplayer.is-splash .fp-unload,.flowplayer.is-poster .fp-unload,.flowplayer.is-splash .fp-time,.flowplayer.is-poster .fp-time,.flowplayer.is-splash .fp-embed,.flowplayer.is-poster .fp-embed,.flowplayer.is-splash .fp-title,.flowplayer.is-poster .fp-title,.flowplayer.is-splash .fp-brand,.flowplayer.is-poster .fp-brand{display:none !important}
+.flowplayer.is-poster .fp-engine{top:-9999em}
+.flowplayer.is-loading .fp-waiting{display:block}
+.flowplayer.is-loading .fp-controls,.flowplayer.is-loading .fp-time{display:none}
+.flowplayer.is-loading .fp-ui{background-position:-9999em}
+.flowplayer.is-loading video.fp-engine{position:absolute;top:-9999em}
+.flowplayer.is-seeking .fp-waiting{display:block}
+.flowplayer.is-playing{background-image:none !important;background-color:#333;}
+.flowplayer.is-playing.hls-fix.is-finished .fp-engine{position:absolute;top:-9999em}
+.flowplayer.is-fullscreen{top:0 !important;left:0 !important;border:0 !important;margin:0 !important;width:100% !important;height:100% !important;max-width:100% !important;z-index:99999 !important;-webkit-box-shadow:0 !important;-moz-box-shadow:0 !important;box-shadow:0 !important;background-image:none !important;background-color:#333;}
+.is-rtl.flowplayer.is-fullscreen{left:auto !important;right:0 !important}
+.flowplayer.is-fullscreen .fp-player{background-color:#333}
+.flowplayer.is-error{border:1px solid #909090;background:#fdfdfd !important;}
+.flowplayer.is-error h2{font-weight:bold;font-size:large;margin-top:10%}
+.flowplayer.is-error .fp-message{display:block}
+.flowplayer.is-error object,.flowplayer.is-error video,.flowplayer.is-error .fp-controls,.flowplayer.is-error .fp-time,.flowplayer.is-error .fp-subtitle{display:none}
+.flowplayer.is-ready.is-muted .fp-mute{opacity:.7;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70)}
+.flowplayer.is-ready.is-muted .fp-mute:before{content:"\e605"}
+.flowplayer.is-mouseout .fp-controls,.flowplayer.is-mouseout .fp-title{height:0;-webkit-transition:height .15s .3s;-moz-transition:height .15s .3s;transition:height .15s .3s}
+.is-fullscreen.flowplayer.is-mouseout .fp-controls{height:3px;bottom:0}
+.flowplayer.is-mouseout .fp-title{overflow:hidden}
+.flowplayer.is-mouseout .fp-timeline{margin:0 !important}
+.flowplayer.is-mouseout .fp-timeline{-webkit-transition:height .15s .3s,top .15s .3s,margin .15s .3s;-moz-transition:height .15s .3s,top .15s .3s,margin .15s .3s;transition:height .15s .3s,top .15s .3s,margin .15s .3s;height:4px;top:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
+.flowplayer.is-mouseout .fp-fullscreen,.flowplayer.is-mouseout .fp-unload,.flowplayer.is-mouseout .fp-elapsed,.flowplayer.is-mouseout .fp-remaining,.flowplayer.is-mouseout .fp-duration,.flowplayer.is-mouseout .fp-embed,.flowplayer.is-mouseout .fp-volume,.flowplayer.is-mouseout .fp-play,.flowplayer.is-mouseout .fp-menu,.flowplayer.is-mouseout .fp-brand,.flowplayer.is-mouseout .fp-timeline-tooltip,.flowplayer.is-mouseout.aside-time .fp-time{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .15s .3s;-moz-transition:opacity .15s .3s;transition:opacity .15s .3s}
+.flowplayer.is-mouseover .fp-controls,.flowplayer.fixed-controls .fp-controls{height:30px}
+.flowplayer.is-mouseover .fp-title,.flowplayer.fixed-controls .fp-title{height:30px}
+.flowplayer.is-mouseover .fp-fullscreen,.flowplayer.fixed-controls .fp-fullscreen,.flowplayer.is-mouseover .fp-unload,.flowplayer.fixed-controls .fp-unload,.flowplayer.is-mouseover .fp-elapsed,.flowplayer.fixed-controls .fp-elapsed,.flowplayer.is-mouseover .fp-remaining,.flowplayer.fixed-controls .fp-remaining,.flowplayer.is-mouseover .fp-duration,.flowplayer.fixed-controls .fp-duration,.flowplayer.is-mouseover .fp-embed,.flowplayer.fixed-controls .fp-embed,.flowplayer.is-mouseover .fp-logo,.flowplayer.fixed-controls .fp-logo,.flowplayer.is-mouseover .fp-volume,.flowplayer.fixed-controls .fp-volume,.flowplayer.is-mouseover .fp-play,.flowplayer.fixed-controls .fp-play,.flowplayer.is-mouseover .fp-menu,.flowplayer.fixed-controls .fp-menu{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer.fixed-controls .fp-volume{display:block}
+.flowplayer.fixed-controls .fp-controls{bottom:-30px;}
+.is-fullscreen.flowplayer.fixed-controls .fp-controls{bottom:0}
+.flowplayer.fixed-controls .fp-time em{bottom:-20px;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);}
+.is-fullscreen.flowplayer.fixed-controls .fp-time em{bottom:10px}
+.flowplayer.is-disabled .fp-progress{background-color:#999}
+.flowplayer.is-flash-disabled{background-color:#333;}
+.flowplayer.is-flash-disabled object.fp-engine{z-index:100}
+.flowplayer.is-flash-disabled .fp-flash-disabled{display:block;z-index:101}
+.flowplayer .fp-embed{position:absolute;top:10px;left:auto;right:50px;display:block;width:30px;height:30px;text-align:center;}
+.is-rtl.flowplayer .fp-embed{right:auto;left:50px}
+.flowplayer .fp-embed-code{position:absolute;display:none;top:10px;right:67px;background-color:#333;padding:3px 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 3px #ccc;-moz-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc;font-size:12px;}
+.is-closeable.flowplayer .fp-embed-code{right:99px}
+.flowplayer .fp-embed-code:before{content:'';width:0;height:0;position:absolute;top:2px;right:-10px;border:5px solid transparent;border-left-color:#333}
+.is-rtl.flowplayer .fp-embed-code{right:auto;left:67px;}
+.is-rtl.flowplayer .fp-embed-code:before{right:auto;left:-10px;border-left-color:transparent;border-right-color:#333}
+.flowplayer .fp-embed-code textarea{width:400px;height:16px;font-family:monaco,"courier new",verdana;color:#777;white-space:nowrap;resize:none;overflow:hidden;border:0;outline:0;background-color:transparent;color:#ccc}
+.flowplayer .fp-embed-code label{display:block;color:#999}
+.flowplayer.is-embedding .fp-embed,.flowplayer.is-embedding .fp-embed-code{display:block;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer.no-time .fp-embed{left:10px !important;}
+.is-rtl.flowplayer.no-time .fp-embed{left:auto;right:10px !important}
+.flowplayer.is-live .fp-timeline,.flowplayer.is-live .fp-duration,.flowplayer.is-live .fp-remaining{display:none}
+.flowplayer .fp-context-menu{position:absolute;display:none;z-index:1001;background-color:#fff;padding:10px;border:1px solid #aaa;-webkit-box-shadow:0 0 4px #888;-moz-box-shadow:0 0 4px #888;box-shadow:0 0 4px #888;width:170px;}
+.flowplayer .fp-context-menu li{text-align:center !important;padding:10px;color:#444 !important;font-size:11px !important;margin:0 -10px 0 -10px;}
+.flowplayer .fp-context-menu li a{color:#00a7c8 !important;font-size:12.100000000000001px !important}
+.flowplayer .fp-context-menu li:hover:not(.copyright){background-color:#eee}
+.flowplayer .fp-context-menu li.copyright{margin:0;padding-left:110px;background-image:url("img/flowplayer.png");background-repeat:no-repeat;background-size:100px 20px;background-position:5px 5px;border-bottom:1px solid #bbb;}
+@media (-webkit-min-device-pixel-ratio: 2){.flowplayer .fp-context-menu li.copyright{background-image:url("img/flowplayer@2x.png")}
+}@-moz-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-webkit-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-o-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-ms-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}.flowplayer.is-touch.is-mouseover .fp-progress:before{background-color:#00a7c8}
+.flowplayer .fp-menu .fp-dropdown{right:-10px;left:auto;bottom:30px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
+.flowplayer .fp-menu .fp-dropdown:before{display:none}
+.flowplayer .fp-play{width:30px}
+.flowplayer.aside-time .fp-time{top:0;left:0}
+.no-brand.flowplayer .fp-remaining,.no-brand.flowplayer .fp-duration{right:115px}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close,.flowplayer .fp-embed{right:0;top:0;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-close,.is-rtl.flowplayer .fp-embed{right:auto;left:0}
+.flowplayer .fp-embed{right:32px;}
+.is-rtl.flowplayer .fp-embed{right:auto;left:32px}
+.flowplayer.is-closeable.is-ready .fp-fullscreen{right:32px}
+.flowplayer.is-closeable.is-ready .fp-embed{right:64px}
+.flowplayer.play-button .fp-play{display:block}
+.flowplayer.play-button .fp-elapsed{left:27px;}
+.is-rtl.flowplayer.play-button .fp-elapsed{right:27px}
+.flowplayer.play-button .fp-timeline{margin-left:72px;}
+.is-rtl.flowplayer.play-button .fp-timeline{margin-right:72px}
+.is-long.flowplayer.play-button .fp-timeline{margin-left:102px;}
+.is-rtl.is-long.flowplayer.play-button .fp-timeline{margin-right:102px}
+.no-time.flowplayer.play-button .fp-timeline,.aside-time.flowplayer.play-button .fp-timeline{margin-left:27px;}
+.is-rtl.no-time.flowplayer.play-button .fp-timeline,.is-rtl.aside-time.flowplayer.play-button .fp-timeline{margin-right:27px}
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/flowplayer/skin/playful.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/flowplayer/skin/playful.css Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,349 @@
+@font-face {
+ font-family: 'fpicons';
+ src:url('fonts/fpicons.eot?yg5dv7');
+ src:url('fonts/fpicons.eot?#iefixyg5dv7') format('embedded-opentype'),
+ url('fonts/fpicons.woff?yg5dv7') format('woff'),
+ url('fonts/fpicons.ttf?yg5dv7') format('truetype'),
+ url('fonts/fpicons.svg?yg5dv7#fpicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="fp-i-"], [class*=" fp-i-"] {
+ font-family: 'fpicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.flowplayer{position:relative;width:100%;counter-increment:flowplayer;background-size:contain;background-repeat:no-repeat;background-position:center center;display:inline-block;}
+.flowplayer *{font-weight:inherit;font-family:inherit;font-style:inherit;text-decoration:inherit;font-size:100%;padding:0;border:0;margin:0;list-style-type:none}
+.flowplayer a:focus{outline:0}
+.flowplayer video{width:100%}
+.flowplayer.is-ipad video{-webkit-transform:translateX(-2048px);}
+.is-ready.flowplayer.is-ipad video{-webkit-transform:translateX(0)}
+.flowplayer .fp-player{position:absolute;top:0;left:0;width:100%;height:100%}
+.flowplayer .fp-engine,.flowplayer .fp-ui,.flowplayer .fp-message{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;z-index:1}
+.flowplayer .fp-ui{z-index:11}
+.flowplayer .fp-message{display:none;text-align:center;padding-top:5%;cursor:default;}
+.flowplayer .fp-message h2{font-size:120%;margin-bottom:1em}
+.flowplayer .fp-message p{color:#666;font-size:95%}
+.flowplayer .fp-title{line-height:35px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif;font-size:11px;cursor:default;color:#fff;width:auto;max-width:50%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;float:left;padding:0 24px;}
+.is-rtl.flowplayer .fp-title{float:right}
+.aside-time.flowplayer .fp-title{display:none !important}
+.flowplayer .fp-controls{position:absolute;bottom:0;width:100%;}
+.no-background.flowplayer .fp-controls{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important}
+.is-fullscreen.flowplayer .fp-controls{bottom:3px}
+.is-mouseover.flowplayer .fp-controls{bottom:0}
+.flowplayer .fp-controls,.flowplayer .fp-title,.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close,.flowplayer .fp-embed,.flowplayer.aside-time .fp-time{background-color:#000;background-color:rgba(0,0,0,0.65);}
+.no-background.flowplayer .fp-controls,.no-background.flowplayer .fp-title,.no-background.flowplayer .fp-fullscreen,.no-background.flowplayer .fp-unload,.no-background.flowplayer .fp-close,.no-background.flowplayer .fp-embed,.no-background.flowplayer.aside-time .fp-time{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.no-background.flowplayer .fp-play,.no-background.flowplayer .fp-brand{background-color:transparent !important;background-image:-webkit-gradient(linear,left top,left bottom,from(transparent),to(transparent)) !important;background-image:-webkit-linear-gradient(top,transparent,transparent) !important;background-image:-moz-linear-gradient(top,transparent,transparent) !important;background-image:-o-linear-gradient(top,transparent,transparent) !important;background-image:linear-gradient(to bottom,transparent,transparent) !important;text-shadow:0 0 1px #000}
+.flowplayer.fixed-controls .fp-controls{background-color:#000}
+.flowplayer .fp-timeline{background-color:#a5a5a5}
+.flowplayer .fp-buffer{background-color:#eee}
+.flowplayer .fp-progress{background-color:#00a7c8}
+.flowplayer .fp-volumeslider{background-color:#a5a5a5}
+.flowplayer .fp-volumelevel{background-color:#00a7c8}
+.flowplayer .fp-waiting{display:none;margin:19% auto;text-align:center;}
+.flowplayer .fp-waiting *{-webkit-box-shadow:0 0 5px #333;-moz-box-shadow:0 0 5px #333;box-shadow:0 0 5px #333}
+.flowplayer .fp-waiting em{width:1em;height:1em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;background-color:rgba(255,255,255,0.8);display:inline-block;-webkit-animation:pulse .6s infinite;-moz-animation:pulse .6s infinite;animation:pulse .6s infinite;margin:.3em;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);}
+.flowplayer .fp-waiting em:nth-child(1){-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s}
+.flowplayer .fp-waiting em:nth-child(2){-webkit-animation-delay:.45s;-moz-animation-delay:.45s;animation-delay:.45s}
+.flowplayer .fp-waiting em:nth-child(3){-webkit-animation-delay:.6s;-moz-animation-delay:.6s;animation-delay:.6s}
+.flowplayer .fp-waiting p{color:#ccc;font-weight:bold}
+.flowplayer .fp-speed{font-size:30px;background-color:#333;background-color:rgba(51,51,51,0.8);color:#eee;margin:0 auto;text-align:center;width:120px;padding:.1em 0 0;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .5s;-moz-transition:opacity .5s;transition:opacity .5s;}
+.flowplayer .fp-speed.fp-hilite{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-help{position:absolute;top:0;left:-9999em;z-index:100;background-color:#333;background-color:rgba(51,51,51,0.9);width:100%;height:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s;text-align:center;}
+.is-help.flowplayer .fp-help{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-help .fp-help-section{margin:3%;direction:ltr}
+.flowplayer .fp-help .fp-help-basics{margin-top:6%}
+.flowplayer .fp-help p{color:#eee;margin:.5em 0;font-size:14px;line-height:1.5;display:inline-block;margin:1% 2%}
+.flowplayer .fp-help em{background:#eee;-webkit-border-radius:.3em;-moz-border-radius:.3em;border-radius:.3em;margin-right:.4em;padding:.3em .6em;color:#333}
+.flowplayer .fp-help small{font-size:90%;color:#aaa}
+.flowplayer .fp-help .fp-close{display:block}
+@media (max-width: 600px){.flowplayer .fp-help p{font-size:9px}
+}.flowplayer .fp-dropdown{position:absolute;top:5px;width:100px;background-color:#000 !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;margin:0 !important;list-style-type:none !important;}
+.flowplayer .fp-dropdown:before{content:'';display:block;position:absolute;top:-5px;left:calc(50% - 5px);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid rgba(51,51,51,0.9)}
+.flowplayer .fp-dropdown li{padding:12px !important;margin:0 !important;color:#fff !important;font-size:11px !important;list-style-type:none !important;}
+.flowplayer .fp-dropdown li.active{background-color:#00a7c8 !important;cursor:default !important}
+.flowplayer .fp-dropdown.fp-dropup{bottom:20px;top:auto;}
+.flowplayer .fp-dropdown.fp-dropup:before{top:auto;bottom:-5px;border-bottom:none;border-top:5px solid rgba(51,51,51,0.9)}
+.flowplayer .fp-tooltip{background-color:#000;color:#fff;display:none;position:absolute;padding:5px;}
+.flowplayer .fp-tooltip:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;left:calc(50% - 5px);border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000}
+.flowplayer .fp-timeline-tooltip{bottom:41px}
+.flowplayer .fp-timeline:hover+.fp-timeline-tooltip{display:block}
+.flowplayer .fp-subtitle{position:absolute;bottom:40px;left:-99999em;z-index:10;text-align:center;width:100%;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .3s;-moz-transition:opacity .3s;transition:opacity .3s;}
+.flowplayer .fp-subtitle p{display:inline;background-color:#333;background-color:rgba(51,51,51,0.9);color:#eee;padding:.1em .4em;font-size:16px;line-height:1.6;}
+.flowplayer .fp-subtitle p:after{content:'';clear:both}
+.flowplayer .fp-subtitle p b{font-weight:bold}
+.flowplayer .fp-subtitle p i{font-style:italic}
+.flowplayer .fp-subtitle p u{text-decoration:underline}
+.flowplayer .fp-subtitle.fp-active{left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-mute,.flowplayer .fp-embed,.flowplayer .fp-close,.flowplayer .fp-play,.flowplayer .fp-menu{font-family:'fpicons' !important;color:#fff !important;font-size:15px !important;text-align:center !important;line-height:30px !important;text-decoration:none !important;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-mute,.is-rtl.flowplayer .fp-embed,.is-rtl.flowplayer .fp-close,.is-rtl.flowplayer .fp-play,.is-rtl.flowplayer .fp-menu{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);transform:scale(-1,1)}
+.is-rtl.flowplayer .fp-menu{-webkit-transform:none;-moz-transform:none;transform:none}
+.flowplayer .fp-fullscreen:before{content:"\e602"}
+.flowplayer .fp-unload:before,.flowplayer .fp-close:before{content:"\e600"}
+.flowplayer .fp-mute:before{content:"\e606"}
+.flowplayer .fp-embed:before{content:"\e603"}
+.flowplayer .fp-play:before{content:"\e608"}
+.flowplayer .fp-menu:before{content:"\e604"}
+.flowplayer .fp-flash-disabled{background:#333;width:390px;margin:0 auto;position:absolute;bottom:0;color:#fff}
+.is-splash.flowplayer .fp-ui,.is-paused.flowplayer .fp-ui{background:url(img/play_white.png) center no-repeat;background-size:11%;}
+.is-rtl.is-splash.flowplayer .fp-ui,.is-rtl.is-paused.flowplayer .fp-ui{background:url(img/play_white_rtl.png) center no-repeat;background-size:11%}
+@media (-webkit-min-device-pixel-ratio: 2){.is-splash.flowplayer .fp-ui,.is-paused.flowplayer .fp-ui{background:url(img/play_white@x2.png) center no-repeat;background-size:11%}
+.is-rtl.is-splash.flowplayer .fp-ui,.is-rtl.is-paused.flowplayer .fp-ui{background:url(img/play_white_rtl@x2.png) center no-repeat;background-size:11%}
+}.is-fullscreen.flowplayer .fp-ui{background-size:auto}
+.is-seeking.flowplayer .fp-ui,.is-loading.flowplayer .fp-ui{background-image:none}
+.flowplayer .fp-brand{color:#fff !important;position:absolute;right:124px;font-weight:normal !important;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;text-decoration:none !important;line-height:15px !important;font-size:11px !important;height:15px;width:55px;bottom:11px;box-sizing:border-box;text-align:center;padding:1px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
+.has-menu.flowplayer .fp-brand{right:161px}
+.is-rtl.flowplayer .fp-brand{right:auto;left:134px}
+.has-menu.is-rtl.flowplayer .fp-brand{left:161px}
+.no-brand.flowplayer .fp-brand{display:none}
+.no-volume.no-mute.flowplayer .fp-brand{right:12px;}
+.has-menu.no-volume.no-mute.flowplayer .fp-brand{right:51px}
+.no-volume.flowplayer .fp-brand{right:62px}
+.no-mute.flowplayer .fp-brand{right:99px}
+.flowplayer .fp-logo{position:absolute;top:auto;left:15px;bottom:45px;cursor:pointer;display:none;z-index:100;}
+.flowplayer .fp-logo img{width:100%}
+.is-embedded.flowplayer .fp-logo{display:block}
+.fixed-controls.flowplayer .fp-logo{bottom:15px}
+.flowplayer .fp-fullscreen,.flowplayer .fp-unload,.flowplayer .fp-close{position:absolute;top:12px;left:auto;right:12px;display:block;width:30px;height:23px;text-align:center;cursor:pointer;height:35px;width:35px;}
+.is-rtl.flowplayer .fp-fullscreen,.is-rtl.flowplayer .fp-unload,.is-rtl.flowplayer .fp-close{right:auto;left:12px}
+.flowplayer .fp-unload,.flowplayer .fp-close{display:none}
+.flowplayer .fp-play{display:none;height:35px !important;position:absolute;bottom:0;left:0;text-align:center;}
+.is-rtl.flowplayer .fp-play{left:auto;right:0}
+.is-playing.flowplayer .fp-play:before{content:"\e607"}
+.flowplayer .fp-menu{display:none;position:absolute;bottom:0;z-index:11;right:12px;}
+.is-rtl.flowplayer .fp-menu{right:auto;left:12px}
+.has-menu.flowplayer .fp-menu{display:block}
+.flowplayer .fp-menu .fp-dropdown{z-index:12;display:none;left:-42.5px;line-height:auto;width:153px;-webkit-transform:none;-moz-transform:none;transform:none;}
+.is-rtl.flowplayer .fp-menu .fp-dropdown{left:-12px}
+.flowplayer .fp-menu.dropdown-open .fp-dropdown{display:block}
+.flowplayer.is-ready.is-closeable .fp-unload{display:block}
+.flowplayer.is-ready.is-closeable .fp-embed{right:106px}
+.flowplayer.is-ready.is-closeable .fp-fullscreen{right:59px}
+.flowplayer.is-fullscreen .fp-fullscreen{display:block !important;}
+.flowplayer.is-fullscreen .fp-fullscreen:before{content:"\e601"}
+.flowplayer .fp-timeline{height:3px;position:relative;overflow:hidden;top:12px;height:11px;margin:0 238px 0 59px;}
+.no-brand.flowplayer .fp-timeline{margin-right:171px;}
+.has-menu.no-brand.flowplayer .fp-timeline{margin-right:198px}
+.no-volume.no-brand.flowplayer .fp-timeline{margin-right:109px}
+.no-mute.no-brand.flowplayer .fp-timeline{margin-right:133px}
+.no-mute.no-volume.no-brand.flowplayer .fp-timeline{margin-right:59px}
+.has-menu.flowplayer .fp-timeline{margin-right:265px}
+.no-volume.flowplayer .fp-timeline{margin-right:176px}
+.no-mute.flowplayer .fp-timeline{margin-right:200px}
+.no-mute.no-volume.flowplayer .fp-timeline{margin-right:126px;}
+.has-menu.no-mute.no-volume.flowplayer .fp-timeline{margin-right:165px}
+.is-rtl.flowplayer .fp-timeline{margin:0 59px 0 238px;}
+.no-brand.is-rtl.flowplayer .fp-timeline{margin-left:171px;}
+.has-menu.no-brand.is-rtl.flowplayer .fp-timeline{margin-left:210px}
+.has-menu.is-rtl.flowplayer .fp-timeline{margin-left:277px}
+.no-volume.is-rtl.flowplayer .fp-timeline{margin-left:109px}
+.no-mute.is-rtl.flowplayer .fp-timeline{margin-left:133px}
+.no-mute.no-volume.is-rtl.flowplayer .fp-timeline{margin-left:59px}
+.is-long.flowplayer .fp-timeline{margin:0 268px 0 89px;}
+.no-volume.is-long.flowplayer .fp-timeline{margin-right:194px}
+.no-mute.is-long.flowplayer .fp-timeline{margin-right:144px}
+.has-menu.is-long.flowplayer .fp-timeline{margin-right:307px}
+.no-brand.is-long.flowplayer .fp-timeline{margin-right:201px;}
+.no-volume.no-brand.is-long.flowplayer .fp-timeline{margin-right:139px}
+.no-mute.no-brand.is-long.flowplayer .fp-timeline{margin-right:89px}
+.has-menu.no-brand.is-long.flowplayer .fp-timeline{margin-right:240px}
+.is-rtl.is-long.flowplayer .fp-timeline{margin:89px 0 201px 0;}
+.no-volume.is-rtl.is-long.flowplayer .fp-timeline{margin-left:139px}
+.no-mute.is-rtl.is-long.flowplayer .fp-timeline{margin-left:89px}
+.aside-time.flowplayer .fp-timeline,.no-time.flowplayer .fp-timeline{margin:0 203px 0 12px;}
+.has-menu.aside-time.flowplayer .fp-timeline,.has-menu.no-time.flowplayer .fp-timeline{margin-right:242px}
+.aside-time.no-brand.flowplayer .fp-timeline{margin-right:124px}
+.aside-time.no-volume.flowplayer .fp-timeline,.no-time.no-volume.flowplayer .fp-timeline{margin-right:129px}
+.aside-time.no-mute.flowplayer .fp-timeline,.no-time.no-mute.flowplayer .fp-timeline{margin-right:79px}
+.is-rtl.aside-time.flowplayer .fp-timeline,.is-rtl.no-time.flowplayer .fp-timeline{margin:0 12px 0 124px}
+.is-rtl.aside-time.no-volume.flowplayer .fp-timeline,.is-rtl.no-time.no-volume.flowplayer .fp-timeline{margin-left:62px}
+.is-rtl.aside-time.no-mute.flowplayer .fp-timeline,.is-rtl.no-time.no-mute.flowplayer .fp-timeline{margin-left:12px}
+.flowplayer .fp-buffer,.flowplayer .fp-progress{position:absolute;top:0;left:auto;height:100%;cursor:col-resize}
+.flowplayer .fp-buffer{-webkit-transition:width .25s linear;-moz-transition:width .25s linear;transition:width .25s linear}
+.flowplayer .fp-timeline.no-animation .fp-buffer{-webkit-transition:none;-moz-transition:none;transition:none}
+.flowplayer .fp-progress.animated{transition-timing-function:linear;transition-property:width,height}
+.flowplayer.is-touch .fp-timeline{overflow:visible}
+.flowplayer.is-touch .fp-progress{-webkit-transition:width .2s linear;-moz-transition:width .2s linear;transition:width .2s linear;box-sizing:border-box}
+.flowplayer.is-touch .fp-timeline.is-dragging .fp-progress{-webkit-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;-moz-transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear;transition:right .1s linear,border .1s linear,top .1s linear,left .1s linear}
+.flowplayer.is-touch.is-mouseover .fp-progress:after,.flowplayer.is-touch.is-mouseover .fp-progress:before{content:'';box-sizing:border-box;display:block;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;position:absolute;right:-5px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:after,.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:before{right:auto;left:-5px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-progress:after{left:-10px;-webkit-box-shadow:-1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:-1px 0 4px rgba(0,0,0,0.5);box-shadow:-1px 0 4px rgba(0,0,0,0.5)}
+.flowplayer.is-touch.is-mouseover .fp-progress:before{width:10px;height:10px}
+.flowplayer.is-touch.is-mouseover .fp-progress:after{height:18px;width:18px;top:-4px;right:-10px;border:5px solid rgba(255,255,255,0.65);-webkit-box-shadow:1px 0 4px rgba(0,0,0,0.5);-moz-box-shadow:1px 0 4px rgba(0,0,0,0.5);box-shadow:1px 0 4px rgba(0,0,0,0.5)}
+.flowplayer.is-touch.is-mouseover .fp-timeline.is-dragging .fp-progress:after{border:10px solid #fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px;-webkit-transition:inherit;-moz-transition:inherit;transition:inherit;top:-5px;right:-10px}
+.flowplayer.is-touch.is-rtl.is-mouseover .fp-timeline.is-dragging .fp-progress:after{left:-15px;right:auto;border:10px solid #fff}
+.flowplayer .fp-volume{position:absolute;top:12px;right:12px;}
+.has-menu.flowplayer .fp-volume{right:39px}
+.is-rtl.flowplayer .fp-volume{right:auto;left:12px}
+.is-rtl.has-menu.flowplayer .fp-volume{left:39px}
+.flowplayer .fp-mute{position:relative;width:38px;height:20px;float:left;top:-4.5px;cursor:pointer;}
+.is-rtl.flowplayer .fp-mute{float:right}
+.no-mute.flowplayer .fp-mute{display:none}
+.flowplayer .fp-volumeslider{width:75px;height:11px;cursor:col-resize;float:left;}
+.is-rtl.flowplayer .fp-volumeslider{float:right}
+.no-volume.flowplayer .fp-volumeslider{display:none}
+.flowplayer .fp-volumelevel{height:100%}
+.flowplayer .fp-time{text-shadow:0 0 1px #000;font-size:11px;font-weight:normal;font-family:'myriad pro',Helvetica,Arial,sans-serif !important;color:#fff;width:100%;}
+.flowplayer .fp-time.is-inverted .fp-duration{display:none}
+.flowplayer .fp-time.is-inverted .fp-remaining{display:inline}
+.flowplayer .fp-time em{width:35px;height:11px;line-height:11px;text-align:center;position:absolute;bottom:11px}
+.no-time.flowplayer .fp-time{display:none}
+.is-long.flowplayer .fp-time em{width:65px}
+.flowplayer .fp-elapsed{left:12px;}
+.is-rtl.flowplayer .fp-elapsed{left:auto;right:12px}
+.flowplayer .fp-remaining,.flowplayer .fp-duration{right:191px;color:#eee;}
+.no-brand.flowplayer .fp-remaining,.no-brand.flowplayer .fp-duration{right:136px;}
+.has-menu.no-brand.flowplayer .fp-remaining,.has-menu.no-brand.flowplayer .fp-duration{right:163px}
+.no-volume.no-brand.flowplayer .fp-remaining,.no-volume.no-brand.flowplayer .fp-duration{right:62px}
+.no-mute.no-brand.flowplayer .fp-remaining,.no-mute.no-brand.flowplayer .fp-duration{right:99px}
+.no-mute.no-volume.no-brand.flowplayer .fp-remaining,.no-mute.no-volume.no-brand.flowplayer .fp-duration{right:12px}
+.has-menu.flowplayer .fp-remaining,.has-menu.flowplayer .fp-duration{right:230px}
+.no-volume.flowplayer .fp-remaining,.no-volume.flowplayer .fp-duration{right:129px}
+.no-mute.flowplayer .fp-remaining,.no-mute.flowplayer .fp-duration{right:166px}
+.no-mute.no-volume.flowplayer .fp-remaining,.no-mute.no-volume.flowplayer .fp-duration{right:79px;}
+.has-menu.no-mute.no-volume.flowplayer .fp-remaining,.has-menu.no-mute.no-volume.flowplayer .fp-duration{right:118px}
+.is-rtl.flowplayer .fp-remaining,.is-rtl.flowplayer .fp-duration{right:auto;left:191px;}
+.no-brand.is-rtl.flowplayer .fp-remaining,.no-brand.is-rtl.flowplayer .fp-duration{left:124px;}
+.has-menu.no-brand.is-rtl.flowplayer .fp-remaining,.has-menu.no-brand.is-rtl.flowplayer .fp-duration{left:151px}
+.has-menu.is-rtl.flowplayer .fp-remaining,.has-menu.is-rtl.flowplayer .fp-duration{left:218px}
+.no-volume.is-rtl.flowplayer .fp-remaining,.no-volume.is-rtl.flowplayer .fp-duration{left:62px}
+.no-mute.is-rtl.flowplayer .fp-remaining,.no-mute.is-rtl.flowplayer .fp-duration{left:99px}
+.no-mute.no-volume.is-rtl.flowplayer .fp-remaining,.no-mute.no-volume.is-rtl.flowplayer .fp-duration{left:12px}
+.flowplayer .fp-remaining{display:none}
+.flowplayer.aside-time .fp-time{position:absolute;top:12px;left:12px;bottom:auto !important;width:auto;background-color:#000;background-color:rgba(0,0,0,0.65);height:35px;padding:0 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;line-height:35px;text-align:center;font-size:15px;}
+.no-background.flowplayer.aside-time .fp-time{background-color:transparent !important}
+.flowplayer.aside-time .fp-time strong,.flowplayer.aside-time .fp-time em{position:static}
+.flowplayer.aside-time .fp-time .fp-elapsed::after{content:' / '}
+.flowplayer.is-splash,.flowplayer.is-poster{cursor:pointer;}
+.flowplayer.is-splash .fp-controls,.flowplayer.is-poster .fp-controls,.flowplayer.is-splash .fp-fullscreen,.flowplayer.is-poster .fp-fullscreen,.flowplayer.is-splash .fp-unload,.flowplayer.is-poster .fp-unload,.flowplayer.is-splash .fp-time,.flowplayer.is-poster .fp-time,.flowplayer.is-splash .fp-embed,.flowplayer.is-poster .fp-embed,.flowplayer.is-splash .fp-title,.flowplayer.is-poster .fp-title,.flowplayer.is-splash .fp-brand,.flowplayer.is-poster .fp-brand{display:none !important}
+.flowplayer.is-poster .fp-engine{top:-9999em}
+.flowplayer.is-loading .fp-waiting{display:block}
+.flowplayer.is-loading .fp-controls,.flowplayer.is-loading .fp-time{display:none}
+.flowplayer.is-loading .fp-ui{background-position:-9999em}
+.flowplayer.is-loading video.fp-engine{position:absolute;top:-9999em}
+.flowplayer.is-seeking .fp-waiting{display:block}
+.flowplayer.is-playing{background-image:none !important;background-color:#333;}
+.flowplayer.is-playing.hls-fix.is-finished .fp-engine{position:absolute;top:-9999em}
+.flowplayer.is-fullscreen{top:0 !important;left:0 !important;border:0 !important;margin:0 !important;width:100% !important;height:100% !important;max-width:100% !important;z-index:99999 !important;-webkit-box-shadow:0 !important;-moz-box-shadow:0 !important;box-shadow:0 !important;background-image:none !important;background-color:#333;}
+.is-rtl.flowplayer.is-fullscreen{left:auto !important;right:0 !important}
+.flowplayer.is-fullscreen .fp-player{background-color:#333}
+.flowplayer.is-error{border:1px solid #909090;background:#fdfdfd !important;}
+.flowplayer.is-error h2{font-weight:bold;font-size:large;margin-top:10%}
+.flowplayer.is-error .fp-message{display:block}
+.flowplayer.is-error object,.flowplayer.is-error video,.flowplayer.is-error .fp-controls,.flowplayer.is-error .fp-time,.flowplayer.is-error .fp-subtitle{display:none}
+.flowplayer.is-ready.is-muted .fp-mute{opacity:.7;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70)}
+.flowplayer.is-ready.is-muted .fp-mute:before{content:"\e605"}
+.flowplayer.is-mouseout .fp-controls,.flowplayer.is-mouseout .fp-title{height:0;-webkit-transition:height .15s .3s;-moz-transition:height .15s .3s;transition:height .15s .3s}
+.is-fullscreen.flowplayer.is-mouseout .fp-controls{height:3px;bottom:0}
+.flowplayer.is-mouseout .fp-title{overflow:hidden}
+.flowplayer.is-mouseout .fp-timeline{margin:0 !important}
+.flowplayer.is-mouseout .fp-timeline{-webkit-transition:height .15s .3s,top .15s .3s,margin .15s .3s;-moz-transition:height .15s .3s,top .15s .3s,margin .15s .3s;transition:height .15s .3s,top .15s .3s,margin .15s .3s;height:4px;top:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
+.flowplayer.is-mouseout .fp-fullscreen,.flowplayer.is-mouseout .fp-unload,.flowplayer.is-mouseout .fp-elapsed,.flowplayer.is-mouseout .fp-remaining,.flowplayer.is-mouseout .fp-duration,.flowplayer.is-mouseout .fp-embed,.flowplayer.is-mouseout .fp-volume,.flowplayer.is-mouseout .fp-play,.flowplayer.is-mouseout .fp-menu,.flowplayer.is-mouseout .fp-brand,.flowplayer.is-mouseout .fp-timeline-tooltip,.flowplayer.is-mouseout.aside-time .fp-time{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);-webkit-transition:opacity .15s .3s;-moz-transition:opacity .15s .3s;transition:opacity .15s .3s}
+.flowplayer.is-mouseover .fp-controls,.flowplayer.fixed-controls .fp-controls{height:35px}
+.flowplayer.is-mouseover .fp-title,.flowplayer.fixed-controls .fp-title{height:35px}
+.flowplayer.is-mouseover .fp-fullscreen,.flowplayer.fixed-controls .fp-fullscreen,.flowplayer.is-mouseover .fp-unload,.flowplayer.fixed-controls .fp-unload,.flowplayer.is-mouseover .fp-elapsed,.flowplayer.fixed-controls .fp-elapsed,.flowplayer.is-mouseover .fp-remaining,.flowplayer.fixed-controls .fp-remaining,.flowplayer.is-mouseover .fp-duration,.flowplayer.fixed-controls .fp-duration,.flowplayer.is-mouseover .fp-embed,.flowplayer.fixed-controls .fp-embed,.flowplayer.is-mouseover .fp-logo,.flowplayer.fixed-controls .fp-logo,.flowplayer.is-mouseover .fp-volume,.flowplayer.fixed-controls .fp-volume,.flowplayer.is-mouseover .fp-play,.flowplayer.fixed-controls .fp-play,.flowplayer.is-mouseover .fp-menu,.flowplayer.fixed-controls .fp-menu{opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer.fixed-controls .fp-volume{display:block}
+.flowplayer.fixed-controls .fp-controls{bottom:-35px;}
+.is-fullscreen.flowplayer.fixed-controls .fp-controls{bottom:0}
+.flowplayer.fixed-controls .fp-time em{bottom:-23px;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);}
+.is-fullscreen.flowplayer.fixed-controls .fp-time em{bottom:12px}
+.flowplayer.is-disabled .fp-progress{background-color:#999}
+.flowplayer.is-flash-disabled{background-color:#333;}
+.flowplayer.is-flash-disabled object.fp-engine{z-index:100}
+.flowplayer.is-flash-disabled .fp-flash-disabled{display:block;z-index:101}
+.flowplayer .fp-embed{position:absolute;top:12px;left:auto;right:59px;display:block;width:35px;height:35px;text-align:center;}
+.is-rtl.flowplayer .fp-embed{right:auto;left:59px}
+.flowplayer .fp-embed-code{position:absolute;display:none;top:10px;right:77px;background-color:#333;padding:3px 5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 3px #ccc;-moz-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc;font-size:12px;}
+.is-closeable.flowplayer .fp-embed-code{right:114px}
+.flowplayer .fp-embed-code:before{content:'';width:0;height:0;position:absolute;top:2px;right:-10px;border:5px solid transparent;border-left-color:#333}
+.is-rtl.flowplayer .fp-embed-code{right:auto;left:77px;}
+.is-rtl.flowplayer .fp-embed-code:before{right:auto;left:-10px;border-left-color:transparent;border-right-color:#333}
+.flowplayer .fp-embed-code textarea{width:400px;height:16px;font-family:monaco,"courier new",verdana;color:#777;white-space:nowrap;resize:none;overflow:hidden;border:0;outline:0;background-color:transparent;color:#ccc}
+.flowplayer .fp-embed-code label{display:block;color:#999}
+.flowplayer.is-embedding .fp-embed,.flowplayer.is-embedding .fp-embed-code{display:block;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+.flowplayer.no-time .fp-embed{left:12px !important;}
+.is-rtl.flowplayer.no-time .fp-embed{left:auto;right:12px !important}
+.flowplayer.is-live .fp-timeline,.flowplayer.is-live .fp-duration,.flowplayer.is-live .fp-remaining{display:none}
+.flowplayer .fp-context-menu{position:absolute;display:none;z-index:1001;background-color:#fff;padding:10px;border:1px solid #aaa;-webkit-box-shadow:0 0 4px #888;-moz-box-shadow:0 0 4px #888;box-shadow:0 0 4px #888;width:170px;}
+.flowplayer .fp-context-menu li{text-align:center !important;padding:10px;color:#444 !important;font-size:11px !important;margin:0 -10px 0 -10px;}
+.flowplayer .fp-context-menu li a{color:#00a7c8 !important;font-size:12.100000000000001px !important}
+.flowplayer .fp-context-menu li:hover:not(.copyright){background-color:#eee}
+.flowplayer .fp-context-menu li.copyright{margin:0;padding-left:110px;background-image:url("img/flowplayer.png");background-repeat:no-repeat;background-size:100px 20px;background-position:5px 5px;border-bottom:1px solid #bbb;}
+@media (-webkit-min-device-pixel-ratio: 2){.flowplayer .fp-context-menu li.copyright{background-image:url("img/flowplayer@2x.png")}
+}@-moz-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-webkit-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-o-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@-ms-keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}@keyframes pulse{0%{opacity:0}
+100%{opacity:1}
+}.flowplayer.is-touch.is-mouseover .fp-progress:before{background-color:#00a7c8}
+.flowplayer .fp-title{position:absolute;top:12px;left:12px;}
+.is-rtl.flowplayer .fp-title{left:auto;right:12px}
+.flowplayer .fp-title,.flowplayer .fp-unload,.flowplayer .fp-fullscreen,.flowplayer .fp-embed{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.flowplayer .fp-embed-code{right:99px;}
+.is-closeable.flowplayer .fp-embed-code{right:146px}
+.is-rtl.flowplayer .fp-embed-code{right:auto;left:99px}
+.flowplayer.is-mouseout .fp-menu{display:none}
+.flowplayer.is-mouseout .fp-controls{-webkit-transition:none;-moz-transition:none;transition:none;-webkit-animation:functional-controls-hide 1s 1;-moz-animation:functional-controls-hide 1s 1;animation:functional-controls-hide 1s 1}
+.flowplayer.is-mouseout .fp-timeline{-webkit-transition:none;-moz-transition:none;transition:none}
+.flowplayer.is-mouseout .fp-volume,.flowplayer.is-mouseout .fp-brand,.flowplayer.is-mouseout .fp-play,.flowplayer.is-mouseout .fp-time{-webkit-transition:none;-moz-transition:none;transition:none;opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+.flowplayer.fixed-controls .fp-elapsed,.flowplayer.fixed-controls.is-mouseover .fp-elapsed{left:59px}
+.flowplayer.fixed-controls .fp-controls,.flowplayer.fixed-controls.is-mouseover .fp-controls{bottom:-35px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;left:0;right:0;}
+.is-fullscreen.flowplayer.fixed-controls .fp-controls,.is-fullscreen.flowplayer.fixed-controls.is-mouseover .fp-controls{bottom:0}
+.flowplayer.fixed-controls .fp-controls .fp-play,.flowplayer.fixed-controls.is-mouseover .fp-controls .fp-play{left:12px}
+.flowplayer.fixed-controls .fp-controls .fp-timeline,.flowplayer.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:106px;}
+.is-long.flowplayer.fixed-controls .fp-controls .fp-timeline,.is-long.flowplayer.fixed-controls.is-mouseover .fp-controls .fp-timeline{margin-left:136px}
+.flowplayer.is-mouseover .fp-controls{bottom:12px;left:59px;right:12px;width:auto;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.flowplayer.is-mouseover .fp-controls{left:12px;right:59px}
+.flowplayer.is-mouseover .fp-controls .fp-play{left:-47px;display:block;background-color:#000;background-color:rgba(0,0,0,0.65);width:35px;height:35px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.is-rtl.flowplayer.is-mouseover .fp-controls .fp-play{left:auto;right:-47px}
+.flowplayer.is-mouseover .fp-controls .fp-timeline{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.flowplayer.is-mouseover .fp-controls .fp-timeline .fp-progress,.flowplayer.is-mouseover .fp-controls .fp-timeline .fp-buffer{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
+.flowplayer.is-mouseover .fp-controls .fp-menu .fp-dropdown{bottom:41px;left:auto;right:-12px;}
+.is-rtl.flowplayer.is-mouseover .fp-controls .fp-menu .fp-dropdown{right:auto;left:-12px}
+.flowplayer.is-mouseover .fp-controls .fp-menu .fp-dropdown:before{display:none}
+.flowplayer.is-mouseover .fp-controls li{border-color:#000;}
+.flowplayer.is-mouseover .fp-controls li.active{border-color:#00a7c8}
+.flowplayer.is-mouseover .fp-controls li:last-child:before{content:'';display:block;position:absolute;bottom:-5px;width:0;height:0;right:12px;border-bottom:none;border-top-width:5px;border-top-style:solid;border-top-color:inherit;border-left:5px solid transparent;border-right:5px solid transparent;}
+.is-rtl.flowplayer.is-mouseover .fp-controls li:last-child:before{right:auto;left:12px}
+.flowplayer .fp-elapsed,.flowplayer.play-button .fp-elapsed{left:71px;}
+.is-rtl.flowplayer .fp-elapsed,.is-rtl.flowplayer.play-button .fp-elapsed{right:71px;left:auto}
+.flowplayer .fp-time em{bottom:23px}
+@-moz-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-webkit-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-o-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@-ms-keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}@keyframes functional-controls-hide{0%{opacity:0;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0)}
+100%{bottom:0;right:0;left:0;opacity:1;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100)}
+}.flowplayer .fp-controls,.flowplayer .fp-title,.flowplayer .fp-embed,.flowplayer .fp-play,.flowplayer .fp-fullscreen,.flowplayer .fp-close,.flowplayer.aside-time .fp-time,.flowplayer .fp-unload{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(136,136,136,0.85)),to(rgba(0,0,0,0.85)));background-image:-webkit-linear-gradient(top,rgba(136,136,136,0.85),rgba(0,0,0,0.85));background-image:-moz-linear-gradient(top,rgba(136,136,136,0.85),rgba(0,0,0,0.85));background-image:-o-linear-gradient(top,rgba(136,136,136,0.85),rgba(0,0,0,0.85));background-image:linear-gradient(to bottom,rgba(136,136,136,0.85),rgba(0,0,0,0.85));color:#eee !important;}
+.flowplayer .fp-controls:before,.flowplayer .fp-title:before,.flowplayer .fp-embed:before,.flowplayer .fp-play:before,.flowplayer .fp-fullscreen:before,.flowplayer .fp-close:before,.flowplayer.aside-time .fp-time:before,.flowplayer .fp-unload:before{color:#eee}
+.flowplayer .fp-dropdown{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
+.flowplayer .fp-dropdown li:last-child{-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px}
+.flowplayer .fp-fullscreen:before,.flowplayer .fp-unload:before,.flowplayer .fp-mute:before,.flowplayer .fp-embed:before,.flowplayer .fp-close:before,.flowplayer .fp-play:before,.flowplayer .fp-menu:before{vertical-align:-2px}
+.flowplayer .fp-controls .fp-menu{bottom:3px;}
+.is-mouseover.flowplayer .fp-controls .fp-menu .fp-dropdown{bottom:36px}
+.flowplayer .fp-volumeslider{height:8px;margin-top:1px;margin-left:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
+.flowplayer .fp-volumeslider .fp-volumelevel{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
+.flowplayer .fp-mute{top:-9.5px;}
+.flowplayer .fp-mute:before{content:"\e60c";vertical-align:0;}
+.is-muted.is-ready.flowplayer .fp-mute:before{content:"\e60c";color:#ccc}
+.flowplayer .fp-mute:after{content:'';background-color:#9ebb11;width:6px;height:6px;display:block;position:absolute;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;right:2px;top:11px;}
+.is-muted.flowplayer .fp-mute:after{background-color:#f00}
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/img/video-play-mask.png
Binary file src/pyams_media/skin/resources/img/video-play-mask.png has changed
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/js/pyams_media.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/js/pyams_media.js Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,37 @@
+(function($) {
+
+ window.PyAMS_media = {
+
+ initPlayer: function(element) {
+ MyAMS.dialog.registerShownCallback(PyAMS_media.initPlayerDialog, element);
+ var players = $('.flowplayer', element);
+ if (players.exists()) {
+ players.each(function () {
+ var player = $(this);
+ var flowplayer = $(player).flowplayer();
+ var events = player.data('ams-flowplayer-events');
+ if (events) {
+ for (var event in events) {
+ flowplayer.on(event, MyAMS.getFunctionByName(events[event]));
+ }
+ }
+ });
+ }
+ },
+
+ initPlayerDialog: function() {
+ var dialog = $(this);
+ $('.modal-viewport', dialog).removeAttr('style')
+ .removeClass('modal-viewport');
+ },
+
+ getPlayerTime: function(e, api) {
+ var parent = $(this);
+ var player = parent.data('flowplayer');
+ var position = player.video.time;
+ var form = parent.parents('form');
+ $('INPUT[name="form.widgets.time"]', form).val(position);
+ }
+ };
+
+})(jQuery);
diff -r 000000000000 -r fd39db613f8b src/pyams_media/skin/resources/js/pyams_media.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/skin/resources/js/pyams_media.min.js Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,1 @@
+(function(a){window.PyAMS_media={initPlayer:function(b){MyAMS.dialog.registerShownCallback(PyAMS_media.initPlayerDialog,b);var c=a(".flowplayer",b);if(c.exists()){c.each(function(){var f=a(this);var d=a(f).flowplayer();var e=f.data("ams-flowplayer-events");if(e){for(var g in e){d.on(g,MyAMS.getFunctionByName(e[g]))}}})}},initPlayerDialog:function(){var b=a(this);a(".modal-viewport",b).removeAttr("style").removeClass("modal-viewport")},getPlayerTime:function(h,f){var d=a(this);var c=d.data("flowplayer");var b=c.video.time;var g=d.parents("form");a('INPUT[name="form.widgets.time"]',g).val(b)}}})(jQuery);
\ No newline at end of file
diff -r 000000000000 -r fd39db613f8b src/pyams_media/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/tests/__init__.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,1 @@
+
diff -r 000000000000 -r fd39db613f8b src/pyams_media/tests/test_utilsdocs.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/tests/test_utilsdocs.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+"""
+Generic Test case for pyams_media doctest
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import doctest
+import sys
+import os
+
+
+current_dir = os.path.dirname(__file__)
+
+def doc_suite(test_dir, setUp=None, tearDown=None, globs=None):
+ """Returns a test suite, based on doctests found in /doctest."""
+ suite = []
+ if globs is None:
+ globs = globals()
+
+ flags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE |
+ doctest.REPORT_ONLY_FIRST_FAILURE)
+
+ package_dir = os.path.split(test_dir)[0]
+ if package_dir not in sys.path:
+ sys.path.append(package_dir)
+
+ doctest_dir = os.path.join(package_dir, 'doctests')
+
+ # filtering files on extension
+ docs = [os.path.join(doctest_dir, doc) for doc in
+ os.listdir(doctest_dir) if doc.endswith('.txt')]
+
+ for test in docs:
+ suite.append(doctest.DocFileSuite(test, optionflags=flags,
+ globs=globs, setUp=setUp,
+ tearDown=tearDown,
+ module_relative=False))
+
+ return unittest.TestSuite(suite)
+
+def test_suite():
+ """returns the test suite"""
+ return doc_suite(current_dir)
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
diff -r 000000000000 -r fd39db613f8b src/pyams_media/tests/test_utilsdocstrings.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/tests/test_utilsdocstrings.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+"""
+Generic Test case for pyams_media doc strings
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import doctest
+import sys
+import os
+
+
+current_dir = os.path.abspath(os.path.dirname(__file__))
+
+def doc_suite(test_dir, globs=None):
+ """Returns a test suite, based on doc tests strings found in /*.py"""
+ suite = []
+ if globs is None:
+ globs = globals()
+
+ flags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE |
+ doctest.REPORT_ONLY_FIRST_FAILURE)
+
+ package_dir = os.path.split(test_dir)[0]
+ if package_dir not in sys.path:
+ sys.path.append(package_dir)
+
+ # filtering files on extension
+ docs = [doc for doc in
+ os.listdir(package_dir) if doc.endswith('.py')]
+ docs = [doc for doc in docs if not doc.startswith('__')]
+
+ for test in docs:
+ fd = open(os.path.join(package_dir, test))
+ content = fd.read()
+ fd.close()
+ if '>>> ' not in content:
+ continue
+ test = test.replace('.py', '')
+ location = 'pyams_media.%s' % test
+ suite.append(doctest.DocTestSuite(location, optionflags=flags,
+ globs=globs))
+
+ return unittest.TestSuite(suite)
+
+def test_suite():
+ """returns the test suite"""
+ return doc_suite(current_dir)
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
diff -r 000000000000 -r fd39db613f8b src/pyams_media/utility.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/utility.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,91 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_media.interfaces import IMediaConversionUtility, CONVERTER_HANDLER_KEY, CUSTOM_AUDIO_TYPES, \
+ CUSTOM_VIDEO_TYPES
+from pyams_utils.interfaces.zeo import IZEOConnection
+from zope.intid.interfaces import IIntIds
+
+# import packages
+from persistent import Persistent
+from pyams_utils.registry import get_utility
+from pyams_zmq.socket import zmq_socket, zmq_response
+from pyramid.threadlocal import get_current_registry
+from zope.container.contained import Contained
+from zope.interface import implementer
+from zope.schema.fieldproperty import FieldProperty
+
+
+@implementer(IMediaConversionUtility)
+class MediaConversionUtility(Persistent, Contained):
+ """Medias conversions utility"""
+
+ zeo_connection = FieldProperty(IMediaConversionUtility['zeo_connection'])
+
+ video_formats = FieldProperty(IMediaConversionUtility['video_formats'])
+ video_frame_size = FieldProperty(IMediaConversionUtility['video_frame_size'])
+ video_audio_sampling = FieldProperty(IMediaConversionUtility['video_audio_sampling'])
+ video_audio_bitrate = FieldProperty(IMediaConversionUtility['video_audio_bitrate'])
+ video_quantisation = FieldProperty(IMediaConversionUtility['video_quantisation'])
+
+ audio_formats = FieldProperty(IMediaConversionUtility['audio_formats'])
+
+ def check_media_conversion(self, media):
+ """Check if conversion is needed for given media"""
+ content_type = media.content_type.decode() if media.content_type else None
+ if self.audio_formats and \
+ (content_type.startswith('audio/') or (content_type in CUSTOM_AUDIO_TYPES)):
+ requested_formats = self.audio_formats
+ elif self.video_formats and \
+ (content_type.startswith('video/') or (content_type in CUSTOM_VIDEO_TYPES)):
+ requested_formats = self.video_formats
+ else:
+ requested_formats = ()
+ for format in requested_formats:
+ self.convert(media, format)
+
+ def _get_socket(self):
+ registry = get_current_registry()
+ handler = registry.settings.get(CONVERTER_HANDLER_KEY, False)
+ if handler:
+ return zmq_socket(handler)
+
+ def convert(self, media, format):
+ """Send conversion request for given media"""
+ socket = self._get_socket()
+ if socket is None:
+ return [501, "No socket handler defined in configuration file"]
+ if not self.zeo_connection:
+ return [502, "Missing ZEO connection"]
+ zeo = get_utility(IZEOConnection, self.zeo_connection)
+ intids = get_utility(IIntIds)
+ settings = {'zeo': zeo.get_settings(),
+ 'media': intids.register(media),
+ 'format': format}
+ socket.send_json(['convert', settings])
+ return zmq_response(socket)
+
+ def test_process(self):
+ """Send test request to conversion process"""
+ socket = self._get_socket()
+ if socket is None:
+ return [501, "No socket handler defined in configuration file"]
+ if not self.zeo_connection:
+ return [502, "Missing ZEO connection"]
+ socket.send_json(['test', {}])
+ return zmq_response(socket)
diff -r 000000000000 -r fd39db613f8b src/pyams_media/video.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/video.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,163 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import os.path
+import subprocess
+
+from tempfile import NamedTemporaryFile
+
+# import interfaces
+from pyams_file.interfaces import IVideo, IThumbnail
+from zope.annotation.interfaces import IAnnotations
+from zope.traversing.interfaces import ITraversable
+
+# import packages
+import transaction
+
+from pyams_file.file import ImageFile, get_magic_content_type
+from pyams_file.image import ThumbnailGeometrry
+from pyams_media.ffbase import FFmpeg
+from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyramid.threadlocal import get_current_registry
+from zope.lifecycleevent import ObjectCreatedEvent, ObjectAddedEvent
+from zope.location import locate
+
+
+THUMBNAIL_ANNOTATION_KEY = 'pyams_media.video.thumbnail'
+
+
+@adapter_config(context=IVideo, provides=IThumbnail)
+class VideoThumbnailAdapter(object):
+ """Video thumbnail adapter"""
+
+ def __init__(self, video):
+ self.video = video
+ annotations = IAnnotations(video)
+ self.thumbnail = annotations.get(THUMBNAIL_ANNOTATION_KEY)
+
+ def get_image_size(self):
+ if self.thumbnail is not None:
+ return self.thumbnail.get_image_size()
+ else:
+ mpeg = FFmpeg('ffprobe')
+ streams = mpeg.info(self.video)
+ if streams:
+ for stream in streams:
+ if stream.get('codec_type') != 'video':
+ continue
+ return stream.get('width'), stream.get('height')
+
+ def get_thumbnail_size(self, thumbnail_name, forced=False):
+ if self.thumbnail is not None:
+ return IThumbnail(self.thumbnail).get_thumbnail_size(thumbnail_name, forced)
+ else:
+ return self.get_image_size()
+
+ def get_thumbnail_geometry(self, thumbnail_name):
+ if self.thumbnail is not None:
+ return IThumbnail(self.thumbnail).get_thumbnail_geometry(thumbnail_name)
+ else:
+ size = self.get_image_size()
+ if size:
+ geometry = ThumbnailGeometrry()
+ geometry.x1 = 0
+ geometry.y1 = 0
+ geometry.x2 = size[0]
+ geometry.y2 = size[1]
+ return geometry
+
+ def set_thumbnail_geometry(self, thumbnail_name, geometry):
+ if self.thumbnail is not None:
+ IThumbnail(self.thumbnail).set_thumbnail_geometry(thumbnail_name, geometry)
+
+ def clear_geometries(self):
+ if self.thumbnail is not None:
+ IThumbnail(self.thumbnail).clear_geometries()
+
+ def get_thumbnail_name(self, thumbnail_name, with_size=False):
+ if self.thumbnail is not None:
+ return IThumbnail(self.thumbnail).get_thumbnail_name(thumbnail_name, with_size)
+ else:
+ size = self.get_image_size()
+ if size is not None:
+ if with_size:
+ return '{0}x{1}'.format(*size), size
+ else:
+ return '{0}x{1}'.format(*size)
+ else:
+ return None, None
+
+ def get_thumbnail(self, thumbnail_name, format=None, time=5):
+ if self.thumbnail is None:
+ pipe = subprocess.Popen(('ffmpeg', '-i', '-', '-ss', str(time), '-f', 'image2', '-vframes', '1', '-'),
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if pipe:
+ stdout, stderr = pipe.communicate(self.video.data)
+ # Some videos formats can't be converted via pipes
+ # If so, we must provide a temporay file...
+ if not stdout:
+ output = NamedTemporaryFile(prefix='video_', suffix='.thumb')
+ output.write(self.video.data)
+ output.file.flush()
+ pipe = subprocess.Popen(('ffmpeg', '-i', output.name, '-ss', str(time), '-f', 'image2',
+ '-vframes', '1', '-'),
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if pipe:
+ stdout, stderr = pipe.communicate()
+ # Create final image
+ registry = get_current_registry()
+ annotations = IAnnotations(self.video)
+ image = ImageFile(stdout)
+ image.content_type = get_magic_content_type(image.data)
+ registry.notify(ObjectCreatedEvent(image))
+ self.thumbnail = annotations[THUMBNAIL_ANNOTATION_KEY] = image
+ locate(self.thumbnail, self.video)
+ registry.notify(ObjectAddedEvent(image, self.video))
+ if self.thumbnail is not None:
+ size_name = '{0[0]}x{0[1]}'.format(self.get_image_size())
+ if thumbnail_name != size_name:
+ watermark = os.path.abspath(os.path.join(__file__, '..',
+ 'skin', 'resources', 'img', 'video-play-mask.png'))
+ return IThumbnail(self.thumbnail).get_thumbnail(thumbnail_name, format, watermark)
+ else:
+ return IThumbnail(self.thumbnail).get_thumbnail(thumbnail_name, format)
+
+ def delete_thumbnail(self, thumbnail_name):
+ annotations = IAnnotations(self.video)
+ if THUMBNAIL_ANNOTATION_KEY in annotations:
+ del annotations[THUMBNAIL_ANNOTATION_KEY]
+
+ def clear_thumbnails(self):
+ annotations = IAnnotations(self.video)
+ if THUMBNAIL_ANNOTATION_KEY in annotations:
+ del annotations[THUMBNAIL_ANNOTATION_KEY]
+ self.thumbnail = None
+
+
+@adapter_config(name='thumb', context=IVideo, provides=ITraversable)
+class ThumbnailTraverser(ContextAdapter):
+ """++thumb++ video namespace traverser"""
+
+ def traverse(self, name, furtherpath=None):
+ if '.' in name:
+ thumbnail_name, format = name.rsplit('.', 1)
+ else:
+ thumbnail_name = name
+ format = None
+ thumbnails = IThumbnail(self.context)
+ result = thumbnails.get_thumbnail(thumbnail_name, format)
+ transaction.commit()
+ return result
diff -r 000000000000 -r fd39db613f8b src/pyams_media/zmi/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/zmi/__init__.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,137 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_form.interfaces.form import IWidgetsSuffixViewletsManager
+from pyams_media.interfaces import IMediaConversionUtility
+from pyams_skin.interfaces.viewlet import ITableItemColumnActionsMenu
+from pyams_skin.layer import IPyAMSLayer
+
+# import packages
+from pyams_form.form import AJAXEditForm, AJAXAddForm
+from pyams_form.schema import CloseButton
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.viewlet.toolbar import ToolbarMenuItem
+from pyams_template.template import template_config
+from pyams_utils.text import text_to_html
+from pyams_viewlet.viewlet import viewlet_config, Viewlet
+from pyams_zmi.control_panel import UtilitiesTable
+from pyams_zmi.form import AdminDialogEditForm, AdminDialogAddForm
+from pyams_zmi.layer import IAdminLayer
+from pyramid.view import view_config
+from z3c.form import field, button
+from zope.interface import Interface
+
+from pyams_media import _
+
+
+@pagelet_config(name='properties.html', context=IMediaConversionUtility, layer=IPyAMSLayer, permission='system.view')
+class MediaConversionUtilityPropertiesEditForm(AdminDialogEditForm):
+ """Medias conversion utility properties edit form"""
+
+ @property
+ def title(self):
+ return self.context.__name__
+
+ legend = _("Update medias converter properties")
+
+ fields = field.Fields(IMediaConversionUtility)
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ ajax_handler = 'properties.json'
+ edit_permission = 'system.manage'
+
+
+@view_config(name='properties.json', context=IMediaConversionUtility, request_type=IPyAMSLayer,
+ permission='system.manage', renderer='json', xhr=True)
+class MediaConversionUtilityPropertiesAJAXEditForm(AJAXEditForm, MediaConversionUtilityPropertiesEditForm):
+ """Medias conversion utility properties edit form, JSON renderer"""
+
+
+@viewlet_config(name='test-conversion-process.menu', context=IMediaConversionUtility, layer=IAdminLayer,
+ view=UtilitiesTable, manager=ITableItemColumnActionsMenu, permission='system.manage')
+class MediaConversionProcessTestMenu(ToolbarMenuItem):
+ """Medias conversion process test menu"""
+
+ label = _("Test process connection...")
+ label_css_class = 'fa fa-fw fa-film'
+ url = 'test-conversion-process.html'
+ modal_target = True
+ stop_propagation = True
+
+
+class IMediaConversionProcessTestButtons(Interface):
+ """Medias conversion process test buttons"""
+
+ close = CloseButton(name='close', title=_("Close"))
+ test = button.Button(name='test', title=_("Test connection"))
+
+
+@pagelet_config(name='test-conversion-process.html', context=IMediaConversionUtility, layer=IPyAMSLayer,
+ permission='system.manage')
+class MediaConversionProcessTestForm(AdminDialogAddForm):
+ """Medias conversion process test form"""
+
+ @property
+ def title(self):
+ return self.context.__name__
+
+ legend = _("Test medias converter process connection")
+ icon_css_class = 'fa fa-fw fa-film'
+
+ prefix = 'test_form.'
+ fields = field.Fields(Interface)
+ buttons = button.Buttons(IMediaConversionProcessTestButtons)
+ ajax_handler = 'test-conversion-process.json'
+ edit_permission = 'system.manage'
+
+ @property
+ def form_target(self):
+ return '#{0}_test_result'.format(self.id)
+
+ def updateActions(self):
+ super(MediaConversionProcessTestForm, self).updateActions()
+ if 'test' in self.actions:
+ self.actions['test'].addClass('btn-primary')
+
+ def createAndAdd(self, data):
+ return self.context.test_process()
+
+
+@viewlet_config(name='test-conversion-process.suffix', layer=IAdminLayer, manager=IWidgetsSuffixViewletsManager,
+ view=MediaConversionProcessTestForm, weight=50)
+@template_config(template='templates/process-test.pt')
+class MediaConversionProcessTestSuffix(Viewlet):
+ """Media conversion process test form suffix"""
+
+
+@view_config(name='test-conversion-process.json', context=IMediaConversionUtility, request_type=IPyAMSLayer,
+ permission='system.manage', renderer='json', xhr=True)
+class MediaConversionProcessAJAXTestForm(AJAXAddForm, MediaConversionProcessTestForm):
+ """Medias conversion process test form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ status, message = changes
+ if status == 200:
+ return {'status': 'success',
+ 'content': {'html': text_to_html(message)},
+ 'close_form': False}
+ else:
+ return {'status': 'info',
+ 'content': {'html': text_to_html(message)},
+ 'close_form': False}
diff -r 000000000000 -r fd39db613f8b src/pyams_media/zmi/templates/process-test.pt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/zmi/templates/process-test.pt Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,1 @@
+
diff -r 000000000000 -r fd39db613f8b src/pyams_media/zmi/templates/video-thumbnail.pt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/zmi/templates/video-thumbnail.pt Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,18 @@
+
+
+
+
+
diff -r 000000000000 -r fd39db613f8b src/pyams_media/zmi/video.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_media/zmi/video.py Wed Sep 02 15:31:55 2015 +0200
@@ -0,0 +1,148 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+from pyams_form.interfaces.form import IWidgetsPrefixViewletsManager
+from pyams_skin.help import ContentHelp
+from pyams_skin.interfaces import IContentHelp
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+from pyams_zmi.layer import IAdminLayer
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+from decimal import Decimal
+
+# import interfaces
+from pyams_file.interfaces import IVideo, IThumbnail
+from pyams_skin.interfaces.viewlet import IContextActions
+from z3c.form.interfaces import HIDDEN_MODE
+
+# import packages
+from pyams_form.form import AJAXAddForm
+from pyams_form.schema import CloseButton
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.layer import IPyAMSLayer
+from pyams_skin.viewlet.toolbar import ToolbarMenuDivider, ToolbarMenuItem
+from pyams_utils.schema import DottedDecimalField
+from pyams_viewlet.viewlet import viewlet_config, Viewlet
+from pyams_zmi.form import AdminDialogAddForm
+from pyramid.view import view_config
+from z3c.form import field, button
+from zope.interface import Interface
+
+from pyams_media import _
+
+
+@viewlet_config(name='video.thumbnail.divider', context=IVideo, layer=IPyAMSLayer, view=Interface,
+ manager=IContextActions, permission='manage', weight=19)
+class VideoDividerAction(ToolbarMenuDivider):
+ """Video divider action"""
+
+
+#
+# Video thumbnail
+#
+
+@viewlet_config(name='video.thumbnail.action', context=IVideo, layer=IPyAMSLayer, view=Interface,
+ manager=IContextActions, permission='manage', weight=20)
+class VideoThumbnailAction(ToolbarMenuItem):
+ """Video thumbnail selection action"""
+
+ label = _("Select thumbnail...")
+ label_css_class = 'fa fa-fw fa-film'
+
+ url = 'video-thumbnail.html'
+ modal_target = True
+
+
+class IVideoThumbnailButtons(Interface):
+ """Video thumbnail selection buttons"""
+
+ close = CloseButton(name='close', title=_("Close"))
+ select = button.Button(name='resize', title=_("Select thumbnail"))
+
+
+class IVideoThumbnailInfo(Interface):
+ """Video thumbnail selection info"""
+
+ time = DottedDecimalField(title=_("Thumbnail timestamp"),
+ required=True,
+ default=Decimal(5))
+
+
+@pagelet_config(name='video-thumbnail.html', context=IVideo, layer=IPyAMSLayer, permission='manage')
+class VideoThumbnailEditForm(AdminDialogAddForm):
+ """Video thumbnail selection form"""
+
+ legend = _("Select video thumbnail")
+ icon_css_class = 'fa fa-fw fa-film'
+
+ fields = field.Fields(IVideoThumbnailInfo)
+ buttons = button.Buttons(IVideoThumbnailButtons)
+ ajax_handler = 'video-thumbnail.json'
+
+ @property
+ def title(self):
+ return self.context.title or self.context.filename
+
+ def updateWidgets(self, prefix=None):
+ super(VideoThumbnailEditForm, self).updateWidgets(prefix)
+ self.widgets['time'].mode = HIDDEN_MODE
+
+ def updateActions(self):
+ super(VideoThumbnailEditForm, self).updateActions()
+ if 'select' in self.actions:
+ self.actions['select'].addClass('btn-primary')
+
+ def createAndAdd(self, data):
+ thumbnailer = IThumbnail(self.context, None)
+ if thumbnailer is not None:
+ size = thumbnailer.get_image_size()
+ time = data.get('time')
+ if not isinstance(time, float):
+ time = float(time)
+ thumbnailer.clear_thumbnails()
+ return thumbnailer.get_thumbnail('{0[0]}x{0[1]}'.format(size), 'png', time)
+
+
+@view_config(name='video-thumbnail.json', context=IVideo, request_type=IPyAMSLayer,
+ permission='manage', renderer='json', xhr=True)
+class VideoThumbnailAJAXEditForm(AJAXAddForm, VideoThumbnailEditForm):
+ """Video thumbnail selection form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ translate = self.request.localizer.translate
+ if changes:
+ return {'status': 'success',
+ 'message': translate(_("Thumbnail selected successfully."))}
+ else:
+ return {'status': 'info',
+ 'message': translate(_("An error occurred. No created thumbnail."))}
+
+
+@viewlet_config(name='video-thumbnail-prefix', context=IVideo, layer=IAdminLayer, view=VideoThumbnailEditForm,
+ manager=IWidgetsPrefixViewletsManager)
+@template_config(template='templates/video-thumbnail.pt')
+class VideoThumbnailViewletsPrefix(Viewlet):
+ """Video thumbnail edit form viewlets prefix"""
+
+
+@adapter_config(context=(IVideo, IAdminLayer, VideoThumbnailEditForm), provides=IContentHelp)
+class VideoThumbnailEditFormHelpAdapter(ContentHelp):
+ """Video thumbnail selection form help adapter"""
+
+ message = _("""You can play the video until you display the image you want.
+
+By pausing the video and clicking on ''Select thumbnail'' button, the selected frame will be used as
+video illustration.""")
+ message_format = 'rest'